如何通过 Mailgun 通过电子邮件发送 Twilio SMS 附件?
How can I email Twilio SMS attachments via Mailgun?
背景: 我使用自己的网络应用程序通过 Twilio 发送和接收 SMS 消息。我将图像附件插入邮件正文,但希望将其他附件类型(例如 PDF)发送到我的邮件帐户。
答案:(见下文。)
投反对票者的注意事项(他们认为我不应该问和回答我自己的问题:
请花时间阅读 official Whosebug policy(这是我在撰写 post 之前所做的)。截至该日期,它显示为...
Can I answer my own question?
Yes! Stack Exchange has always explicitly encouraged users to answer
their own questions. If you have a question that you already know the
answer to, and you would like to document that knowledge in public so
that others (including yourself) can find it later, it's perfectly
okay to ask and answer your own question on a Stack Exchange site.
To encourage people to do this, there is a checkbox at the bottom of
the page every time you ask a question. If you have more than 15
reputation and already know the answer, click the checkbox that says
"Answer your own question" at the bottom of the Ask Question page.
Type in your answer, then submit both question and answer together.
有道理,对吧?在这种情况下,post 提供有关两个非常流行的服务(即 Twilio 和 Mailgun)的信息。如果一个沮丧的开发人员碰壁了,为什么他们要问一个问题并等待答案而不是轻易地找到答案呢? 99% 的时间,我无需 post 提问即可在 StackExchange 上找到答案。
在浏览媒体附件时,我寻找任何不是 .jpg、.gif 或 .png 的文件。
// Look for attachments
$numMedia = $_REQUEST["NumMedia"];
if ($numMedia > 0) {
$attachments = "\n\n";
// Step through list
for ($i = 0; $i < $numMedia; $i++) {
// Get the attachment's URL on Twilio
$attachment = $_REQUEST["MediaUrl" . $i];
// If not .jpg, .gif, or .png
if (!preg_match('~(image/jpeg|image/gif|image/png)~', $_REQUEST["MediaContentType" . $i])) {
// Inform user in message body
$attachments .= "[A non-image file was sent.]\n\n";
// Note the presence of a non-image attachment
$nonImageAttachment = true;
}
// If image, add a link and image tag to the message body
else {
$attachments .= "<a href='" . $attachment . "' target='_blank'><img src='" . $attachment . "' target='_blank'></a>\n\n";
}
}
// If there are any non-image attachments, trigger the emailAttachment function
if ($nonImageAttachment) {
emailAttachments();
}
}
如果发现任何非图像附件,将触发emailAttachments
功能。该功能通过电子邮件发送所有附件(甚至图像),以便将单个 SMS 中的所有附件保存在一起。
function emailAttachments() {
// Get global variables for Twilio and Mailgun
global $twilio_source, $twilio_sid, $twilio_token;
global $mailTo, $mailFrom, $mailgun_api_key, $mailgun_url, $mailgun_domain;
// Step through all attachments
$numMedia = $_REQUEST["NumMedia"];
if ($numMedia > 0) {
// Note the recipient's number (in case we need to notify SMS sender of a problem)
$to = $_REQUEST["To"];
// Use the sender's number and the time for forming a filename
$from = $_REQUEST["From"];
$numericFrom = preg_replace("/[^\d]/", "", $from);
$timestamp = round(microtime(true));
// Format the sender's phone number for use in the Subject and Body
$prefix = substr($from, 1, 1);
$areaCode = substr($from, 2, 3);
$exchange = substr($from, 5, 3);
$line = substr($from, 8);
$formattedFrom = "{$prefix} ({$areaCode}) {$exchange}-{$line}";
// Include the attachment count in the Subject (plural if appropriate)
$description = $numMedia . " " . ($numMedia == 1 ? "attachment" : "attachments");
$subject = "Forwarding {$description} from {$formattedFrom}.";
// Include any SMS Body text in the email's Body
$body = $_REQUEST["Body"];
$message = "<p>SMS from {$formattedFrom}</p><p style='margin-left:20px; margin-right:20px; font-family:monospace; color:navy;'>{$body}</p>";
// Specify the Mailgun parameters (not including the attachments)
$mailgunParams = array(
"from" => $mailFrom,
"to" => $mailTo,
"subject" => $subject,
"html" => $message
);
// Set a directory and start fetching from Twilio
$directory = "downloads/";
for ($i = 0; $i < $numMedia; $i++) {
// Get the content type that Twilio sent and combine it with the sender's number, the timestamp, file number, and proper extension
$contentType = $_REQUEST["MediaContentType" . $i];
$filename = $numericFrom . "." . $timestamp . "." . ($i + 1) . "." . substr($contentType, strrpos($contentType, "/") + 1);
// Open a file in the download directory
$file = fopen($directory . $filename, "w+");
// Fetch the file content with cURL
$ch = curl_init();
$options = array(
CURLOPT_HTTPGET => true,
CURLOPT_URL => $_REQUEST["MediaUrl" . $i],
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
CURLOPT_USERPWD => "$twilio_sid:$twilio_token",
CURLOPT_FILE => $file
);
curl_setopt_array($ch, $options);
curl_exec($ch);
// Close connection
curl_close($ch);
// Add the file information to the Mailgun array
$mailgunParams["attachment[$i]"] = curl_file_create($directory . $filename);
}
// Establish cURL connection to Mailgun
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, "api:" . $mailgun_api_key);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_URL, "https://api.mailgun.net/v3/" . $mailgun_domain . "/messages");
curl_setopt($ch, CURLOPT_POSTFIELDS, $mailgunParams);
// Parse the result
$response = curl_exec($ch);
$response = strtolower(str_replace("\n", "", trim($response)));
$result= json_decode($response, true);
$status = explode(".", $result["message"]);
// If the message was not queued, trigger function to notify the sender and post error to log
if ($status[0] !== "queued") {
notifySender($from, $to);
error_log("Message not sent because of " . print_r($status, true));
}
// Close connection
curl_close($ch);
// Step through the attachment list one more time, and delete the files from the server
for ($i = 0; $i < $numMedia; $i++) {
$filename = $numericFrom . "." . $timestamp . "." . ($i + 1) . "." . substr($contentType, strrpos($contentType, "/") + 1);
unlink($directory . $filename);
}
}
}
如果 Mailgun 没有将邮件排队,通知发件人通过电子邮件发送附件。
function notifySender($respondTo, $respondingFrom) {
// Get parameters for sending through Twilio, as well as a callback URL
global $twilio_sid, $twilio_token;
global $website_URL;
// Get the email address that you want the Sender to use for sending attachments via email instead of SMS
global $mailToAlternative;
// Set any parameters you want Twilio to return (e.g., origination time to monitor performance)
$timestamp = round(microtime(true));
$callback = $website_URL . "?originated=" . $timestamp;
// Create Twilio array
$params = array (
"From" => $respondingFrom,
"Body" => " SERVER AUTO-REPLY:\n\nPlease re-send non-image file(s) to…\n\n{$mailToAlternative}",
"StatusCallback" => $callback
);
// Send to Twilio
$client = new Client($twilio_sid, $twilio_token);
$message = $client->messages->create($respondTo, $params);
// Optionally do something with the result (e.g., write to log file)
$sid = $message->sid;
$status = $message->status;
}
背景: 我使用自己的网络应用程序通过 Twilio 发送和接收 SMS 消息。我将图像附件插入邮件正文,但希望将其他附件类型(例如 PDF)发送到我的邮件帐户。
答案:(见下文。)
投反对票者的注意事项(他们认为我不应该问和回答我自己的问题:
请花时间阅读 official Whosebug policy(这是我在撰写 post 之前所做的)。截至该日期,它显示为...
Can I answer my own question?
Yes! Stack Exchange has always explicitly encouraged users to answer their own questions. If you have a question that you already know the answer to, and you would like to document that knowledge in public so that others (including yourself) can find it later, it's perfectly okay to ask and answer your own question on a Stack Exchange site.
To encourage people to do this, there is a checkbox at the bottom of the page every time you ask a question. If you have more than 15 reputation and already know the answer, click the checkbox that says "Answer your own question" at the bottom of the Ask Question page. Type in your answer, then submit both question and answer together.
有道理,对吧?在这种情况下,post 提供有关两个非常流行的服务(即 Twilio 和 Mailgun)的信息。如果一个沮丧的开发人员碰壁了,为什么他们要问一个问题并等待答案而不是轻易地找到答案呢? 99% 的时间,我无需 post 提问即可在 StackExchange 上找到答案。
在浏览媒体附件时,我寻找任何不是 .jpg、.gif 或 .png 的文件。
// Look for attachments
$numMedia = $_REQUEST["NumMedia"];
if ($numMedia > 0) {
$attachments = "\n\n";
// Step through list
for ($i = 0; $i < $numMedia; $i++) {
// Get the attachment's URL on Twilio
$attachment = $_REQUEST["MediaUrl" . $i];
// If not .jpg, .gif, or .png
if (!preg_match('~(image/jpeg|image/gif|image/png)~', $_REQUEST["MediaContentType" . $i])) {
// Inform user in message body
$attachments .= "[A non-image file was sent.]\n\n";
// Note the presence of a non-image attachment
$nonImageAttachment = true;
}
// If image, add a link and image tag to the message body
else {
$attachments .= "<a href='" . $attachment . "' target='_blank'><img src='" . $attachment . "' target='_blank'></a>\n\n";
}
}
// If there are any non-image attachments, trigger the emailAttachment function
if ($nonImageAttachment) {
emailAttachments();
}
}
如果发现任何非图像附件,将触发emailAttachments
功能。该功能通过电子邮件发送所有附件(甚至图像),以便将单个 SMS 中的所有附件保存在一起。
function emailAttachments() {
// Get global variables for Twilio and Mailgun
global $twilio_source, $twilio_sid, $twilio_token;
global $mailTo, $mailFrom, $mailgun_api_key, $mailgun_url, $mailgun_domain;
// Step through all attachments
$numMedia = $_REQUEST["NumMedia"];
if ($numMedia > 0) {
// Note the recipient's number (in case we need to notify SMS sender of a problem)
$to = $_REQUEST["To"];
// Use the sender's number and the time for forming a filename
$from = $_REQUEST["From"];
$numericFrom = preg_replace("/[^\d]/", "", $from);
$timestamp = round(microtime(true));
// Format the sender's phone number for use in the Subject and Body
$prefix = substr($from, 1, 1);
$areaCode = substr($from, 2, 3);
$exchange = substr($from, 5, 3);
$line = substr($from, 8);
$formattedFrom = "{$prefix} ({$areaCode}) {$exchange}-{$line}";
// Include the attachment count in the Subject (plural if appropriate)
$description = $numMedia . " " . ($numMedia == 1 ? "attachment" : "attachments");
$subject = "Forwarding {$description} from {$formattedFrom}.";
// Include any SMS Body text in the email's Body
$body = $_REQUEST["Body"];
$message = "<p>SMS from {$formattedFrom}</p><p style='margin-left:20px; margin-right:20px; font-family:monospace; color:navy;'>{$body}</p>";
// Specify the Mailgun parameters (not including the attachments)
$mailgunParams = array(
"from" => $mailFrom,
"to" => $mailTo,
"subject" => $subject,
"html" => $message
);
// Set a directory and start fetching from Twilio
$directory = "downloads/";
for ($i = 0; $i < $numMedia; $i++) {
// Get the content type that Twilio sent and combine it with the sender's number, the timestamp, file number, and proper extension
$contentType = $_REQUEST["MediaContentType" . $i];
$filename = $numericFrom . "." . $timestamp . "." . ($i + 1) . "." . substr($contentType, strrpos($contentType, "/") + 1);
// Open a file in the download directory
$file = fopen($directory . $filename, "w+");
// Fetch the file content with cURL
$ch = curl_init();
$options = array(
CURLOPT_HTTPGET => true,
CURLOPT_URL => $_REQUEST["MediaUrl" . $i],
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
CURLOPT_USERPWD => "$twilio_sid:$twilio_token",
CURLOPT_FILE => $file
);
curl_setopt_array($ch, $options);
curl_exec($ch);
// Close connection
curl_close($ch);
// Add the file information to the Mailgun array
$mailgunParams["attachment[$i]"] = curl_file_create($directory . $filename);
}
// Establish cURL connection to Mailgun
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, "api:" . $mailgun_api_key);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_URL, "https://api.mailgun.net/v3/" . $mailgun_domain . "/messages");
curl_setopt($ch, CURLOPT_POSTFIELDS, $mailgunParams);
// Parse the result
$response = curl_exec($ch);
$response = strtolower(str_replace("\n", "", trim($response)));
$result= json_decode($response, true);
$status = explode(".", $result["message"]);
// If the message was not queued, trigger function to notify the sender and post error to log
if ($status[0] !== "queued") {
notifySender($from, $to);
error_log("Message not sent because of " . print_r($status, true));
}
// Close connection
curl_close($ch);
// Step through the attachment list one more time, and delete the files from the server
for ($i = 0; $i < $numMedia; $i++) {
$filename = $numericFrom . "." . $timestamp . "." . ($i + 1) . "." . substr($contentType, strrpos($contentType, "/") + 1);
unlink($directory . $filename);
}
}
}
如果 Mailgun 没有将邮件排队,通知发件人通过电子邮件发送附件。
function notifySender($respondTo, $respondingFrom) {
// Get parameters for sending through Twilio, as well as a callback URL
global $twilio_sid, $twilio_token;
global $website_URL;
// Get the email address that you want the Sender to use for sending attachments via email instead of SMS
global $mailToAlternative;
// Set any parameters you want Twilio to return (e.g., origination time to monitor performance)
$timestamp = round(microtime(true));
$callback = $website_URL . "?originated=" . $timestamp;
// Create Twilio array
$params = array (
"From" => $respondingFrom,
"Body" => " SERVER AUTO-REPLY:\n\nPlease re-send non-image file(s) to…\n\n{$mailToAlternative}",
"StatusCallback" => $callback
);
// Send to Twilio
$client = new Client($twilio_sid, $twilio_token);
$message = $client->messages->create($respondTo, $params);
// Optionally do something with the result (e.g., write to log file)
$sid = $message->sid;
$status = $message->status;
}