Computer >> Máy Tính >  >> Phần mềm >> Thư

Cách gửi bản tin email bằng API SendGrid

Trong nhiều năm, Quincy Larson đã gửi bản tin email hàng tuần thông qua nền tảng Mail for Good của freeCodeCamp, được cung cấp bởi Amazon SES.

Gần đây anh ấy đã di chuyển quy trình này sang SendGrid. Trong bài viết này, tôi sẽ chỉ cho bạn cách tôi đã xây dựng một công cụ để thực hiện điều này.

Cách thiết lập tài khoản SendGrid

Bước đầu tiên là đăng ký SendGrid và thiết lập tài khoản của bạn. Đối với mục đích của hướng dẫn này, cấp miễn phí phải là đủ.

Khi mở rộng quy mô ứng dụng của mình, bạn có thể cần tăng giới hạn email khả dụng của mình thông qua nền tảng này.

Cách thiết lập địa chỉ IP chuyên dụng trên SendGrid

Theo mặc định, SendGrid sử dụng địa chỉ IP được chia sẻ để gửi email. Điều này có thể được chấp nhận đối với các ứng dụng email quy mô nhỏ hơn, nhưng khi bạn tăng tỷ lệ gửi, bạn sẽ cần thiết lập một địa chỉ IP chuyên dụng.

Đây là một ý tưởng hay vì "danh tiếng người gửi" của bạn (số liệu mà SendGrid sử dụng để đánh giá vị thế của bạn với các nhà cung cấp dịch vụ email) sẽ không bị tác động tiêu cực bởi hành động của những người dùng khác có cùng IP.

Để thiết lập IP chuyên dụng của riêng bạn, hãy chọn tùy chọn "Cài đặt" từ menu điều hướng bên, sau đó chọn "Địa chỉ IP". Tuy nhiên, chỉ cần lưu ý nhanh:tùy chọn này không khả dụng trên cấp miễn phí.

Tùy thuộc vào gói trả phí của bạn, bạn có thể đã thiết lập một địa chỉ IP chuyên dụng. Nếu bạn chưa có hoặc nếu bạn chọn thêm địa chỉ khác, bạn có thể chọn nút "Thêm địa chỉ IP" để định cấu hình một IP mới.

Cách gửi bản tin email bằng API SendGrid
Trình đơn cài đặt cho địa chỉ IP

Cách cấp quyền cho người gửi email trong SendGrid

LƯU Ý:bạn có thể bỏ qua phần này nếu bạn đang sử dụng miền tùy chỉnh cho email của mình.

Để gửi email từ địa chỉ email cá nhân của bạn, bạn cần xác minh rằng địa chỉ email đó thuộc về bạn.

Trong menu bên trái, chọn "Cài đặt", sau đó chọn "Xác thực người gửi". Chọn "Xác minh một người gửi" để thực hiện quy trình thêm một địa chỉ email của bạn.

Cách gửi bản tin email bằng API SendGrid
Tùy chọn một người gửi

Cách xác thực miền tùy chỉnh của bạn trong SendGrid

LƯU Ý:bạn có thể bỏ qua phần này nếu bạn KHÔNG sử dụng miền tùy chỉnh cho email của mình.

Để gửi email từ miền thư tùy chỉnh của bạn, bạn sẽ cần xác thực miền đó với SendGrid. Để đến màn hình này, hãy chọn lại menu Cài đặt, sau đó chọn "Xác thực người gửi".

Cách gửi bản tin email bằng API SendGrid
Trình đơn cài đặt cho Xác thực người gửi

Sau đó, bạn sẽ thấy một màn hình có tùy chọn cho "Xác thực miền". Chọn tùy chọn "Xác thực miền của bạn" và SendGrid sẽ hướng dẫn bạn quy trình định cấu hình bản ghi DNS của bạn (với các hướng dẫn cụ thể dựa trên nhà cung cấp DNS của bạn).

Cách gửi bản tin email bằng API SendGrid
Trang cài đặt xác thực người gửi

Cách thiết lập Reverse DNS trong SendGrid

LƯU Ý:bạn có thể bỏ qua phần này nếu bạn không sử dụng miền tùy chỉnh cho email của mình.

Reverse DNS (Hệ thống tên miền) được các nhà cung cấp dịch vụ email sử dụng để tra cứu chủ sở hữu của một địa chỉ IP nhất định. Việc thiết lập này sẽ cho phép các nhà cung cấp dịch vụ email xác minh rằng địa chỉ IP mà bạn gửi email từ đó được kết nối với miền tùy chỉnh của bạn.

Trong cùng một màn hình Xác thực người gửi như trên, bạn sẽ thấy phần "Reverse DNS". Sẽ có một tùy chọn để định cấu hình DNS ngược cho từng IP chuyên dụng mà bạn có trên tài khoản của mình - như Xác thực miền, nền tảng của SendGrid sẽ hướng dẫn bạn cách thiết lập điều này.

Cách thiết lập xác thực email trong SendGrid

LƯU Ý:bạn có thể bỏ qua phần này nếu bạn không sử dụng miền tùy chỉnh cho email của mình.

