Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 744c011a authored by Israel Yago Pereira's avatar Israel Yago Pereira Committed by Arnau Vàzquez
Browse files

Offer the option to use SendGrid dynamic template API

parent 0442f800
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@ RUN apt-get update && apt-get install -y libyaml-dev nano libpng-dev libfreetype
 # https://getcomposer.org/doc/faqs/how-to-install-untrusted-packages-safely.md
RUN docker-php-ext-configure gd --with-freetype --with-jpeg 
RUN docker-php-ext-install -j$(nproc) gd 
RUN COMPOSER_ALLOW_SUPERUSER=1 composer require --no-plugins --no-scripts pear/mail pear/net_smtp pear/auth_sasl pear/mail_mime phpseclib/phpseclib:~3.0 curl/curl 
RUN COMPOSER_ALLOW_SUPERUSER=1 composer require --no-plugins --no-scripts pear/mail pear/net_smtp pear/auth_sasl pear/mail_mime phpseclib/phpseclib:~3.0 curl/curl sendgrid/sendgrid
RUN apt-get remove -y git unzip 
RUN rm -rf /var/lib/apt/lists/* && rm /usr/bin/composer
RUN chown -R www-data:www-data /var/www/html/vendor/ /var/www/html/composer.lock /var/www/html/composer.json
+7 −0
Original line number Diff line number Diff line
@@ -33,6 +33,13 @@ Then, the user can sign up with the following URL:
https://welcome.domaina.pw/?authmail=user@email.com&authsecret=password
```

# SendGrid integration
To be able to use [SendGrid](https://sendgrid.com/) as the email sender, you need to set the following ENV variables:
- `SENDGRID_API_KEY`, something like: "SG.r_l1Ss0aRAB8..."
- `SENDGRID_EMAIL_FROM`, a valid sender email validated on SendGrid
- `SENDGRID_TEMPLATE_ID_EMAIL_CONFIRMATION`, a template id of the email confirmation body to be used. Also created on SendGrid dashboard. ex: "d-47948c4b..."
- `SENDGRID_TEMPLATE_ID_ACCOUNT_CREATED`, a template id of the email sent when the account was created. Also created on SendGrid dashboard. ex: "d-87143d1c..."

# License

The project is licensed under [AGPL](LICENSE).
+29 −6
Original line number Diff line number Diff line
@@ -22,16 +22,23 @@ function respond_with_message($response_code, $message)
}


function sendWelcomeMsg($authmail, $mbox, $domain)
function sendWelcomeMail($authmail, $mbox, $domain)
{
    $mailDomain = getMailDomain();
    if (getenv("SENDGRID_API_KEY") !== false) {
        return sendWelcomeMailWithSendGrid($authmail, $mbox, $domain, $mailDomain);
    }
    return sendWelcomeMailWithPHPMail($authmail, $mbox, $domain, $mailDomain);
}

function sendWelcomeMailWithPHPMail(string $to, string $mbox, string $domain, string $mailDomain)
{
    global $strings;
    global $mail_domain;
    $from = getenv("SMTP_FROM");
    $to = $authmail;
    $msg = $strings["success_account_created"];
    $subject = "$mbox@$mail_domain";
    $subject = "$mbox@$mailDomain";
    $html = "<html> <body> <div> <h1>$msg</h1> </div> <div> <p> " . $strings[("success_message1")] . " </p> <p> " . $strings["success_message2"] . ' </p> <p> ' . $strings["success_message3"] . ' </p> <p> ' . $strings["success_message4"] . ' </p> <p> ' . $strings["success_message5"] . ' </p>  </body> </html>';
    $html = str_replace("@@@mail_domain@@@", $mail_domain, $html);
    $html = str_replace("@@@mail_domain@@@", $mailDomain, $html);
    $html = str_replace("@@@domain@@@", $domain, $html);
    $html = str_replace("@@@username@@@", $mbox, $html);
    $mime = new Mail_mime(array(
@@ -61,6 +68,22 @@ function sendWelcomeMsg($authmail, $mbox, $domain)
    $mail = $smtp->send($to, $mime->headers($headers), $body);
}

function sendWelcomeMailWithSendGrid(string $to, string $mbox, string $domain, string $mailDomain)
{
    $lang = strtoupper(getCurrentRequestLanguage());
    $TEMPLATE_ID = getLocalizedEnv("SENDGRID_TEMPLATE_ID_ACCOUNT_CREATED", $lang);
    
    $substitutions = [
      new \SendGrid\Mail\Substitution("domain", $domain),
      new \SendGrid\Mail\Substitution("mail_domain", $mailDomain),
      new \SendGrid\Mail\Substitution("username", $mbox),
    ];

    $email = createSendGridEmail($to, $TEMPLATE_ID, $substitutions);
    
    sendEmailWithSendGrid($email);
}

function checkIfUserExists($mail)
{
    global $domain;
@@ -277,7 +300,7 @@ if (strcmp($pw, $pw2)) {
$answer = createMailAccount($resultmail, $pw, $pw2, $name, $quota, $authmail);

if ($answer->success) {
    sendWelcomeMsg($authmail, $mbox, $domain);
    sendWelcomeMail($authmail, $mbox, $domain);
    $done = "$authmail:$authsecret:$mbox";
    $myfile = file_put_contents("/var/accounts/auth.file.done", $done . PHP_EOL, FILE_APPEND | LOCK_EX);
    if ($myfile === false) {
+118 −6
Original line number Diff line number Diff line
@@ -29,11 +29,19 @@ function sendInviteMail($to, $secret, $lang)
{
    $encoded_email = urlencode($to);
    $domain = getenv("DOMAIN");
    $signupURL = "https://welcome.$domain/";
    if ($lang != "en") {
        $signup_url = "https://welcome.$domain/$lang/register?authmail=$encoded_email&authsecret=$secret";
    } else {
        $signup_url = "https://welcome.$domain/register?authmail=$encoded_email&authsecret=$secret";
        $signupURL .= "$lang/";
    }
    $signupURL .= "register?authmail=$encoded_email&authsecret=$secret";
    if (getenv("SENDGRID_API_KEY") !== false) {
        return sendInviteMailWithSendGrid($to, $signupURL);
    }
    return sendInviteMailWithPHPMail($to, $signupURL, $lang);
}

function sendInviteMailWithPHPMail(string $to, string $signupURL, string $lang): bool
{
    $template = null;
    $from = getenv("SMTP_FROM");
    if (file_exists("/var/www/html/invite_template/$lang.json")) {
@@ -51,8 +59,8 @@ function sendInviteMail($to, $secret, $lang)
    $text = $template->text;
    $html = $template->html;

    $text = str_replace("@@@TARGETURL@@@", $signup_url, $text);
    $html = str_replace("@@@TARGETURL@@@", $signup_url, $html);
    $text = str_replace("@@@TARGETURL@@@", $signupURL, $text);
    $html = str_replace("@@@TARGETURL@@@", $signupURL, $html);


    $mime = new Mail_mime(
@@ -92,13 +100,108 @@ function sendInviteMail($to, $secret, $lang)
    }
}

function sendInviteMailWithSendGrid(string $to, string $signupURL): bool
{

    $lang = strtoupper(getCurrentRequestLanguage());

    $TEMPLATE_ID = getLocalizedEnv("SENDGRID_TEMPLATE_ID_EMAIL_CONFIRMATION", $lang);
    
    $substitutions = [
      new \SendGrid\Mail\Substitution("TARGETURL", $signupURL),
    ];

    $email = createSendGridEmail($to, $TEMPLATE_ID, $substitutions);
    
    return sendEmailWithSendGrid($email);
}

/**
 * @return string valid language code
 */
