我对AWS比较新,我试图通过Lambda函数处理我的电子邮件。我在node.js中构建了这个:
'use strict';
exports.handler = (event, context, callback) => {
var http = require('http');
var data = JSON.stringify(event);
var options = {
host: 'my.host',
port: '80',
path: '/my/path',
method: 'POST',
headers: {
'Content-Type': 'application/json; charset=utf-8',
'Content-Length': data.length
}
};
var req = http.request(options, function(res) {
var msg = '';
res.setEncoding('utf8');
res.on('data', function(chunk) {
msg += chunk;
});
res.on('end', function() {
console.log(JSON.parse(msg));
});
});
req.write(data);
req.end();
};
我已经使用端点进行了测试并且它运行良好,问题是我刚刚意识到邮件正文从未发送过。如何访问邮件正文以发送邮件并由我的api处理?
如果您需要查看发送的样品,请告诉我。
答案 0 :(得分:5)
所以我所做的就是将收到的电子邮件存储在S3存储桶中,而不是通知我的api新邮件已经到达(发送文件名)。最后从S3读取,解析,存储和删除S3,在我的api中。
Lambda通知功能:
请注意,第一条规则创建的S3文件的名称与邮件ID相同,因此
'fileName': event.Records[0].ses.mail.messageId
。
'use strict';
exports.handler = (event, context, callback) => {
var http = require('http');
var data = JSON.stringify({
'fileName': event.Records[0].ses.mail.messageId,
});
var options = {
host: 'my.host',
port: '80',
path: '/my/path',
method: 'POST',
headers: {
'Content-Type': 'application/json; charset=utf-8',
'Content-Length': data.length
}
};
var req = http.request(options, function(res) {
var msg = '';
res.setEncoding('utf8');
res.on('data', function(chunk) {
msg += chunk;
});
res.on('end', function() {
console.log(JSON.parse(msg));
context.succeed();
});
});
req.write(data);
req.end();
};
Api功能(PHP - Laravel):
请注意,我正在使用基于Plancake电子邮件解析器(链接here)的电子邮件解析器以及我自己的一些更改,如果需要,我将进行编辑以显示源。
public function process_incoming_email(Request $request)
{
$current_time = Carbon::now()->setTimezone('Brazil/East'); // ALL TIMEZONES: http://us.php.net/manual/en/timezones.others.php
try
{
if ($request->has('fileName')
{
$file_name = $request->input('fileName');
// GET CREDENTIALS AND AUTHENTICATE
$credentials = CredentialProvider::env();
$s3 = new S3Client([
'version' => 'latest',
'region' => 'my-region',
'credentials' => $credentials
]);
// FECTH S3 OBJECT
$object = $s3->GetObject(['Bucket' => 'my-bucket', 'Key' => $file_name]);
$body = $object['Body']->getContents();
// PARSE S3 OBJECT
$parser = new EmailParser($body);
$receivers = ['to' => $parser->getTo(), 'cc' => $parser->getCc()];
$from = $parser->getFrom();
$body_plain = $parser->getPlainBody();
$body_html = $parser->getHTMLBody();
$subject = $parser->getSubject();
$error_message;
// PROCESS EACH RECEIVER
foreach ($receivers as $type => $type_receivers)
{
foreach ($type_receivers as $receiver)
{
// PROCESS DOMAIN-MATCHING RECEIVERS
if(preg_match("/@(.*)/", $receiver['email'], $matches) && $matches[1] == self::HOST)
{
// INSERT NEW EMAIL
$inserted = DB::table('my-emails')->insert([
// ...
]);
}
}
}
// ADD ERROR LOG IF PARSER COULD NOT FIND EMAILS
if($email_count == 0)
{
DB::table('my-logs')->insert(
['sender' => $request->ip(), 'type' => 'error', 'content' => ($error_message = 'Could not parse received email or find a suitable user receiving email.') . ' File: ' . $file_name]
);
}
// DELETE OBJECT FROM S3 IF INSERTED
else if(count($emails) == $email_count)
{
$s3->deleteObject(['Bucket' => 'my-bucket', 'Key' => $file_name]);
// RETURN SUCCESSFUL JSON RESPONSE
return Response::json(['success' => true, 'receivedAt' => $current_time, 'message' => 'Email successfully received and processed.']);
}
// ADD ERROR LOG IF NOT INSERTED
else
{
DB::table('my-logs')->insert(
['sender' => $request->ip(), 'type' => 'error', 'content' => ($error_message = 'Inserted ' . count($emails) . ' out of ' . $email_count . ' parsed records.') . ' File: ' . $file_name]
);
}
}
else
{
// ERROR: NO fileName FIELD IN RESPONSE
DB::table('my-logs')->insert(
['sender' => $request->ip(), 'type' => 'error', 'content' => ($error_message = 'Incorrect request input format.') . ' Input: ' . json_encode($request->all())]
);
}
}
// ERROR TREATMENT
catch(Exception $ex)
{
DB::table('my-logs')->insert(
['sender' => $request->ip(), 'type' => 'error', 'content' => ($error_message = 'An exception occurred while processing an incoming email.') . ' Details: ' . $ex->getMessage()]
);
}
// RETURN FAILURE JSON RESPONSE
return Response::json(['success' => false, 'receivedAt' => $current_time, 'message' => $error_message]);
}
答案 1 :(得分:1)
我有一个非常类似的解决方案,但步骤少了一步。可以设置lambda触发器。因此,我创建了一个存储桶myemailbucket
,并将来自SES的邮件发送到该存储桶。然后我将lambda函数的触发器更改为存储桶myemailbucket
中s3中的任何create事件。