Các nhà cung cấp email lớn (chẳng hạn như Gmail, Yahoo và Outlook) sử dụng một số phương pháp để xác thực người gửi email:SPF, DKIM và DMARC.

  • SPF (Khung chính sách người gửi) xác thực rằng địa chỉ IP gửi thư từ miền của bạn được phép làm như vậy.
  • DKIM (Thư được xác định DomainKeys) sử dụng chuỗi khóa công khai để xác thực rằng một email from địa chỉ chính xác và không bị giả mạo / làm sai lệch.
  • DMARC (Xác thực, báo cáo và tuân thủ tin nhắn dựa trên miền) là một tập hợp các hướng dẫn cho các nhà cung cấp dịch vụ email biết cách phản ứng khi email không xác thực được SPF hoặc DKIM.

Quy trình xác thực của SendGrid sẽ hướng dẫn bạn cách thiết lập SPF và DKIM như một phần của quy trình xác thực miền, nhưng bạn sẽ cần phải định cấu hình DMARC của mình theo cách thủ công.

Truy cập nhà cung cấp dịch vụ lưu trữ DNS của bạn và truy cập cài đặt quản lý DNS. Từ đó, thêm một TXT mới bản ghi có tên là _dmarc.yourdomain.com (thay thế yourdomain.com với miền tùy chỉnh của bạn).

Lưu ý rằng một số nhà cung cấp, chẳng hạn như GoDaddy, sẽ tự động nối miền của bạn vào bản ghi - trong trường hợp này, tên phải là _dmarc .

Giá trị của bản ghi này phải có cấu trúc tương tự như:

"v=DMARC1; p=none; pct=100; rua=mailto:dmarc@yourdomain.com"
  • v=DMARC cho biết phiên bản của quy tắc DMARC để sử dụng (hiện chỉ có Phiên bản 1).
  • p=none cho biết hành động mà nhà cung cấp email nên thực hiện khi email không DKIM hoặc SPF. Cài đặt này phải bắt đầu là none , để tránh ảnh hưởng đến khả năng gửi email của bạn. Khi bạn đã xác nhận rằng DKIM và SPF của mình được định cấu hình chính xác, bạn có thể cập nhật giá trị này thành quarantine để các nhà cung cấp tự động định tuyến các email bị lỗi đến thư mục spam hoặc reject yêu cầu nhà cung cấp từ chối / trả lại các email không thành công.
  • pct=100 cho biết tỷ lệ email không thành công mà hành động sẽ được áp dụng.
  • rua=mailto:dmarc@yourdomain.com là địa chỉ email để gửi các báo cáo tổng hợp. Các báo cáo này chứa thông tin về tất cả các email từ các IP của bạn do một nhà cung cấp nhất định nhận được. Thay thế dmarc@yourdomain.com bằng địa chỉ email bạn muốn nhận các báo cáo đó.

Cách tạo Mẫu động trong SendGrid

Công cụ chúng ta sẽ xây dựng hôm nay sử dụng tính năng mẫu động của SendGrid để đặt chủ đề và nội dung của email. Để thiết lập điều này, hãy chọn tùy chọn "API Email" trong menu điều hướng bên, sau đó chọn "Mẫu động".

Cách gửi bản tin email bằng API SendGrid
Trình đơn cài đặt cho Mẫu động

Bạn sẽ thấy màn hình có lời nhắc tạo mẫu động đầu tiên của mình. Chọn tùy chọn "Tạo Mẫu Động".

Đặt tên cho mẫu mới của bạn:"freeCodeCamp SendGrid Tutorial". SendGrid sẽ thêm mẫu này vào danh sách các mẫu có sẵn. Chọn mẫu để xem Template ID (hãy ghi nhớ điều này, vì chúng tôi sẽ cần nó cho công cụ sau này) và nhấp vào nút "Thêm phiên bản".

Cách gửi bản tin email bằng API SendGrid
Xem trước mẫu mới được thêm

Chọn "Mẫu trống" trên màn hình xuất hiện, sau đó chọn "Trình chỉnh sửa mã". Bây giờ bạn sẽ thấy chế độ xem trình chỉnh sửa. Trình soạn thảo của SendGrid sử dụng HTML để tạo nội dung email - tuy nhiên, khi chúng tôi xây dựng công cụ của mình, chúng tôi sẽ gửi phiên bản văn bản thuần túy.

Bây giờ, hãy thay thế nội dung của trình chỉnh sửa bằng mã sau:

<p>This is a test email used with the freeCodeCamp SendGrid tutorial</p>
<p>Unsubscribe: {{{unsubscribeId}}}</p>
Công cụ của chúng tôi sẽ gửi các email có văn bản rõ ràng, do đó, bản soạn thảo HTML bổ sung là không cần thiết.

Bạn sẽ nhận thấy rằng chúng tôi đã thêm {{{unsubscribeId}}} . Mẫu của SendGrid sử dụng Handlebars để thay thế động các giá trị - chúng tôi sẽ tận dụng tính năng này khi chúng tôi xây dựng công cụ.

Bây giờ hãy chọn tùy chọn cài đặt từ trên cùng bên trái - bạn có thể tùy ý đặt tên cho phiên bản mẫu của mình, nhưng trường "Chủ đề" là những gì chúng tôi muốn sửa đổi. Đặt giá trị này thành {{{subject}}} để tải động giá trị chủ đề từ công cụ của chúng tôi.

Để kiểm tra mẫu động, hãy chọn tùy chọn "Dữ liệu Kiểm tra" từ menu trên cùng. Chèn dữ liệu JSON này vào trình chỉnh sửa ở đó:

{
    "unsubscribeId": "1",
    "subject": "Testing emails!"
}
Hãy nhớ rằng JSON yêu cầu các khóa phải được đặt trong dấu ngoặc kép!

