2011-05-26 19:00:26 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Mail adapter that uses SendGrid's web API to deliver email.
|
|
|
|
*/
|
2019-01-04 14:40:26 +01:00
|
|
|
final class PhabricatorMailSendGridAdapter
|
|
|
|
extends PhabricatorMailAdapter {
|
2011-05-26 19:00:26 +02:00
|
|
|
|
2018-02-06 14:23:47 +01:00
|
|
|
const ADAPTERTYPE = 'sendgrid';
|
|
|
|
|
2019-01-05 15:30:22 +01:00
|
|
|
public function getSupportedMessageTypes() {
|
|
|
|
return array(
|
|
|
|
PhabricatorMailEmailMessage::MESSAGETYPE,
|
|
|
|
);
|
|
|
|
}
|
2011-05-26 19:00:26 +02:00
|
|
|
|
2018-02-06 00:58:07 +01:00
|
|
|
protected function validateOptions(array $options) {
|
|
|
|
PhutilTypeSpec::checkMap(
|
|
|
|
$options,
|
|
|
|
array(
|
|
|
|
'api-key' => 'string',
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
public function newDefaultOptions() {
|
|
|
|
return array(
|
|
|
|
'api-key' => null,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-01-05 15:30:22 +01:00
|
|
|
public function sendMessage(PhabricatorMailExternalMessage $message) {
|
|
|
|
$key = $this->getOption('api-key');
|
2011-05-26 19:00:26 +02:00
|
|
|
|
2019-01-05 15:30:22 +01:00
|
|
|
$parameters = array();
|
2011-05-26 19:00:26 +02:00
|
|
|
|
2019-01-05 15:30:22 +01:00
|
|
|
$subject = $message->getSubject();
|
|
|
|
if ($subject !== null) {
|
|
|
|
$parameters['subject'] = $subject;
|
2011-05-26 19:00:26 +02:00
|
|
|
}
|
|
|
|
|
2019-01-05 15:30:22 +01:00
|
|
|
$personalizations = array();
|
2011-05-26 19:00:26 +02:00
|
|
|
|
2019-01-05 15:30:22 +01:00
|
|
|
$to_addresses = $message->getToAddresses();
|
|
|
|
if ($to_addresses) {
|
|
|
|
$personalizations['to'] = array();
|
|
|
|
foreach ($to_addresses as $address) {
|
|
|
|
$personalizations['to'][] = $this->newPersonalization($address);
|
|
|
|
}
|
2011-11-08 23:14:00 +01:00
|
|
|
}
|
2011-05-26 19:00:26 +02:00
|
|
|
|
2019-01-05 15:30:22 +01:00
|
|
|
$cc_addresses = $message->getCCAddresses();
|
|
|
|
if ($cc_addresses) {
|
|
|
|
$personalizations['cc'] = array();
|
|
|
|
foreach ($cc_addresses as $address) {
|
|
|
|
$personalizations['cc'][] = $this->newPersonalization($address);
|
|
|
|
}
|
2011-05-26 19:00:26 +02:00
|
|
|
}
|
|
|
|
|
2019-01-05 15:30:22 +01:00
|
|
|
// 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,
|
|
|
|
);
|
2014-08-15 17:04:10 +02:00
|
|
|
|
2019-01-05 15:30:22 +01:00
|
|
|
$from_address = $message->getFromAddress();
|
|
|
|
if ($from_address) {
|
|
|
|
$parameters['from'] = $this->newPersonalization($from_address);
|
2011-05-26 19:00:26 +02:00
|
|
|
}
|
|
|
|
|
2019-01-05 15:30:22 +01:00
|
|
|
$reply_address = $message->getReplyToAddress();
|
|
|
|
if ($reply_address) {
|
|
|
|
$parameters['reply_to'] = $this->newPersonalization($reply_address);
|
2011-05-26 19:00:26 +02:00
|
|
|
}
|
|
|
|
|
2019-01-05 15:30:22 +01:00
|
|
|
$headers = $message->getHeaders();
|
|
|
|
if ($headers) {
|
|
|
|
$map = array();
|
|
|
|
foreach ($headers as $header) {
|
|
|
|
$map[$header->getName()] = $header->getValue();
|
|
|
|
}
|
|
|
|
$parameters['headers'] = $map;
|
2011-05-26 19:00:26 +02:00
|
|
|
}
|
|
|
|
|
2019-01-05 15:30:22 +01:00
|
|
|
$content = array();
|
|
|
|
$text_body = $message->getTextBody();
|
|
|
|
if ($text_body !== null) {
|
|
|
|
$content[] = array(
|
|
|
|
'type' => 'text/plain',
|
|
|
|
'value' => $text_body,
|
|
|
|
);
|
2011-11-08 23:14:00 +01:00
|
|
|
}
|
|
|
|
|
2019-01-05 15:30:22 +01:00
|
|
|
$html_body = $message->getHTMLBody();
|
|
|
|
if ($html_body !== null) {
|
|
|
|
$content[] = array(
|
|
|
|
'type' => 'text/html',
|
|
|
|
'value' => $html_body,
|
|
|
|
);
|
2011-05-26 19:00:26 +02:00
|
|
|
}
|
2019-01-05 15:30:22 +01:00
|
|
|
$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;
|
2011-05-26 19:00:26 +02:00
|
|
|
}
|
|
|
|
|
2019-01-05 15:30:22 +01:00
|
|
|
$sendgrid_uri = 'https://api.sendgrid.com/v3/mail/send';
|
|
|
|
$json_parameters = phutil_json_encode($parameters);
|
2011-05-26 19:00:26 +02:00
|
|
|
|
2019-01-05 15:30:22 +01:00
|
|
|
id(new HTTPSFuture($sendgrid_uri))
|
|
|
|
->setMethod('POST')
|
|
|
|
->addHeader('Authorization', "Bearer {$key}")
|
|
|
|
->addHeader('Content-Type', 'application/json')
|
|
|
|
->setData($json_parameters)
|
|
|
|
->setTimeout(60)
|
|
|
|
->resolvex();
|
2011-05-26 19:00:26 +02:00
|
|
|
|
2019-01-05 15:30:22 +01:00
|
|
|
// 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.
|
|
|
|
}
|
2011-05-26 19:00:26 +02:00
|
|
|
|
2019-01-05 15:30:22 +01:00
|
|
|
private function newPersonalization(PhutilEmailAddress $address) {
|
|
|
|
$result = array(
|
|
|
|
'email' => $address->getAddress(),
|
|
|
|
);
|
2011-05-26 19:00:26 +02:00
|
|
|
|
2019-01-05 15:30:22 +01:00
|
|
|
$display_name = $address->getDisplayName();
|
|
|
|
if ($display_name) {
|
|
|
|
$result['name'] = $display_name;
|
2011-05-26 19:00:26 +02:00
|
|
|
}
|
|
|
|
|
2019-01-05 15:30:22 +01:00
|
|
|
return $result;
|
2011-05-26 19:00:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|