+1

NodeJs - Send mail by Mandrill API

Giới thiệu

Mandrill là dịch vụ SMTP Mail miễn phí được tạo ra bởi Mailchimp (một công ty với hơn 10 năm xây dựng nền tảng email marketing). Dịch vụ mail của Mandrill là dạng transaction email cho phép các tổ chức, cá nhân có nhu cầu xác thực thông tin của người dùng hoặc truyền thông điệp tự động tới người dùng các thông tin mang tính chất thông báo, thông tin cá nhân. Email Giao Dịch bao gồm các dạng email: khôi phục mật khẩu, email xác thực đơn hàng, email xác thực tài khoản, email thông tin đơn hàng, …

Tôi biết đến Mandrill được một thời gian khá lâu rồi, lúc đó bản thân gặp khá nhiều khó khăn trong việc config mail server. Config một hồi rồi thì cũng gửi được email, nhưng gửi được một vài mail tôi cảm thấy hệ thống chạy không được ổn định. Tôi đã suy nghĩ nếu sử dụng SMTP bên ngoài sẽ giúp giảm tải cho server, và tôi tin điều đó đúng. Tôi bắt tay tìm kiếm các nhà cung cấp dịch vụ SMTP trên internet, kết quả là đã tìm ra được dịch vụ Mandrill này, thứ mà tôi đang cần. Tôi sẽ giới thiệu với bạn về nó, cách sử dụng nó để gửi mail bằng nodejs.

Tại sao sử dụng mandrill

  • Miễn phí: Mandrill cho phép mỗi tháng gửi 12k mail miễn phí, thêm 0.2$ mỗi 1k email tiếp theo. Tính ra chi phí cũng không tốn nhiều, mà chưa chắc bạn đã sử dụng hết 12k/tháng.

  • Gửi mail dễ dàng: để tích hợp Mandrill vào hệ thống của bạn hãy lên API Document xem ngôn ngữ bạn làm là gì để tích hợp nó vào hệ thống gửi mail của bạn.

  • Custom template theo ý bạn: bạn có thể tạo 1 template bất kỳ và thiết đặt những thông tin sẽ thay thế trong template đó theo ý bạn muốn, bằng biến có định dạng *|VARIABLE| *

  • Mandrill điều chỉnh giới hạn gửi mail theo giờ tùy theo số lượng bạn sử dụng, hiện tại thì tôi đã kiểm nghiệm được rằng có thể gửi tối đa 2.167 mail/h

  • Tốc độ gửi nhanh: qua một số phép thử nghiệm, theo cảm nhận của tôi thấy mail của nhà cung cấp hosting tốc độ gửi hơi chậm, của Gmail cũng chậm và còn giới hạn gửi theo giờ, của Namecheap là good nhất cho phép gửi tối đa 500mail/h tuy nhiên nó chỉ có 1 cụm server ở Dallas, giờ thì có Mandrill là tốt nhất.

Sử dụng Mandrill như thế nào trong nodejs

Để tích hợp thư viện mandrill api vào hệ thống node js bạn cần chạy lệnh dưới để cài đặt