Bây giờ bạn sẽ thấy bản xem trước ở phía bên phải của màn hình phản ánh các giá trị này trong mẫu. Hãy nhớ nhấn Save để lưu các thay đổi của bạn!

Cách gửi bản tin email bằng API SendGrid
Màn hình trình chỉnh sửa và xem trước hiển thị tải động các giá trị mẫu

Cách tạo khóa API trong SendGrid

Bước cuối cùng trong việc định cấu hình tài khoản SendGrid của bạn là tạo khóa API để công cụ của chúng tôi sử dụng.

Nhấp vào mũi tên quay lại ở trên cùng bên trái để quay lại trang SendGrid chính. Sau đó chọn "Cài đặt" và "Khóa API". Chọn "Tạo khóa API" để tạo khóa mới. Bạn có thể tùy chọn cấp "Quyền truy cập đầy đủ" cho khóa của mình, nhưng với mục đích của hướng dẫn này, bạn sẽ chỉ cần quyền truy cập "Gửi thư".

Đảm bảo đặt tên mô tả cho khóa của bạn để bạn sẽ nhớ mục đích của nó nếu truy cập lại vào màn hình này. Khi bạn đã định cấu hình các quyền của mình, hãy chọn "Tạo và xem" để tạo khóa - lưu khóa này ở nơi an toàn vì bạn sẽ không thể xem lại .

Cách gửi bản tin email bằng API SendGrid
Tạo màn hình API với quyền Gửi thư được bật

Cách tạo Công cụ Email

Bây giờ là lúc viết mã để thực sự gửi một số email. Bạn có thể xem mã cho ứng dụng trực tiếp của chúng tôi, nhưng vì mục đích của hướng dẫn này, chúng tôi sẽ xây dựng một phiên bản rút gọn một chút để tập trung chủ yếu vào việc sử dụng API SendGrid.

Phần mềm Bắt buộc cho Tập lệnh Chiến dịch Email Tùy chỉnh

Bạn sẽ cần cài đặt các công cụ sau để làm việc với dự án này:

  • Node.js - phiên bản LTS được khuyến nghị
  • Một IDE, chẳng hạn như VSCode hoặc Atom

Bạn cũng có thể muốn git tùy ý để kiểm soát phiên bản.

Công cụ trực tiếp của chúng tôi sử dụng một cụm MongoDB Atlas, nhưng ví dụ hướng dẫn của chúng tôi sẽ không. Nếu bạn chưa quen với MongoDB, chương trình học của freeCodeCamp bao gồm một phần tuyệt vời về cách thiết lập và sử dụng MongoDB.

Cách Khởi tạo Dự án

Tạo một thư mục (thư mục) để làm việc trong dự án này. Sau đó, mở thư mục đó bằng trình chỉnh sửa và thiết bị đầu cuối bạn chọn.

Để bắt đầu, chúng ta sẽ cần thiết lập dự án này như một dự án Node. Cách nhanh nhất để làm như vậy là với npm init trong thiết bị đầu cuối của bạn. Phần này sẽ hướng dẫn bạn cách tạo package.json là tệp cốt lõi của một ứng dụng Node.

Các giá trị mặc định sẽ hoạt động tốt cho ứng dụng của chúng tôi, nhưng chúng tôi sẽ muốn sửa đổi scripts phần:

  "scripts": {
    "build": "tsc",
    "send": "node ./prod/send.js"
  },
npm init sẽ tạo một test script - điều này có thể bị xóa cho dự án của chúng tôi.

build script sẽ được sử dụng để biên dịch TypeScript của chúng tôi thành JavaScript và send script sẽ chạy ứng dụng của chúng tôi.

Tiếp theo chúng ta sẽ cài đặt và thiết lập TypeScript. Nếu bạn không quen thuộc với TypeScript, về cơ bản nó là một tập hợp siêu JavaScript với các định nghĩa kiểu mạnh hơn và kiểm tra lỗi thời gian biên dịch.

Để cài đặt TypeScript trên dự án của bạn, hãy chạy npm install --save-dev typescript trong thiết bị đầu cuối của bạn. (--save-dev cờ lưu nó dưới dạng phụ thuộc phát triển - TypeScript không bắt buộc trong thời gian chạy vì vậy có thể được dọn dẹp trong môi trường sản xuất).

TypeScript yêu cầu tệp cấu hình của riêng nó để thiết lập các quy tắc mà nó phải tuân theo khi tạo tệp JavaScript. Tạo một tệp trong thư mục gốc của dự án của bạn có tên là tsconfig.json và chèn phần sau:

{
    "compilerOptions": {
      "target": "es5",
      "module": "commonjs",
      "strict": true,
      "esModuleInterop": true,
      "skipLibCheck": true,
      "forceConsistentCasingInFileNames": true,
      "outDir": "./prod",
      "rootDir": "./src"
    }
  }
Nếu bạn xem kho hướng dẫn, bạn sẽ thấy thêm excludes tài sản. Giá trị đó dành riêng cho cấu trúc tệp hướng dẫn và bạn sẽ không cần nó.

Để ngắn gọn, chúng tôi sẽ không đi sâu vào các cài đặt cấu hình này. Nếu bạn muốn biết thêm thông tin, TypeScript có tài liệu rất chuyên sâu.

