Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14089568
D19960.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
7 KB
Referenced Files
None
Subscribers
None
D19960.diff
View Options
diff --git a/src/applications/metamta/adapter/PhabricatorMailSendGridAdapter.php b/src/applications/metamta/adapter/PhabricatorMailSendGridAdapter.php
--- a/src/applications/metamta/adapter/PhabricatorMailSendGridAdapter.php
+++ b/src/applications/metamta/adapter/PhabricatorMailSendGridAdapter.php
@@ -8,166 +8,137 @@
const ADAPTERTYPE = 'sendgrid';
- private $params = array();
+ public function getSupportedMessageTypes() {
+ return array(
+ PhabricatorMailEmailMessage::MESSAGETYPE,
+ );
+ }
protected function validateOptions(array $options) {
PhutilTypeSpec::checkMap(
$options,
array(
- 'api-user' => 'string',
'api-key' => 'string',
));
}
public function newDefaultOptions() {
return array(
- 'api-user' => null,
'api-key' => null,
);
}
- public function setFrom($email, $name = '') {
- $this->params['from'] = $email;
- $this->params['from-name'] = $name;
- return $this;
- }
+ public function sendMessage(PhabricatorMailExternalMessage $message) {
+ $key = $this->getOption('api-key');
- public function addReplyTo($email, $name = '') {
- if (empty($this->params['reply-to'])) {
- $this->params['reply-to'] = array();
- }
- $this->params['reply-to'][] = array(
- 'email' => $email,
- 'name' => $name,
- );
- return $this;
- }
+ $parameters = array();
- public function addTos(array $emails) {
- foreach ($emails as $email) {
- $this->params['tos'][] = $email;
+ $subject = $message->getSubject();
+ if ($subject !== null) {
+ $parameters['subject'] = $subject;
}
- return $this;
- }
- public function addCCs(array $emails) {
- foreach ($emails as $email) {
- $this->params['ccs'][] = $email;
- }
- return $this;
- }
+ $personalizations = array();
- public function addAttachment($data, $filename, $mimetype) {
- if (empty($this->params['files'])) {
- $this->params['files'] = array();
+ $to_addresses = $message->getToAddresses();
+ if ($to_addresses) {
+ $personalizations['to'] = array();
+ foreach ($to_addresses as $address) {
+ $personalizations['to'][] = $this->newPersonalization($address);
+ }
}
- $this->params['files'][$filename] = $data;
- }
-
- public function addHeader($header_name, $header_value) {
- $this->params['headers'][] = array($header_name, $header_value);
- return $this;
- }
-
- public function setBody($body) {
- $this->params['body'] = $body;
- return $this;
- }
-
- public function setHTMLBody($body) {
- $this->params['html-body'] = $body;
- return $this;
- }
-
-
- public function setSubject($subject) {
- $this->params['subject'] = $subject;
- return $this;
- }
-
- public function supportsMessageIDHeader() {
- return false;
- }
-
- public function send() {
- $user = $this->getOption('api-user');
- $key = $this->getOption('api-key');
-
- $params = array();
- $ii = 0;
- foreach (idx($this->params, 'tos', array()) as $to) {
- $params['to['.($ii++).']'] = $to;
+ $cc_addresses = $message->getCCAddresses();
+ if ($cc_addresses) {
+ $personalizations['cc'] = array();
+ foreach ($cc_addresses as $address) {
+ $personalizations['cc'][] = $this->newPersonalization($address);
+ }
}
- $params['subject'] = idx($this->params, 'subject');
- $params['text'] = idx($this->params, 'body');
+ // This is a list of different sets of recipients who should receive copies
+ // of the mail. We handle "one message to each recipient" ourselves.
+ $parameters['personalizations'] = array(
+ $personalizations,
+ );
- if (idx($this->params, 'html-body')) {
- $params['html'] = idx($this->params, 'html-body');
+ $from_address = $message->getFromAddress();
+ if ($from_address) {
+ $parameters['from'] = $this->newPersonalization($from_address);
}
- $params['from'] = idx($this->params, 'from');
- if (idx($this->params, 'from-name')) {
- $params['fromname'] = $this->params['from-name'];
+ $reply_address = $message->getReplyToAddress();
+ if ($reply_address) {
+ $parameters['reply_to'] = $this->newPersonalization($reply_address);
}
- if (idx($this->params, 'reply-to')) {
- $replyto = $this->params['reply-to'];
-
- // Pick off the email part, no support for the name part in this API.
- $params['replyto'] = $replyto[0]['email'];
+ $headers = $message->getHeaders();
+ if ($headers) {
+ $map = array();
+ foreach ($headers as $header) {
+ $map[$header->getName()] = $header->getValue();
+ }
+ $parameters['headers'] = $map;
}
- foreach (idx($this->params, 'files', array()) as $name => $data) {
- $params['files['.$name.']'] = $data;
+ $content = array();
+ $text_body = $message->getTextBody();
+ if ($text_body !== null) {
+ $content[] = array(
+ 'type' => 'text/plain',
+ 'value' => $text_body,
+ );
}
- $headers = idx($this->params, 'headers', array());
-
- // See SendGrid Support Ticket #29390; there's no explicit REST API support
- // for CC right now but it works if you add a generic "Cc" header.
- //
- // SendGrid said this is supported:
- // "You can use CC as you are trying to do there [by adding a generic
- // header]. It is supported despite our limited documentation to this
- // effect, I am glad you were able to figure it out regardless. ..."
- if (idx($this->params, 'ccs')) {
- $headers[] = array('Cc', implode(', ', $this->params['ccs']));
+ $html_body = $message->getHTMLBody();
+ if ($html_body !== null) {
+ $content[] = array(
+ 'type' => 'text/html',
+ 'value' => $html_body,
+ );
}
-
- if ($headers) {
- // Convert to dictionary.
- $headers = ipull($headers, 1, 0);
- $headers = json_encode($headers);
- $params['headers'] = $headers;
+ $parameters['content'] = $content;
+
+ $attachments = $message->getAttachments();
+ if ($attachments) {
+ $files = array();
+ foreach ($attachments as $attachment) {
+ $files[] = array(
+ 'content' => base64_encode($attachment->getData()),
+ 'type' => $attachment->getMimeType(),
+ 'filename' => $attachment->getFilename(),
+ 'disposition' => 'attachment',
+ );
+ }
+ $parameters['attachments'] = $files;
}
- $params['api_user'] = $user;
- $params['api_key'] = $key;
+ $sendgrid_uri = 'https://api.sendgrid.com/v3/mail/send';
+ $json_parameters = phutil_json_encode($parameters);
- $future = new HTTPSFuture(
- 'https://sendgrid.com/api/mail.send.json',
- $params);
- $future->setMethod('POST');
+ id(new HTTPSFuture($sendgrid_uri))
+ ->setMethod('POST')
+ ->addHeader('Authorization', "Bearer {$key}")
+ ->addHeader('Content-Type', 'application/json')
+ ->setData($json_parameters)
+ ->setTimeout(60)
+ ->resolvex();
- list($body) = $future->resolvex();
+ // The SendGrid v3 API does not return a JSON response body. We get a
+ // non-2XX HTTP response in the case of an error, which throws above.
+ }
- $response = null;
- try {
- $response = phutil_json_decode($body);
- } catch (PhutilJSONParserException $ex) {
- throw new PhutilProxyException(
- pht('Failed to JSON decode response.'),
- $ex);
- }
+ private function newPersonalization(PhutilEmailAddress $address) {
+ $result = array(
+ 'email' => $address->getAddress(),
+ );
- if ($response['message'] !== 'success') {
- $errors = implode(';', $response['errors']);
- throw new Exception(pht('Request failed with errors: %s.', $errors));
+ $display_name = $address->getDisplayName();
+ if ($display_name) {
+ $result['name'] = $display_name;
}
- return true;
+ return $result;
}
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Nov 25, 11:47 AM (21 h, 15 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6785808
Default Alt Text
D19960.diff (7 KB)
Attached To
Mode
D19960: Upgrade Sendgrid to the modern mailer API; removes "api-user" option
Attached
Detach File
Event Timeline
Log In to Comment