nockieboy
nockieboy

Reputation: 367

PHP: SendGrid mail attachments from S3 server

I need to be able to send one, maybe more, files stored on an Amazon S3 server as attachments in an email created using SendGrid.

The problem I have is that I'm not a web dev expert and the sparse PHP examples I can find are not helping me much.

Do I need to download the files from the S3 server to the local /tmp directory and add them as attachments that way, or can I pass the body of the file from the FileController and insert it as an attachment that way?

I'm not really sure where to start, but here's what I've done so far:

$attachments = array();
// Process the attachment_ids
foreach($attachment_ids as $attachment_id) {
        // Get the file if it is attached to the Activity
        if (in_array($attachment_id, $activity_file_ids)) {
                $file = File::find($attachment_id);
                $fileController = new FileController($this->_app);
                $fileObject = $fileController->getFile($attachment_id);
error_log(print_r($fileObject, true));
                $attachment = array();
                $attachment['content'] = $fileObject;
                $attachment['type'] = $fileController->mime_content_type($file->file_ext);
                $attachment['name'] = explode(".", $file->filename, 2)[0];
                $attachment['filename'] = $file->filename;
                $attachment['disposition'] = "inline";
                $attachment['content_id'] = '';
        }
}

My next step would be to push the $attachment array to the $attachments array. Once $attachments is complete, iterate through it and add each $attachment to the SendGrid e-mail object (the e-mail is working fine without attachments, btw.)

Problem is, I'm not sure I'm going down the right road with this or if there's a much shorter and neater (and working) way of doing it?

FileController->getFile() essentially does this:

$file = $this->_s3->getObject(array(
    'Bucket' => $bucket,
    'Key'    => $filename,
));
return $file['Body'];

Any help (especially code examples) would be greatly appreciated!

Upvotes: 0

Views: 950

Answers (1)

nockieboy
nockieboy

Reputation: 367

Okay, I've got a working solution to this now - here's the code:

// Process the attachment_ids
foreach($attachment_ids as $attachment_id) {
        // Get the file if it is attached to the Activity
        if (in_array($attachment_id, $activity_file_ids)) {
                // Get the file record
                $file = File::find($attachment_id);
                // Get an instance of FileController
                $fileController = new FileController($this->_app);
                // Set up the Attachment object
                $attachment = new \SendGrid\Attachment();
                $attachment->setContent(base64_encode($fileController->getFile($attachment_id)));
                $attachment->setType($fileController->mime_content_type($file->file_ext));
                $attachment->setFilename($file->filename);
                $attachment->setDisposition("attachment");
                $attachment->setContentId($file->file_desc);
                // Add the attachment to the mail
                $mail->addAttachment($attachment);
         }
}

Don't know if it will help anybody else, but there it is. The solution was to get the file from the S3 server and pass base64_encode($file['Body']) to the setContent function of an instantiated Attachment object, along with setting a few other fields for it too.

Upvotes: 1

Related Questions