Nếu bạn đang sử dụng git để kiểm soát phiên bản và tải nó lên một kho lưu trữ (chẳng hạn như GitHub), bạn sẽ muốn tạo một .gitignore tệp trong thư mục gốc của dự án của bạn. Tệp này phải chứa:

/node_modules/
.env
/prod/
  • /node_modules/ sẽ bỏ qua các gói đã cài đặt. Đây được coi là phương pháp hay nhất khi làm việc với kiểm soát phiên bản.
  • .env sẽ bỏ qua tệp biến môi trường của chúng tôi. Điều này rất quan trọng vì bạn không bao giờ muốn cam kết những bí mật của bạn vào một kho lưu trữ.
  • /prod/ sẽ bỏ qua các tệp JavaScript đã biên dịch của chúng tôi. Chúng tôi cũng sẽ sử dụng thư mục này cho danh sách email của mình, vì vậy, điều quan trọng là tránh vô tình sử dụng thông tin nhận dạng riêng tư đó.

Tạo .env tệp trong thư mục dự án gốc của bạn. Chúng tôi sẽ tải các biến môi trường sau thông qua tệp này:

SENDGRID_API_KEY=
SENDGRID_FROM=
SENDGRID_TEMPLATE_ID=

MAIL_SUBJECT=
Khi bạn điền các giá trị, hãy nhớ đặt chúng trong dấu ngoặc kép. Ngoài ra, không có khoảng trắng nào xung quanh = ký tên!
  • SENDGRID_API_KEY phải là khóa API mà bạn đã tạo ở các bước trước.
  • SENDGRID_FROM phải là địa chỉ email của bạn (đây là địa chỉ được sử dụng cho from trường).
  • SENDGRID_TEMPLATE_ID phải là id chuỗi cho mẫu động bạn đã tạo trước đó.
  • MAIL_SUBJECT sẽ là dòng chủ đề cho các email bạn gửi. Bây giờ, hãy đặt đây là "Email hướng dẫn của fCC".

Cuối cùng, tạo src trong thư mục dự án gốc của bạn và tạo một send.ts tệp trong thư mục đó.

Cách cài đặt phần phụ thuộc của bạn

Trước tiên, chúng ta cần cài đặt sendgrid Gói Node.js. Gói này đóng vai trò như một trình bao bọc cho API SendGrid và sẽ hợp lý hóa quy trình của chúng tôi để thực hiện các lệnh gọi API để gửi email. Chạy npm install @sendgrid/mail để cài đặt gói này.

Sau đó, chúng ta cần một vài phụ thuộc phát triển. Chạy npm install --save-dev dotenv @types/node .

  • dotenv sẽ cho phép chúng tôi tải các biến môi trường từ .env tệp cục bộ.
  • @types/node cung cấp các định nghĩa kiểu cho Node.js - TypeScript dựa vào các định nghĩa này để hiểu cấu trúc của các phương thức và chức năng tích hợp sẵn.

Cách viết logic

Bây giờ chúng tôi sẽ làm việc trong /src/send.ts của chúng tôi tệp - đây là nơi chúng tôi đang xây dựng phần lớn logic ứng dụng của mình. Chúng tôi sẽ bắt đầu bằng cách nhập các giá trị bắt buộc từ các gói của chúng tôi.

Đầu tiên, chúng tôi muốn tải dotenv đóng gói và phân tích cú pháp các biến môi trường của chúng tôi.

import dotenv from "dotenv";
dotenv.config();
dotenv chỉ cần thiết cho phát triển cục bộ - hầu hết các máy chủ trực tuyến như Heroku và Repl.it có thể xử lý các biến môi trường một cách nguyên bản

dotenv.config() cuộc gọi đọc .env của chúng tôi tệp và tải các giá trị vào process.env Đối tượng nút.

Tiếp theo, chúng tôi nhập các mô-đun cần thiết từ gói SendGrid:

import sgMail, { MailDataRequired } from "@sendgrid/mail";
TypeScript có thể tự động nhập mọi thứ, nhưng bạn nên thực hành nhập thủ công.

sgMail là trình bao bọc API chính và MailDataRequired là định nghĩa kiểu mà chúng tôi sẽ cần.

Cuối cùng, chúng tôi nhập một số tính năng Node tích hợp sẵn để xử lý các tệp của chúng tôi:

import path from "path";
import { createWriteStream, readFile } from "fs";
{cú pháp} dùng để nhập các mô-đun cụ thể từ gói.
  • path sẽ được sử dụng để định vị các tệp danh sách email của chúng tôi bằng các đường dẫn tương đối
  • fs sẽ được sử dụng để đọc và ghi vào các tệp đó

Đã đến lúc bắt đầu xây dựng logic! Ứng dụng của chúng tôi dựa trên một số giá trị cần thiết được đặt trong .env , vì vậy chúng ta cần bắt đầu bằng cách xác thực rằng các biến đó được đặt chính xác. Nếu thiếu bất kỳ nội dung nào, chúng tôi muốn ứng dụng của mình thoát sớm để tránh gặp lỗi khi chúng tôi gửi email.

// Here we check for a valid API key
const apiKey = process.env.SENDGRID_API_KEY;
if (!apiKey) {
  console.error("Missing SendGrid Key");
  process.exit(1);
}

// Here we check for a valid from address
const fromAddress = process.env.SENDGRID_FROM;
if (!fromAddress) {
  console.error("Missing sender email address!");
  process.exit(1);
}

