2016-11-10 13 views
5

Tôi tương đối mới đối với AWS và tôi đang cố gắng xử lý email của mình qua Hàm Lambda. Tôi đã xây dựng cái này trong node.js:SES: Truy cập vào nội dung email bên trong hàm lambda

'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(); 
}; 

Tôi đã thử nghiệm với điểm cuối và nó hoạt động hoàn hảo, vấn đề là tôi vừa mới nhận ra rằng phần thân của thông điệp không bao giờ được gửi đi. Làm thế nào tôi có thể truy cập vào nội dung của tin nhắn để gửi và được xử lý bởi api của tôi?

Nếu bạn cần xem mẫu nội dung gửi cho tôi biết.

Trả lời

4

Vì vậy, những gì tôi đã làm là lưu trữ email nhận được trong một thùng S3, hơn thông báo cho api của tôi rằng một email mới đã đến (gửi tên tệp). Cuối cùng đọc từ S3, phân tích cú pháp, lưu trữ và xóa khỏi S3, bên trong api của tôi.

quy tắc SES: SES rules

Lambda chức năng thông báo:

Lưu ý rằng tên của tập tin S3 tạo ra bởi các quy tắc đầu tiên là giống như thông điệp id, do đó '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 chức năng (PHP - Laravel):

Lưu ý rằng tôi đang sử dụng một phân tích cú pháp email được dựa trên Plancake Email Parser (liên kết here) với một số thay đổi của riêng tôi và nếu cần, tôi sẽ chỉnh sửa để hiển thị nguồn.

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

Cảm ơn bạn đã theo dõi. Ran vào cùng một vấn đề. Dường như một chút ngớ ngẩn (chưa kể đến không hiệu quả) mà chúng ta phải nhảy qua rất nhiều vòng để có được cơ thể thông điệp. Đây có phải là giải pháp tương tự mà bạn đang sử dụng ngày nay không? – DaveJ

+1

@DaveJ Thật không may:/ –

+1

@MatheusSimon - Tôi đang cố gắng để có được một cái gì đó rất giống với bản thân chạy với laravel 5.4, Im sử dụng SES để chấp nhận tất cả các email đến và chúng hiện đang được lưu trữ trong S3, suy nghĩ ban đầu của tôi là phân tích chúng với một hàm javascript trên Lambda và sau đó gửi chúng qua laravel để lưu trữ trong DB và hiển thị trong ứng dụng, tôi có thể tránh lambda hoàn toàn với bộ phân tích email mà bạn đã sử dụng bằng cách tìm nạp đối tượng S3 mà SES lưu trữ không? Đánh giá cao sự giúp đỡ nào, Cảm ơn. – Birdy

1

tôi có một giải pháp rất giống với một trong những khác, nhưng với một bước ít hơn. Có thể đặt bộ kích hoạt lambda. Vì vậy, tôi đã tạo một thùng myemailbucket và đã gửi thư từ SES tới nhóm đó. Sau đó, tôi thay đổi kích hoạt cho hàm lambda của tôi thành bất kỳ sự kiện tạo nào trong s3 trong thùng myemailbucket.

Các vấn đề liên quan