npm install mandrill-api
```

Cài đặt thành công bạn sẽ nhìn thấy trong project của bạn có thư viện
 _mandrill-api: `/node_modules/mandrill-api _`

Để sử dụng được Mandrill-api bạn cần phải đăng ký tài khoản trước http://mandrill.com/signup, Mandrill sẽ cung cấp cho bạn một API_KEY cho ứng dụng

Bạn phải khai báo như sau để sử dụng API

```JavaScript
var mandrill = require('mandrill-api/mandrill');
var mandrill_client = new mandrill.Mandrill('YOUR_API_KEY');
```

Với `YOUR_API_KEY` chính là API_KEY bạn đăng ký ở trên.

**Gửi mail bằng Send method**

Với cách gửi mail thông thường này cần chú ý rằng: kể từ sau ngày 01/12/2015 phải có SPF và DKIM mới có thể gửi được email thông qua tài khoản của bạn. Mục đích của việc này nhà cung cấp mong muốn bạn xác minh quyền sở hữu tên miền (google.com, yahoo.com, ...) hoặc những thông tin đăng ký là hợp lệ.

Thư được gửi từ tên miền hoặc tên miền chưa được xác minh mà không có SPF và DKIM hợp lệ sẽ bị từ chối với reject_reason, unsigned.

Khai báo đoạn mã như sau để thực hiện gửi một email bằng send method:

```JavaScript
var message = {
    "html": "<p>Example HTML content</p>",
    "text": "Example text content",
    "subject": "example subject",
    "from_email": "message.from_email@example.com",
    "from_name": "Example Name",
    "to": [{
            "email": "recipient.email@example.com",
            "name": "Recipient Name",
            "type": "to"
        }],
    "headers": {
        "Reply-To": "message.reply@example.com"
    },
    "important": false,
    "track_opens": null,
    "track_clicks": null,
    "auto_text": null,
    "auto_html": null,
    "inline_css": null,
    "url_strip_qs": null,
    "preserve_recipients": null,
    "view_content_link": null,
    "bcc_address": "message.bcc_address@example.com",
    "tracking_domain": null,
    "signing_domain": null,
    "return_path_domain": null,
    "merge": true,
    "merge_language": "mailchimp",
    "global_merge_vars": [{
            "name": "merge1",
            "content": "merge1 content"
        }],
    "merge_vars": [{
            "rcpt": "recipient.email@example.com",
            "vars": [{
                    "name": "merge2",
                    "content": "merge2 content"
                }]
        }],
    "tags": [
        "password-resets"
    ],
    "subaccount": "customer-123",
    "google_analytics_domains": [
        "example.com"
    ],
    "google_analytics_campaign": "message.from_email@example.com",
    "metadata": {
        "website": "www.example.com"
    },
    "recipient_metadata": [{
            "rcpt": "recipient.email@example.com",
            "values": {
                "user_id": 123456
            }
        }],
    "attachments": [{
            "type": "text/plain",
            "name": "myfile.txt",
            "content": "ZXhhbXBsZSBmaWxl"
        }],
    "images": [{
            "type": "image/png",
            "name": "IMAGECID",
            "content": "ZXhhbXBsZSBmaWxl"
        }]
};
var async = false;
var ip_pool = "Main Pool";
var send_at = "example send_at";
mandrill_client.messages.send({"message": message, "async": async, "ip_pool": ip_pool, "send_at": send_at}, function(result) {
    console.log(result);
    /*
    [{
            "email": "recipient.email@example.com",
            "status": "sent",
            "reject_reason": "hard-bounce",
            "_id": "abc123abc123abc123abc123abc123"
        }]
    */
}, function(e) {
    // Mandrill returns the error as an object with name and message keys
    console.log('A mandrill error occurred: ' + e.name + ' - ' + e.message);
    // A mandrill error occurred: Unknown_Subaccount - No subaccount exists with the id 'customer-123'
});
```

Trong đó

```TextileToHtml
| html <br/> ^string^  | the full HTML content to be sent |
| text <br/> ^string^ | optional full text content to be sent |
|subject <br/> ^string^  | the message subject |
| from_email <br/> ^string^  | the sender email address.
email |
| from_name <br/> ^string^ | optional from name to be used |
| to <br/> ^array^ | an array of recipient information
  `email*` is email address of the recipient
  `name` the optional display name to use for the recipient|