// Here we check for a dynamic template ID
const sgTemplate = process.env.SENDGRID_TEMPLATE_ID;
if (!sgTemplate) {
  console.error("Missing SendGrid Template ID");
  process.exit(1);
}

// Here we check for the mail subject, but if it is missing
// we do not need to exit. Instead we use a fallback value.
const subjectValue = process.env.MAIL_SUBJECT || "Fallback value - check your env!";
|| cú pháp cho mã rằng nếu process.env.MAIL_SUBJECT không xác định hoặc sai, hãy sử dụng chuỗi thay thế.

process.exit(1) cuộc gọi bạn thấy trong mỗi lần kiểm tra điều kiện yêu cầu Node kết thúc quá trình (ứng dụng của chúng tôi) với mã thoát là 1 . Điều này cho thấy rằng ứng dụng của chúng tôi bị lỗi do một trong những lần kiểm tra này không thành công.

SendGrid yêu cầu chúng tôi đặt khóa API. Bên dưới logic biến môi trường của bạn, hãy thêm lệnh gọi hàm để đặt khóa.

// Here we set the SendGrid API key
sgMail.setApiKey(apiKey);

Trước khi tiếp tục, hãy tiếp tục và chạy npm run build trong thiết bị đầu cuối của bạn - điều này sẽ tạo ra một prod thư mục chứa JavaScript đã biên dịch của chúng tôi. Bây giờ bạn sẽ thấy cấu trúc tệp sau:

Cách gửi bản tin email bằng API SendGrid
Cây tệp cho điểm này trong hướng dẫn

Tại thời điểm này, nếu bạn đang sử dụng git bạn muốn rất chắc chắn rằng prod thư mục sẽ không được cam kết với kho lưu trữ của bạn.

Trong prod thư mục, tạo một validEmails.csv tập tin. Ứng dụng của chúng tôi sẽ sử dụng tệp này để đọc danh sách email. Khởi tạo tệp với nội dung sau (thay thế your@email.com với địa chỉ email thực của bạn):

email,unsubscribeId
your@email.com,1
iama@fake.email,2
.csv tệp không có khoảng trắng xung quanh dấu phẩy.

Bây giờ chúng ta có thể viết mã để phân tích cú pháp này thành một danh sách email! Trong src/send.ts của bạn tệp, thêm mã này:

// Here we concatenate our file path for the valid email file
const filePath = path.join(__dirname + "/../validEmails.csv");

// This is where we start reading the file!
readFile(filePath, "utf8", (err, data) => {
    if (err) {
        console.error(err);
        return;
    }
    console.log(data)
});
Chúng tôi đang sử dụng cú pháp hàm mũi tên ES6 trong suốt quá trình này. Bạn có thể sử dụng function khai báo thay thế, nếu bạn thích.

Bây giờ nếu bạn chạy npm run buildnpm run send bạn sẽ thấy nội dung của validEmail.csv của chúng tôi tập tin trong thiết bị đầu cuối. Nếu bạn muốn, bạn có thể xem tiến trình hiện tại của chúng tôi cho đến thời điểm này.

Tuyệt quá! Bây giờ chúng ta cần phân tích chuỗi đó thành một mảng các đối tượng để chúng ta có thể lặp qua nó và xây dựng các thông điệp email của chúng ta. Cập nhật chức năng gọi lại của chúng tôi:

// This is where we start reading the file!
readFile(filePath, "utf8", (err, data) => {
    if (err) {
        console.error(err);
        return;
    }
    
  // Here we parse the data into an object array
  const emailList = data
    .split("\n")
    .slice(1)
    .map((el) => {
      const [email, unsubscribeId] = el.split(",");
      return { email, unsubscribeId };
    });
});
[email, unsubscribeId] áp dụng cấu trúc hủy để gán các giá trị của mảng tách cho hai biến đó.
  • .split("\n") chia chuỗi theo ngắt dòng. LƯU Ý :Nếu bạn đang sử dụng Windows, bạn có thể cần thay đổi cài đặt cuối dòng cho validEmails.csv của mình từ CRLF thành LF (Windows chèn thêm các ký tự ngắt dòng sẽ ảnh hưởng đến việc xử lý dữ liệu của chúng tôi)
  • .slice(1) loại bỏ phần tử đầu tiên của mảng đó (email,unsubscribeId của chúng tôi dòng).
  • map của chúng tôi hàm sẽ chuyển đổi từng email,unsubscribeId chuỗi thành một {email, unsubscribeId} đối tượng.

Kết quả cuối cùng của hàm phân tích cú pháp này sẽ là một mảng các đối tượng có emailunsubscribeId thuộc tính - làm việc với chuỗi trơn tru hơn nhiều.

Cách gửi bản tin email bằng API SendGrid
Kết quả mẫu từ hàm phân tích cú pháp

Bây giờ là lúc để gửi một số email. Bên dưới chức năng phân tích cú pháp của bạn (nhưng vẫn nằm trong readFile callback) thêm cấu trúc cho phương thức lặp của chúng tôi. Bởi vì chúng tôi muốn truy cập từng giá trị trong mảng, chúng tôi sẽ sử dụng .forEach cách tiếp cận.

  // Here we iterate through the emailList array
  emailList.forEach((user) => {});
user tham số sẽ là {email, unsubscribeId} sự vật. Chúng tôi đã gọi nó là user vì nó đại diện cho một đối tượng dữ liệu người dùng freeCodeCamp trong ứng dụng đầy đủ.

