Gửi tệp đính kèm trong email với Amazone SES (send attachment file in email with Amazone SES)

Amazone SES là một service rất quen thuộc đối với chúng ta khi gửi email marketing.Đối với việc gửi mail thì đôi khi yêu cầu ta cần gửi tệp đính kèm trong email.Tuy nhiên, khi mình mới làm việc với yêu cầu này lần đầu thì mình thấy rằng doc của Amazone chưa đủ cụ thể để có thể giúp mình có thể đọc doc và hoàn thành được luôn, ngay cả khi searh về vấn đề này mình cũng không tìm được hướng dẫn tốt hay giải đáp để có thể làm được nên mình đã tốn nhiều thời gian hơn để tự test.Vậy nên mình sẽ viết phần giới thiệu này để những ai tiếp xúc với vấn đề này lần đầu có thể nhanh chóng nắm bắt được cách gửi mail có thêm tệp đính kèm đối với SES email.

Setting.

Để có thể sử dụng SES thì ta cần có access_key_idsecret_access_key , để có thể lấy chúng, thì bạn có thể tham khảo những bài viết về hướng dẫn gửi mail trong Amazone SES nhé, trên Viblo đã có khá nhiều rồi. Ta có thể khởi tạo như sau với 2 key trên:

client = Aws::SES::Client.new {
     access_key_id: "********************************",
     secret_access_key: "********************************",
     region: "us-west-2"
 }

Send mail:

Ta sẽ dùng send_raw_email để gửi mail, cùng xem cú pháp và ví dụ cụ thể trong doc của Amazone như sau: Cú pháp:

resp = client.send_raw_email({
  source: "Address",
  destinations: ["Address"],
  raw_message: { # required
    data: "data", # required
  },
  from_arn: "AmazonResourceName",
  source_arn: "AmazonResourceName",
  return_path_arn: "AmazonResourceName",
  tags: [
    {
      name: "MessageTagName", # required
      value: "MessageTagValue", # required
    },
  ],
  configuration_set_name: "ConfigurationSetName",
})

Ví dụ:


# The following example sends an email with an attachment:

resp = client.send_raw_email({
  destinations: [
  ], 
  from_arn: "", 
  raw_message: {
    data: "From: [email protected]\\nTo: [email protected]\\nSubject: Test email (contains an attachment)\\nMIME-Version: 1.0\\nContent-type: Multipart/Mixed; boundary=\"NextPart\"\\n\\n--NextPart\\nContent-Type: text/plain\\n\\nThis is the message body.\\n\\n--NextPart\\nContent-Type: text/plain;\\nContent-Disposition: attachment; filename=\"attachment.txt\"\\n\\nThis is the text in the attachment.\\n\\n--NextPart--", 
  }, 
  return_path_arn: "", 
  source: "", 
  source_arn: "", 
})

# resp.to_h outputs the following:
{
  message_id: "EXAMPLEf3f73d99b-c63fb06f-d263-41f8-a0fb-d0dc67d56c07-000000", 
}

Trong đó:

  • :source (String) : Nhận dạng của địa chỉ email.Nếu không setting giá trị này thì bắt buộc ta phải setting cho giá trị địa chỉ của \"From\" trong phần data của raw_message(Bạn có thể setting cả 2 phần này.) Nếu thiết lập giá trị cho Source và bật chức năng chuyển tiếp phản hồi thì khi phát sinh những mail bounces hoặc spam sẽ được gửi về địa chỉ mail này.Việc này được ưu tiên hơn cả việc bạn set giá trị cho Return-Path trong Header trong phần raw text.
  • :destinations (Array<String>) : Danh sách địa chỉ nhận mail, bao gồm cả mail CCBCC.
  • :raw_message (required, Types::RawMessage) : Dạng văn bản thô của email, chúng ta cần đảm bảo những thông tin sau:
  1. Mail phải có phần header và phần body, ngăn cách nhau bởi dòng trắng.
  2. Tất cả những trường require của Header bắt buộc phải present. 3.Mỗi phần của MIME multipart phải được định dạng đúng. 4.Loại nội dung MIME phải nằm trong số những loại được Amazone SES hỗ trợ, xem thêm tại : Amazon SES Developer Guide. 5.Phải ở dạng mã hóa base64. 6.Mỗi RFC 5321, chiều dài tối đa của mỗi dòng bao gồm cả <CRLF> là 1000.
  • :from_arn (String) Parametters dùng để gửi authorization. Thay vì sử dụng parametter này, ta có thể dùng X-SES-FROM-ARN trong phần raw message.Nếu sử dụng cả FromArnX-SES-FROM-ARN thì Amazone SES sẽ sử dụng giá trị từ FromArn. ...

Áp dụng.

Phần raw_message là phần quan trọng nhất để có thể gửi mail với tệp đính kèm, tuy nhiên nếu đọc ví dụ của SES mà bạn chưa thể tự viết được nội dung cho phần raw_message thì hãy tham khảo đoạn code sau của mình:

def raw_message
    message_data = raw_message_body
    message_data += message_attachment_body(attachment)
    {
      raw_message: {
        data: message_data
      }
    }
  end
def raw_message_body
    <<-EOS
From: #{from} //Địa chỉ gửi
To: #{to} //Địa chỉ nhận mail (bắt buộc phải có)
BCC: #{bcc.join(",")} //Mail Bcc, có thể có hoặc không tùy bạn.
Subject: #{subject} //subject của mail
MIME-Version: 1.0
Content-type: Multipart/Mixed; boundary="NextPart" //Raw message sẽ được nối với nhau bở các phần trong NextPart

--NextPart
Content-Type: text/plain;
#{content}

    EOS
  end

  def message_attachment_body(attachment)
    <<-EOS
--NextPart
Content-Type: #{attachment.content_type}; name="#{attachment.original_filename}"
Content-Description: #{attachment.original_filename}
Content-Disposition: attachment; filename="#{attachment.original_filename}";
Content-Transfer-Encoding: base64

#{base64_attachment(attachment)}
--NextPart
    EOS
  end

  def base64_attachment(attachment)
    Base64.encode64(open(attachment.tempfile.path){|io| io.read})
  end

Lưu ý rằng nội dung của attachment phải được encode dưới dạng Base64 và các thông tin cũng như nội dung của tệp đính kèm cũng phải đầy đủ như thông tin trong hàm message_attachment_body.

Tham khảo.

http://docs.aws.amazon.com/sdkforruby/api/Aws/SES/Client.html#send_raw_email-instance_method