Sendgrid use attachment on body with sendgrid-php

4.3k views Asked by At

I am using the sendgrid-php lib to send e-mails trough Sendgrid, now I want to use some images, but GMail refuses to open them, as they are on server side. To overcome this behavior I want to attach the images to the e-mail, and display them on the e-mail's body.

Here is my current code:

require("./sendgrid-php/sendgrid-php.php");

$html = '
    <!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <link href="http://fonts.googleapis.com/css?family=Source+Sans+Pro:400,700,300" rel="stylesheet" type="text/css">
</head>
<body style="background-color: #7bb241; padding: 10px 0;">
    <img alt="Projekt Fitness" height="56" src="http://domain/title.png" width="350" style="margin: 40px auto 0 auto; display: block;"/>
    <div style=\'width: 600px; margin: 40px auto; background-color: white; border-radius: 3px; padding: 20px; font-family: "Source Sans Pro", Helvetica, sans-serif; font-weight: 300; font-size: 18px;\'>
       <p>Hello <b>Jonh Doe</b>,</p>
        <p style="text-align: justify;">
         Thanks for subscribing! Soon you will receive our first newsletter!
        </p>
    </div>
</body>
</html>
';

$sendgrid = new SendGrid('myuser', 'mypwd');

$email = new SendGrid\Email();
$email
    ->addTo('[email protected]')
    ->setFrom('contato@domain')
    ->setFromName("Cool Newsletter")
    ->setSubject('Welcome to our newsletter')
    ->setHtml($html)
;

$sendgrid->send($email);
3

There are 3 answers

1
eddiezane On BEST ANSWER

You can accomplish this using inline CID on the image tag.

...
<img src="cid:logo-cid"></div>
...

$sendgrid = new SendGrid('myuser', 'mypwd');

$email = new SendGrid\Email();
$email
    ->addTo('[email protected]')
    ->setFrom('contato@domain')
    ->setFromName("Cool Newsletter")
    ->setSubject('Welcome to our newsletter')
    ->setHtml($html)
    ->addAttachment('./path/to/logo.png', 'logo.png', 'logo-cid')
;

$sendgrid->send($email);

Please let me know if you have further questions!

0
Jean Argoud On

In more recent versions of sendgrid the above methods did not work, but the following did:

$path = './assets/logo.png';
$type = pathinfo($path, PATHINFO_EXTENSION);
$data = file_get_contents($path);        
    
$email = new \SendGrid\Mail\Mail();     
$email->setFrom("[email protected]", "you");
$email->setSubject("Subject of your email");
$email->addTo("[email protected]", "recipient");
$email->addContent("text/html", "Content of your email in HTML");
$email->addAttachment(base64_encode($data), 'image/'.$type, 'logo.png' , 'inline' , 'logo-cid');        
        
$sendgrid = new \SendGrid(file_get_contents(getenv('SENDGRID_API_KEY')));        
try {
   $response = $sendgrid->send($email);            
   print $response->statusCode() . "\n";
   print_r($response->headers());
   print $response->body() . "\n";            
} catch (Exception $e) {
   echo 'Caught exception: '. $e->getMessage() ."\n";            
}         

Basically the solution is that you have to encode your image to base64. "SENDGRID_API_KEY" is my enviorement variable to "sengrid.env".

0
Oswaldo Rodriguez Gonzalez On

If you're looking for inline images, look (Check out how cid:myimagecid is used)

$sg = new \SendGrid("<YOUR API KEY>");
$from = new SendGrid\Email("Somebody", "[email protected]");
$subject = "Bla bla";
$to = new SendGrid\Email("Somebody Else", "[email protected]");
$content = new SendGrid\Content("text/html", 'Your html <img src="cid:myimagecid">');
$mail = new SendGrid\Mail($from, $subject, $to, $content);

$file = 'path/file.jpg';
$file_encoded = base64_encode(file_get_contents($file));
$attachment = new SendGrid\Attachment();
$attachment->setContent($file_encoded);
$attachment->setType("image/jpeg");
$attachment->setContentID("myimagecid");
$attachment->setDisposition("inline");
$attachment->setFilename("filename.jpg");

$mail->addAttachment($attachment);

try {
    $response = $sg->client->mail()->send()->post($mail);
} catch (Exception $e) {
    echo 'Caught exception: ', $e->getMessage(), "\n";
}
var_dump($response);

Works same when using templates.