Trong lệnh gọi lại cho .forEach , chúng ta có thể xây dựng đối tượng thông báo mà API SendGrid mong đợi.

  // Here we iterate through the emailList array
  emailList.forEach((user) => {

    // This is the message object SendGrid needs
    const message: MailDataRequired = {
        to: user.email,
        from: fromAddress,
        subject: subjectValue,
        text: "This goes away!",
        templateId: sgTemplate,
        dynamicTemplateData: {
            subject: subjectValue,
            unsubscribeId: user.unsubscribeId
        }
    }
    
  });

Trước khi tiếp tục, chúng ta hãy xem xét kỹ hơn đối tượng tin nhắn này. MailDataRequired chúng tôi đã nhập trước đó được sử dụng làm định nghĩa kiểu ở đây, vì vậy TypeScript có thể cảnh báo cho chúng tôi nếu chúng tôi tình cờ bỏ lỡ một thuộc tính bắt buộc. Rất may, chúng tôi có tất cả các thuộc tính cần thiết. Nhưng chúng có nghĩa là gì?

  • to: Địa chỉ email để gửi tin nhắn. Đây sẽ là email từ mỗi dòng trong validEmails.csv của chúng tôi tệp
  • from: Địa chỉ email để gửi tin nhắn. Điều này được đặt trong .env của chúng tôi sớm hơn (nó phải là của bạn địa chỉ email).
  • subject: Trường này không bắt buộc nhưng cung cấp cho chúng tôi giá trị dự phòng trong trường hợp mẫu động không phân tích cú pháp chính xác chủ đề của chúng tôi.
  • text: Giá trị văn bản này được ghi đè bởi mẫu. Tuy nhiên, điều quan trọng vẫn là sử dụng. SendGrid có thể gửi email dưới dạng plaintext hoặc html - bằng cách sử dụng text thay vì html thuộc tính này, chúng tôi đảm bảo mẫu của chúng tôi được gửi dưới dạng plaintext . Các nhà cung cấp email có nhiều khả năng hơn để gắn cờ các thư HTML là spam, vì vậy điều này giúp tăng tỷ lệ phân phối của chúng tôi.
  • templateId: Đây là ID cho mẫu động mà SendGrid sẽ sử dụng trong email.
  • dynamicTemplateData: Đây là những giá trị tương ứng với chuỗi Handlebars mà chúng tôi đã đặt trong mẫu động trước đó.

Tuyệt quá! Bước tiếp theo của chúng tôi là lấy thông điệp đã xây dựng này và gửi nó. Bên dưới đối tượng thông báo (nhưng vẫn nằm trong .forEach gọi lại), hãy thêm cuộc gọi gửi của chúng tôi:

    // Here we send the message we just constructed!
    sgMail.send(message);

Thao tác này sẽ gửi thông báo đến từng email trong validEmails.csv của chúng tôi . Thật không may, mã của chúng tôi sẽ chạy âm thầm và chúng tôi sẽ không biết liệu mỗi lần gửi có thành công hay không. Hãy thêm một số xử lý lỗi.

.send() cuộc gọi trả về một Lời hứa, vì vậy chúng ta có thể sử dụng .then().catch() để xử lý việc trả lại.

    // Here we send the message we just constructed!
    sgMail.send(message)
        .then(() => {
            // Here we log successful send requests
            console.info(`Message send success: ${user.email}`)
        }).catch((err) => {
            // Here we log errored send requests
            console.error(err);
            console.error(`Message send failed: ${user.email}`)
        });
Bạn cũng có thể sử dụng async / await, nhưng đây là trường hợp .then.catch rõ ràng hơn

Bây giờ nếu bạn chạy npm run buildnpm run send bạn sẽ thấy một email đẹp trong hộp thư đến của mình!

Tại thời điểm này, bạn đã có một ứng dụng gửi email chức năng. Xin chúc mừng! Bạn có thể xem tiến trình của chúng tôi cho đến thời điểm này nếu bạn muốn.

Đọc tiếp để biết cách xử lý các email bị trả lại và logic bổ sung cho các lỗi gửi, đó là những gì chúng ta sẽ thảo luận tiếp theo.

Cách xử lý email bị trả lại trong SendGrid

Bạn có thể nhận thấy rằng iama@fake.email rất nhiều không phải là một địa chỉ email thực. SendGrid sẽ tạo báo cáo bị trả lại hàng ngày cho hoạt động của bạn vào ngày hôm trước.

Mọi email bị trả lại đều làm tổn hại đến danh tiếng SendGrid của bạn và có thể dẫn đến việc các nhà cung cấp dịch vụ email đánh dấu thư của bạn là thư rác. Vì vậy, chúng tôi cần thêm logic để ngăn việc gửi đến các địa chỉ bị trả lại đã biết.

Bắt đầu bằng cách tạo bouncedEmails.csv tệp trong prod của bạn thư mục (nó phải ở bên cạnh validEmails.csv của bạn ). Chúng tôi không cần unsubscribeId ở đây, vì vậy hãy khởi tạo nó bằng:

email
iama@fake.email
Chúng tôi đã thêm email giả mạo cho mục đích trình diễn

Bây giờ quay lại send.ts của chúng tôi tập tin. Trên dòng 38, ngay bên dưới filePath hiện có của chúng tôi khai báo, định cấu hình đường dẫn cho bouncedEmails.csv mới tệp.

