4 * Mail adapter that uses SendGrid's web API to deliver email.
6 final class PhabricatorMailSendGridAdapter
7 extends PhabricatorMailAdapter
{
9 const ADAPTERTYPE
= 'sendgrid';
11 public function getSupportedMessageTypes() {
13 PhabricatorMailEmailMessage
::MESSAGETYPE
,
17 protected function validateOptions(array $options) {
18 PhutilTypeSpec
::checkMap(
21 'api-key' => 'string',
25 public function newDefaultOptions() {
31 public function sendMessage(PhabricatorMailExternalMessage
$message) {
32 $key = $this->getOption('api-key');
34 $parameters = array();
36 $subject = $message->getSubject();
37 if ($subject !== null) {
38 $parameters['subject'] = $subject;
41 $personalizations = array();
43 $to_addresses = $message->getToAddresses();
45 $personalizations['to'] = array();
46 foreach ($to_addresses as $address) {
47 $personalizations['to'][] = $this->newPersonalization($address);
51 $cc_addresses = $message->getCCAddresses();
53 $personalizations['cc'] = array();
54 foreach ($cc_addresses as $address) {
55 $personalizations['cc'][] = $this->newPersonalization($address);
59 // This is a list of different sets of recipients who should receive copies
60 // of the mail. We handle "one message to each recipient" ourselves.
61 $parameters['personalizations'] = array(
65 $from_address = $message->getFromAddress();
67 $parameters['from'] = $this->newPersonalization($from_address);
70 $reply_address = $message->getReplyToAddress();
72 $parameters['reply_to'] = $this->newPersonalization($reply_address);
75 $headers = $message->getHeaders();
78 foreach ($headers as $header) {
79 $map[$header->getName()] = $header->getValue();
81 $parameters['headers'] = $map;
85 $text_body = $message->getTextBody();
86 if ($text_body !== null) {
88 'type' => 'text/plain',
89 'value' => $text_body,
93 $html_body = $message->getHTMLBody();
94 if ($html_body !== null) {
96 'type' => 'text/html',
97 'value' => $html_body,
100 $parameters['content'] = $content;
102 $attachments = $message->getAttachments();
105 foreach ($attachments as $attachment) {
107 'content' => base64_encode($attachment->getData()),
108 'type' => $attachment->getMimeType(),
109 'filename' => $attachment->getFilename(),
110 'disposition' => 'attachment',
113 $parameters['attachments'] = $files;
116 $sendgrid_uri = 'https://api.sendgrid.com/v3/mail/send';
117 $json_parameters = phutil_json_encode($parameters);
119 id(new HTTPSFuture($sendgrid_uri))
121 ->addHeader('Authorization', "Bearer {$key}")
122 ->addHeader('Content-Type', 'application/json')
123 ->setData($json_parameters)
127 // The SendGrid v3 API does not return a JSON response body. We get a
128 // non-2XX HTTP response in the case of an error, which throws above.
131 private function newPersonalization(PhutilEmailAddress
$address) {
133 'email' => $address->getAddress(),
136 $display_name = $address->getDisplayName();
138 $result['name'] = $display_name;