phpsendgridsendgrid-api-v3sendgrid-templates

SendGrid email substitutions does not work for Gmail emails


I am sending emails using SendGrid API and I am using Dynamic Email templates.

My email template looks like this.

enter image description here

Emails are sent to both Gmail and to emails created using my domain such as admin@mydomain.com.

And I am using email substitutions to replace the {{substitutables}} in the template. The substitutions seem to work for emails from my domain but not for Gmail emails.

Here is what Gmail email looks like. I am using web browser for my Gmail emails. enter image description here

And here is what my domain emails look like. I am using MS Outlook as my mail client for domain emails. enter image description here

Following is the code that I am using to send emails.

public function sendEmail(
    string $templateId,
    array $recipiants,
    array $substitutions = [],
    array $ccs = [],
    array $bccs = [],
    array $replyTo = [],
    array $attachments = []
){

    $emailParams = $this->params->get('email');

    $apiKey = $emailParams['sendgrid']['api_key'];

    $sendgrid = new \SendGrid($apiKey);

    $email = new Mail();

    if (!$recipiants || !is_array($recipiants) || count($recipiants) == 0){
        throw new NotFoundHttpException("Email Recipients Not Found!");
    }

    $email->setTemplateId($templateId);
    $email->setFrom(new From($emailParams['from']['email'], $emailParams['from']['name']));

    // adding recients to the emial
    foreach ($recipiants as $recipiant){
        $personalization = new Personalization();
        $toEmail = new To($recipiant['email'], $recipiant['name']);
        $personalization->addTo($toEmail);
        $email->addPersonalization($personalization);
    }

    // adding CCs to email
    if (count($ccs) > 0) {
        foreach ($ccs as $cc) {
            $ccEmail = new Cc($cc['email'], $cc['name']);
            $email->addCc($ccEmail);
        }
    }

    // adding BCCs to email
    if (count($ccs) > 0) {
        foreach ($bccs as $bcc) {
            $bccEmail = new Bcc($bcc['email'], $bcc['name']);
            $email->addBcc($bccEmail);
        }
    }

    // adding template substitutions
    if (count($substitutions) > 0) {
        $email->addDynamicTemplateDatas($substitutions);
    }

    // sending email
    /** @var Response $response */
    $response = $sendgrid->send($email);

    if ($response->statusCode() != 202){
        throw new AccessDeniedHttpException("Failed to Send Email!");
    }
}

Can someone point me what I am doing wrong and why it is behaving this way? Thank you for your time.


Solution

  • Finally figured out what was wrong with my code. Apparently, even though you create one email object using $email = new Mail(); you can have many recipients.

    When you use personalizations, it sends individual emails to each recipient. So you have to set DynamicTemplateData, CC and BCC to each personalization separately. Unless it only substitutes for the very first recipient in the $recipiants array.

    Following is the updated code.

    public function sendEmail(
        string $templateId,
        array $recipiants,
        array $substitutions = [],
        array $replyTo = [],
        array $attachments = []
    ){
    
        $emailParams = $this->params->get('email');
    
        $apiKey = $emailParams['sendgrid']['api_key'];
    
        $sendgrid = new \SendGrid($apiKey);
    
        $email = new Mail();
    
        if (!$recipiants || !is_array($recipiants) || count($recipiants) == 0){
            throw new NotFoundHttpException("Email Recipients Not Found!");
        }
    
        $email->setTemplateId($templateId);
        $email->setFrom(new From($emailParams['from']['email'], $emailParams['from']['name']));
    
        // adding recients to the emial
        foreach ($recipiants as $recipiant){
    
            $personalization = new Personalization();
    
            $toEmail = new To($recipiant['email'], $recipiant['name']);
    
            $personalization->addTo($toEmail);
    
            // adding substitutions to individual personalization
            foreach ($substitutions as $key => $value) {
                $personalization->addDynamicTemplateData($key, $value);
            }
    
    
            // adding CCs to email
            if (array_key_exists('cc', $recipiant)) {
    
                foreach ($recipiant['cc'] as $cc) {
    
                    $ccEmail = new Cc($cc['email'], $cc['name']);
    
                    $personalization->addCc($ccEmail);
                }
            }
    
            // adding BCCs to email
            if (array_key_exists('bcc', $recipiant)) {
    
                foreach ($recipiant['bcc'] as $bcc) {
    
                    $bccEmail = new Bcc($bcc['email'], $bcc['name']);
    
                    $personalization->addBcc($bccEmail);
                }
            }
    
            // bcc every email to Zone101
            $bccEmail = new Bcc($emailParams['bcc']['email'], $emailParams['bcc']['name']);
            $personalization->addBcc($bccEmail);
    
    
            $email->addPersonalization($personalization);
        }
    
        // sending email
        /** @var Response $response */
        $response = $sendgrid->send($email);
    
        if ($response->statusCode() != 202){
            throw new AccessDeniedHttpException("Failed to Send Email!");
        }
    }