// Here we concatenate our file paths for the CSV files
const filePath = path.join(__dirname + "/validEmails.csv");
const bouncePath = path.join(__dirname + "/bouncedEmails.csv");
__dirname đề cập đến thư mục hiện tại của tệp này (trong trường hợp của chúng tôi là send.ts tệp).

Tuyệt quá! Bây giờ chúng ta cần đọc tệp đó. Ngay bên dưới các khai báo đường dẫn tệp này (trước readFile hiện có của chúng tôi gọi), thêm logic để đọc các tệp bị trả lại.

// Read through the bounce list, parse into array
readFile(bouncePath, "utf8", (err, data) => {
  if (err) {
    console.error(err);
    process.exit(1);
  }
  bounceList = data.split("\n").slice(1);

readFile là không đồng bộ - vì vậy chúng tôi cần bao bọc hàm gọi lại xung quanh tất cả logic gửi hiện có của chúng tôi . Đảm bảo rằng }) đóng của bạn cho lệnh gọi lại này được chuyển đến cuối tệp của chúng tôi.

Chúng tôi đọc bouncedEmails.csv , hãy tách nó trên dòng mới (hãy nhớ rằng bạn sẽ cần đảm bảo phần cuối dòng của mình là LF ) và xóa email hàng. Cuối cùng, chúng tôi tiếp tục với logic gửi hiện có của mình.

