Path: blob/master/src/applications/metamta/adapter/PhabricatorMailSendGridAdapter.php
12256 views
<?php12/**3* Mail adapter that uses SendGrid's web API to deliver email.4*/5final class PhabricatorMailSendGridAdapter6extends PhabricatorMailAdapter {78const ADAPTERTYPE = 'sendgrid';910public function getSupportedMessageTypes() {11return array(12PhabricatorMailEmailMessage::MESSAGETYPE,13);14}1516protected function validateOptions(array $options) {17PhutilTypeSpec::checkMap(18$options,19array(20'api-key' => 'string',21));22}2324public function newDefaultOptions() {25return array(26'api-key' => null,27);28}2930public function sendMessage(PhabricatorMailExternalMessage $message) {31$key = $this->getOption('api-key');3233$parameters = array();3435$subject = $message->getSubject();36if ($subject !== null) {37$parameters['subject'] = $subject;38}3940$personalizations = array();4142$to_addresses = $message->getToAddresses();43if ($to_addresses) {44$personalizations['to'] = array();45foreach ($to_addresses as $address) {46$personalizations['to'][] = $this->newPersonalization($address);47}48}4950$cc_addresses = $message->getCCAddresses();51if ($cc_addresses) {52$personalizations['cc'] = array();53foreach ($cc_addresses as $address) {54$personalizations['cc'][] = $this->newPersonalization($address);55}56}5758// This is a list of different sets of recipients who should receive copies59// of the mail. We handle "one message to each recipient" ourselves.60$parameters['personalizations'] = array(61$personalizations,62);6364$from_address = $message->getFromAddress();65if ($from_address) {66$parameters['from'] = $this->newPersonalization($from_address);67}6869$reply_address = $message->getReplyToAddress();70if ($reply_address) {71$parameters['reply_to'] = $this->newPersonalization($reply_address);72}7374$headers = $message->getHeaders();75if ($headers) {76$map = array();77foreach ($headers as $header) {78$map[$header->getName()] = $header->getValue();79}80$parameters['headers'] = $map;81}8283$content = array();84$text_body = $message->getTextBody();85if ($text_body !== null) {86$content[] = array(87'type' => 'text/plain',88'value' => $text_body,89);90}9192$html_body = $message->getHTMLBody();93if ($html_body !== null) {94$content[] = array(95'type' => 'text/html',96'value' => $html_body,97);98}99$parameters['content'] = $content;100101$attachments = $message->getAttachments();102if ($attachments) {103$files = array();104foreach ($attachments as $attachment) {105$files[] = array(106'content' => base64_encode($attachment->getData()),107'type' => $attachment->getMimeType(),108'filename' => $attachment->getFilename(),109'disposition' => 'attachment',110);111}112$parameters['attachments'] = $files;113}114115$sendgrid_uri = 'https://api.sendgrid.com/v3/mail/send';116$json_parameters = phutil_json_encode($parameters);117118id(new HTTPSFuture($sendgrid_uri))119->setMethod('POST')120->addHeader('Authorization', "Bearer {$key}")121->addHeader('Content-Type', 'application/json')122->setData($json_parameters)123->setTimeout(60)124->resolvex();125126// The SendGrid v3 API does not return a JSON response body. We get a127// non-2XX HTTP response in the case of an error, which throws above.128}129130private function newPersonalization(PhutilEmailAddress $address) {131$result = array(132'email' => $address->getAddress(),133);134135$display_name = $address->getDisplayName();136if ($display_name) {137$result['name'] = $display_name;138}139140return $result;141}142143}144145146