function getCurrentRequestLanguage(): string
{
    if (!isset($_GET["lang"])) {
        return "en";
    }
    $lang = strtolower($_GET["lang"]);
    return check_if_lang_exists($lang) ? $lang : "en";
}

/**
 * @return string a value from getenv but localized by language. Tries to catch at least the value for the default lang or throws an error
 * <code>
 * <?php
 * echo getLocalizedEnv("HELLO", "fr"); // Bonjour
 * echo getLocalizedEnv("HELLO", "en"); // Hello
 * echo getLocalizedEnv("WORLD", "does_not_exist"); // World
 * echo getLocalizedEnv("ONLY_IN_ENG", "fr"); // Only in english
 * echo getLocalizedEnv("DOES_NOT_EXIST", "en"); // throw an error
 * ?>
 * </code>
 */
function getLocalizedEnv(string $envKey, string $lang): string
{
    $lang = strtolower($lang);
    if (!check_if_lang_exists($lang)) {
        $lang = "en";
    }
    
    $lang = strtoupper($lang);

    $value = getenv("{$envKey}_{$lang}");
    if ($value !== false) {
        return $value;
    }
    // Searching for default value
    $value = getenv("{$envKey}_EN");
    if ($value === false) {
        throw new Exception("ENV variable '$envKey' was not found for language '$lang' nor a default value was set");
    }
    return $value;
}

function createSendGridEmail(string $to, string $templateId, ?array $substitutions): \SendGrid\Mail\Mail
{
    $SEND_FROM = getenv("SENDGRID_EMAIL_FROM");
    if ($SEND_FROM === false) {
        throw new Exception("SENDGRID_EMAIL_FROM env variable is required to send email with SendGrid");
    }

    $email = new \SendGrid\Mail\Mail();
    $email->setFrom($SEND_FROM);
    $email->addTo($to);
    
    if ( $substitutions !== null ) {
        $email->addDynamicTemplateDatas($substitutions);
    }
    $email->setTemplateId($templateId);
    return $email;
}

function sendEmailWithSendGrid(\SendGrid\Mail\Mail $email): bool
{
    $SENDGRID_API_KEY = getenv("SENDGRID_API_KEY");
    if ($SENDGRID_API_KEY === false) {
        throw new Exception("SENDGRID_API_KEY env variable is required to send email with SendGrid");
    }
    $sendgrid = new \SendGrid($SENDGRID_API_KEY);
    try {
        $response = $sendgrid->send($email);
        return $response->statusCode() == 202;
    } catch (Exception $e) {
        echo 'Caught exception: '. $e->getMessage() ."\n";
        return false;
    }
}

function respond_with_json($response)
{
    header('Content-type: application/json');
    exit(json_encode($response));
}

function check_if_lang_exists($lang)
function check_if_lang_exists($lang): bool
{
    $available_langs = array("en", "de", "fr", "it", "es");
    return in_array($lang, $available_langs);
@@ -154,3 +257,12 @@ function isAuthorized($mail, $secret)
    $res->success = false;
    return $res;
}

function getMailDomain(): string
{
    $mailDomain = getenv("MAIL_DOMAIN");
    if (empty($mailDomain)) {
        return getenv("DOMAIN");
    }
    return $mailDomain;
}
 No newline at end of file