Quay lại logic gửi của chúng tôi. Trong .forEach của chúng tôi , thêm logic để bỏ qua các email bị chặn (chúng tôi sẽ thêm điều này trước khi xây dựng đối tượng message để tránh tạo ra các biến không cần thiết).

  // Here we iterate through the emailList array
  emailList.forEach((user) => {
    // Here we check if the email has been bounced
    if (bounceList.length && bounceList.includes(user.email)) {
        console.info(`Message send skipped: ${user.email}`);
        return;
    }
    
Nếu bounceList.csv của chúng tôi tệp trống, đang gọi includes sẽ ném ra một lỗi. Vì vậy, chúng tôi kiểm tra .length giá trị đầu tiên.

Bằng cách tận dụng return sớm tuyên bố, chúng tôi kết thúc .forEach cụ thể đó lặp lại khi bounceList bao gồm email đó. Điều này ngăn chúng tôi cố gắng gửi đến các địa chỉ email đã bị trả lại trước đó. Bây giờ nếu bạn chạy npm run buildnpm run start , bạn sẽ thấy đầu ra này trong thiết bị đầu cuối của mình:

Cách gửi bản tin email bằng API SendGrid
Đầu ra bảng điều khiển mẫu cho email bị bỏ qua và email thành công

Xem tiến trình của chúng tôi cho đến thời điểm này.

Cách chụp các email không thành công trong SendGrid

Hiện tại ứng dụng của chúng tôi sẽ báo lỗi nếu không gửi được email. Điều này có thể hoạt động đối với các trường hợp sử dụng nhỏ, nhưng khi mở rộng ứng dụng, bạn sẽ ngày càng khó xác định những lỗi đó và cố gắng gửi lại.

Nhưng thay vào đó, chúng tôi có thể làm cho ứng dụng của mình lưu những email đó vào một tệp mới.

Tạo failedEmails.csv tệp trong prod của bạn thư mục. Tệp này có thể trống. Chúng tôi sẽ viết mã để thêm hàng tiêu đề.

Quay lại send.ts của chúng tôi tệp, hãy chuyển đến phần khai báo đường dẫn của chúng tôi trên dòng 38. Hãy thêm một phần khai báo nữa cho failedEmails.csv mới của chúng tôi :

// Here we concatenate our file paths for the CSV files
const filePath = path.join(__dirname + "/validEmails.csv");
const bouncePath = path.join(__dirname + "/bouncedEmails.csv");
const failedPath = path.join(__dirname + "/failedEmails.csv");

Không giống như các đường dẫn khác của chúng tôi, đường dẫn này sẽ được sử dụng cho write hoạt động. Bởi vì chúng tôi muốn viết liên tục khi email được xử lý, chúng tôi cần tạo một luồng để làm như vậy. Ngay bên dưới các khai báo đường dẫn này, hãy tạo luồng đó và thêm hàng tiêu đề ban đầu của chúng ta.

// Here we create our write stream for failed emails
const failedStream = createWriteStream(failedPath);

// Here we add the header row
failedStream.write("email,unsubscribeId\n")

Đã đến lúc cải thiện logic xử lý lỗi của chúng tôi để kết hợp luồng mới này. Chúng tôi cần thêm một write khác thao tác xử lý lỗi của chúng tôi trong send cuộc gọi.

    // Here we send the message we just constructed!
    sgMail
      .send(message)
      .then(() => {
        // Here we log successful send requests
        console.info(`Message send success: ${user.email}`);
      })
      .catch((err) => {
        // Here we log errored send requests
        console.error(err);
        console.error(`Message send failed: ${user.email}`);
        // And here we add that email to the failedEmails.csv
        failedStream.write(`${user.email},${user.unsubscribeId}\n`)
      });
Chúng tôi muốn duy trì các câu lệnh bảng điều khiển để đảm bảo chúng tôi thấy phản hồi trong khi tập lệnh chạy.

Điều này sẽ viết emailunsubscribeId sang failedEmails.csv mới của chúng tôi ở định dạng thích hợp - cho phép chúng tôi sao chép dữ liệu đó vào validEmails.csv để thực hiện một lần gửi khác.

Xin chúc mừng! Bây giờ bạn đã xây dựng một công cụ thành công và đầy đủ chức năng để gửi các vụ nổ email. Bạn có thể xem mã hoàn thành nếu bạn muốn xác nhận công việc của mình. Nhưng hãy tiếp tục đọc để biết một vài tính năng tùy chọn, "rất vui khi có".

Các tính năng tùy chọn cho Công cụ Email của bạn

Vì công cụ của chúng tôi dựa trên CLI (có nghĩa là nó được sử dụng trong giao diện dòng lệnh hoặc thiết bị đầu cuối) nên không có nhiều phản hồi của người dùng. Chúng tôi có thể tận dụng một số chức năng bảng điều khiển bổ sung để cung cấp thêm thông tin về tiến trình của tập lệnh.

Hãy bắt đầu bằng cách thêm một số "trạm kiểm soát". Trước khi xác thực biến môi trường của chúng ta, hãy in một thông báo rằng tập lệnh đã bắt đầu và đang kiểm tra các biến:

console.info('Script started. Validating environment variables...')
console.info cho biết đây là một thông báo cung cấp thông tin

Sau đó, sau khi xác thực, chúng tôi có thể in một thông báo thành công.

// Here we set the SendGrid API key
sgMail.setApiKey(apiKey);

console.info('Variables confirmed!')

Trong chức năng đọc tệp bị trả lại của chúng tôi, chúng tôi có thể thêm một số thông báo để bắt đầu, thất bại và thành công.

console.info('Reading bounced email list...')

// Read through the bounce list, parse into array
readFile(bouncePath, "utf8", (err, data) => {
  if (err) {
    console.error(err);
    console.error('Failed to read bounced emails!')
    process.exit(1);
  }
  bounceList = data.split("\n").slice(1);

console.info('Bounced emails read!')

Và tương tự đối với danh sách email hợp lệ của chúng tôi:

console.info('Reading send list...')
// This is where we start reading the file!
readFile(filePath, "utf8", (err, data) => {
  if (err) {
    console.error(err);
    console.error('Failed to read send list!')
    return;
  }

Bây giờ, sẽ rất tuyệt nếu có một bản in tin nhắn khi hoạt động hoàn tất. Tuy nhiên, nếu chúng ta thêm console.info sau .forEach của chúng tôi vòng lặp, nó sẽ thực sự in trước khi email đã gửi xong!

Điều này là do .send phương thức tạo một cuộc gọi mạng và trả về một Lời hứa và Lời hứa đó có thể chưa được giải quyết / từ chối trước khi quá trình lặp lại của chúng ta kết thúc.

Vì vậy, thay vào đó, chúng ta có thể xây dựng một bộ đếm để theo dõi số lượng email chúng tôi đã gửi so với tổng số email. Ngay trước .forEach của chúng tôi lặp lại, thêm các biến sau:

    // Here we create variables for counting
    const emailTotal = emailList.length;
    let emailCount = 0;
Bằng cách gán .length cho một biến, chúng tôi tránh phải đọc nó trên mỗi lần lặp.

Chúng tôi muốn đếm các email bị trả lại là đã được xử lý, ngay cả khi chúng tôi đang bỏ qua chúng.

  // Here we iterate through the emailList array
  emailList.forEach((user) => {
    // Here we check if the email has been bounced
    if (bounceList.includes(user.email)) {
      console.info(`Message send skipped: ${user.email}`);
      emailCount++;
      if (emailCount === emailTotal) {
        console.info(
          `Sending complete! Sent ${emailTotal} emails. Have a nice day!`
        );
        return;
      }
    }

Cuối cùng chúng ta cần thêm logic để xem email chúng ta đã gửi có phải là email cuối cùng hay không. Logic này áp dụng cho thành công của chúng tôi và các trình xử lý lỗi cho cuộc gọi gửi:

    // Here we send the message we just constructed!
    sgMail
      .send(message)
      .then(() => {
        // Here we log successful send requests
        console.info(`Message send success: ${user.email}`);
        // Here we handle the email counts
        emailCount++;
        if (emailCount === emailTotal) {
          console.info(
            `Sending complete! Sent ${emailTotal} emails. Have a nice day!`
          );
        }
      })
      .catch((err) => {
        // Here we log errored send requests
        console.error(err);
        console.error(`Message send failed: ${user.email}`);
        // And here we add that email to the failedEmails.csv
        failedStream.write(`${user.email},${user.unsubscribeId}\n`);
        // Here we handle the email counts
        emailCount++;
        if (emailCount === emailTotal) {
          console.info(
            `Sending complete! Sent ${emailTotal} emails. Have a nice day!`
          );
        }
      });

Và với điều đó, ứng dụng của chúng tôi đã hoàn chỉnh! Nếu bạn chạy npm run buildnpm run send tập lệnh, bạn sẽ thấy đầu ra này trong thiết bị đầu cuối của mình:

Cách gửi bản tin email bằng API SendGrid
Đầu ra bảng điều khiển mẫu cho ứng dụng đã hoàn thành.

Và bạn hẳn đã nhận được một vài email giống như sau:

Cách gửi bản tin email bằng API SendGrid
Hình ảnh mẫu của kết quả email kiểm tra

Bạn có thể xem mã cuối cùng của chúng tôi tại đây hoặc bạn có thể xem phiên bản mở rộng được xây dựng cho freeCodeCamp.