| headers <br/> ^struct^ | optional extra headers to add to the message (most headers are allowed) |
| important<br/> ^boolean^ | whether or not this message is important, and should be delivered ahead of non-important messages |
|track_opens<br/> ^boolean^ | whether or not to turn on open tracking for the message |
| track_clicks<br/> ^boolean^ | whether or not to turn on click tracking for the message |
| auto_text<br/> ^boolean^ | whether or not to automatically generate a text part for messages that are not given text |
| auto_html<br/> ^boolean^| whether or not to automatically generate an HTML part for messages that are not given HTML |
|inline_css<br/> ^boolean^ | whether or not to automatically inline all CSS styles provided in the message HTML - only for HTML documents less than 256KB in size |
| url_strip_qs<br/> ^boolean^ | whether or not to strip the query string from URLs when aggregating tracked URL data |
| preserve_recipients<br/> ^boolean^ | whether or not to expose all recipients in to "To" header for each email |
| view_content_link<br/> ^boolean^ | set to false to remove content logging for sensitive emails |
| bcc_address<br/> ^string^ | an optional address to receive an exact copy of each recipient's email |
| tracking_domain<br/> ^string^ | a custom domain to use for tracking opens and clicks instead of mandrillapp.com |
| signing_domain<br/> ^string^ | a custom domain to use for SPF/DKIM signing instead of mandrill (for "via" or "on behalf of" in email clients) |
| return_path_domain<br/> ^string^ | a custom domain to use for the messages's return-path |
|merge<br/> ^boolean^ | whether to evaluate merge tags in the message. Will automatically be set to true if either merge_vars or global_merge_vars are provided. |
| merge_language<br/> ^string^ | the merge tag language to use when evaluating merge tags, either mailchimp or handlebars
oneof(mailchimp, handlebars) |
| global_merge_vars<br/> ^array^ | a single global merge variable
`name` the global merge variable's name. Merge variable names are case-insensitive and may not start with _
`content` the global merge variable's content|
| merge_vars<br/> ^array^ | per-recipient merge variables, which override global merge variables with the same name.
`rcpt*` the email address of the recipient that the merge variables should apply to
`vars` the recipient's merge variables
|
| tags<br/> ^array^ | an array of string to tag the message with. Stats are accumulated using tags, though we only store the first 100 we see, so this should not be unique or change frequently. Tags should be 50 characters or less. Any tags starting with an underscore are reserved for internal use and will cause errors. |
| subaccount<br/> ^string^ | the unique id of a subaccount for this message - must already exist or will fail with an error |
| google_analytics_domains<br/> ^array^ | an array of strings indicating for which any matching URLs will automatically have Google Analytics parameters appended to their query string automatically. |
| google_analytics_campaign<br/> ^array^ | optional string indicating the value to set for the utm_campaign tracking parameter. If this isn't provided the email's from address will be used instead. |
| metadata<br/> ^array^ | metadata an associative array of user metadata. Mandrill will store this metadata and make it available for retrieval. In addition, you can select up to 10 metadata fields to index and make searchable using the Mandrill search api. |
| recipient_metadata<br/> ^array^ | Per-recipient metadata that will override the global values specified in the metadata parameter.
`rcpt` the email address of the recipient that the metadata is associated with
`values` an associated array containing the recipient's unique metadata. If a key exists in both the per-recipient metadata and the global metadata, the per-recipient metadata will be used.|
| attachments<br/> ^array^ | an array of supported attachments to add to the message |
| images<br/> ^array^ | an array of embedded images to add to the message |
| async<br/> ^boolean^ | enable a background sending mode that is optimized for bulk sending. In async mode, messages/send will immediately return a status of "queued" for every recipient. |
| ip_pool<br/> ^string^ | the name of the dedicated ip pool that should be used to send the message. If you do not have any dedicated IPs, this parameter has no effect. If you specify a pool that does not exist, your default pool will be used instead. |
| send_at<br/> ^string^ | this message should be sent as a UTC timestamp in YYYY-MM-DD HH:MM:SS format. |
```

Kết quả trả về sẽ có định dạng format

```TextileToHtml
| email<br/> ^string^ | the email address of the recipient |
| status<br/> ^string^| the sending status of the recipient - either "sent", "queued", "scheduled", "rejected", or "invalid"|
| reject_reason<br/> ^string^| the reason for the rejection if the recipient status is "rejected" - one of "hard-bounce", "soft-bounce", "spam", "unsub", "custom", "invalid-sender", "invalid", "test-mode-limit", "unsigned", or "rule" |
| _id<br/> ^string^| the message's unique id |
```

**Gửi mail bằng Send Template**

Bạn đăng nhập vào [mandrillapp.com](http://mandrillapp.com) và đi đến phần tạo templates trong mục outbound.

Sau đó tạo mới hoàn toàn một template giống như tôi tạo template tên là Test test-template

 ![Screenshot_2.png](https://images.viblo.asia/e16bf252-397b-46a1-9473-802ebf2ea866.png)

Sử dụng script như sau để gọi phương thức send template

```JavaScript
var template_name = "Test test-template"
        template_content = [{}],
        message = {
            "from_email": "emailfrom@your.rentals",
            "from_name": "Mr.Daskine",
            "to": [{
                "email":  "emailto@your.rentals",
                "name": "Mr Daskine",
                "type": "to"
            }],
            "headers": {
                "Reply-To": "emailfrom@your.rentals"
            },
            "global_merge_vars": [
                {
                    "name": "USER_EMAIL",
                    "content":  "emailto@your.rentals"
                },
                {
                    "name": "USER_NAME",
                    "content": "Mr Daskine"
                },
                {
                    "name": "SUBJECT",
                    "content": "Thanks for signing-up"
                }
            ],
            "merge_vars": [
                {
                    "rcpt": "support@your.rentals",
                    "vars": [{}]
                }
            ]
        },
        async = false,
        ip_pool = "Main Pool",
        send_at = "send_at";
    mandrill_client.messages.sendTemplate(
        {
            "template_name": template_name,
            "template_content": template_content,
            "message": message,
            "async": async,
            "ip_pool": ip_pool,
            "send_at": send_at
        },
        function(result) {
        },
        function(e) {
    );
```

Trong đó các tham số truyền lên và giá trị trả về tương tự **Gửi mail bằng Send method**

Khi gửi email chạy thành công như bên dưới

![Screenshot_3.png](https://images.viblo.asia/8c8e37e8-cded-48be-80be-35d63f7982f2.png)

**Kết thúc**

Qua bài viết này các bạn đã thấy được Mandrilll-Api sử dụng trong nodeJs rất dễ dàng phải không? Mong rằng bạn có thể vận dụng nó vào trong project của bạn.

Bạn có thể tham khảo link git: https://github.com/tuandv2611/nodejs-mandrill-api/tree/first-commit

Ngoài ra, Mandrill còn cung cấp nhiều API khác rất tiện lợi cho việc quản lý thông tin email gửi và tracking email. Bạn có thể tham khảo và tìm hiểu thêm tại đây nhé https://mandrillapp.com/api/docs/


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí