Computer >> คอมพิวเตอร์ >  >> ซอฟต์แวร์ >> จดหมาย

วิธีส่งจดหมายข่าวทางอีเมลด้วย SendGrid API

เป็นเวลาหลายปีที่ Quincy Larson ส่งจดหมายข่าวทางอีเมลรายสัปดาห์ผ่านแพลตฟอร์ม Mail for Good ของ freeCodeCamp ซึ่งขับเคลื่อนโดย Amazon SES

เขาเพิ่งย้ายกระบวนการนี้ไปยัง SendGrid ในบทความนี้ ผมจะแสดงให้คุณเห็นถึงวิธีการสร้างเครื่องมือเพื่อให้บรรลุสิ่งนี้

วิธีตั้งค่าบัญชี SendGrid

ขั้นตอนแรกคือการลงทะเบียน SendGrid และตั้งค่าบัญชีของคุณ สำหรับจุดประสงค์ของบทช่วยสอนนี้ ระดับฟรีควรเพียงพอ

เมื่อคุณขยายขนาดแอปพลิเคชัน คุณอาจต้องเพิ่มขีดจำกัดอีเมลที่ใช้ได้ผ่านแพลตฟอร์ม

วิธีตั้งค่าที่อยู่ IP เฉพาะบน SendGrid

ตามค่าเริ่มต้น SendGrid จะใช้ที่อยู่ IP ที่ใช้ร่วมกันสำหรับการส่งอีเมล นี่อาจเป็นที่ยอมรับสำหรับแอปพลิเคชันอีเมลขนาดเล็ก แต่เมื่อคุณเพิ่มอัตราการส่ง คุณจะต้องตั้งค่าที่อยู่ IP เฉพาะ

นี่เป็นความคิดที่ดี เนื่องจาก "ชื่อเสียงของผู้ส่ง" ของคุณ (เมตริกที่ SendGrid ใช้ในการประเมินสถานะของคุณกับผู้ให้บริการอีเมล) จะไม่ได้รับผลกระทบในทางลบจากการกระทำของผู้ใช้รายอื่นที่ใช้ IP เดียวกัน

ในการตั้งค่า IP เฉพาะของคุณเอง ให้เลือกตัวเลือก "การตั้งค่า" จากเมนูการนำทางด้านข้าง จากนั้นเลือก "ที่อยู่ IP" อย่างไรก็ตาม โปรดทราบว่าตัวเลือกนี้ไม่มีให้บริการในระดับฟรี

คุณอาจมีที่อยู่ IP เฉพาะที่ตั้งค่าไว้แล้ว ทั้งนี้ขึ้นอยู่กับแผนการชำระเงินของคุณ หากคุณไม่มีหรือเลือกที่จะเพิ่ม คุณสามารถเลือกปุ่ม "เพิ่มที่อยู่ IP" เพื่อกำหนดค่า IP ใหม่ได้

วิธีส่งจดหมายข่าวทางอีเมลด้วย SendGrid API
การตั้งค่าเมนูสำหรับที่อยู่ IP

วิธีการอนุญาตผู้ส่งอีเมลใน SendGrid

หมายเหตุ:คุณสามารถข้ามส่วนนี้ได้หากคุณใช้โดเมนที่กำหนดเองสำหรับอีเมลของคุณ

ในการส่งอีเมลจากที่อยู่อีเมลส่วนตัวของคุณ คุณจะต้องยืนยันว่าที่อยู่อีเมลนั้นเป็นของคุณ

ในเมนูด้านซ้าย เลือก "การตั้งค่า" จากนั้นเลือก "การตรวจสอบผู้ส่ง" เลือก "ยืนยันผู้ส่งรายเดียว" เพื่ออธิบายขั้นตอนการเพิ่มที่อยู่อีเมลของคุณ

วิธีส่งจดหมายข่าวทางอีเมลด้วย SendGrid API
ตัวเลือกผู้ส่งเดี่ยว

วิธีการตรวจสอบโดเมนที่กำหนดเองของคุณใน SendGrid

หมายเหตุ:คุณสามารถข้ามส่วนนี้ได้หากคุณไม่ได้ใช้โดเมนที่กำหนดเองสำหรับอีเมลของคุณ

ในการส่งอีเมลจากโดเมนอีเมลที่กำหนดเอง คุณจะต้องตรวจสอบสิทธิ์โดเมนนั้นด้วย SendGrid หากต้องการไปที่หน้าจอนี้ ให้เลือกเมนูการตั้งค่าอีกครั้ง จากนั้นเลือก "การตรวจสอบผู้ส่ง"

วิธีส่งจดหมายข่าวทางอีเมลด้วย SendGrid API
การตั้งค่าเมนูสำหรับการตรวจสอบสิทธิ์ผู้ส่ง

จากนั้นคุณควรเห็นหน้าจอที่มีตัวเลือกสำหรับ "Domain Authentication" เลือกตัวเลือก "รับรองความถูกต้องโดเมนของคุณ" แล้ว SendGrid จะแนะนำขั้นตอนการกำหนดค่าระเบียน DNS ของคุณ (พร้อมคำแนะนำเฉพาะตามผู้ให้บริการ DNS ของคุณ)

วิธีส่งจดหมายข่าวทางอีเมลด้วย SendGrid API
หน้าการตั้งค่าการตรวจสอบสิทธิ์ผู้ส่ง

วิธีการตั้งค่า Reverse DNS ใน SendGrid

หมายเหตุ:คุณสามารถข้ามส่วนนี้ได้หากคุณไม่ได้ใช้โดเมนที่กำหนดเองสำหรับอีเมลของคุณ

Reverse DNS (Domain Name System) ถูกใช้โดยผู้ให้บริการอีเมลเพื่อค้นหาเจ้าของที่อยู่ IP ที่ระบุ การตั้งค่านี้จะช่วยให้ผู้ให้บริการอีเมลสามารถตรวจสอบว่าที่อยู่ IP ที่คุณส่งอีเมลนั้นเชื่อมต่อกับโดเมนที่คุณกำหนดเอง

ในหน้าจอการตรวจสอบผู้ส่งเดียวกันกับด้านบน คุณจะเห็นส่วน "Reverse DNS" จะมีตัวเลือกในการกำหนดค่า DNS แบบย้อนกลับสำหรับ IP เฉพาะแต่ละรายการที่คุณมีในบัญชีของคุณ เช่น การตรวจสอบโดเมน แพลตฟอร์มของ SendGrid จะแนะนำคุณตลอดการตั้งค่า

วิธีตั้งค่าการตรวจสอบสิทธิ์อีเมลใน SendGrid

หมายเหตุ:คุณสามารถข้ามส่วนนี้ได้หากคุณไม่ได้ใช้โดเมนที่กำหนดเองสำหรับอีเมลของคุณ

ผู้ให้บริการอีเมลรายใหญ่ (เช่น Gmail, Yahoo และ Outlook) ใช้หลายวิธีในการตรวจสอบสิทธิ์ผู้ส่งอีเมล:SPF, DKIM และ DMARC

  • SPF (กรอบนโยบายผู้ส่ง) ตรวจสอบว่าที่อยู่ IP ที่ส่งอีเมลจากโดเมนของคุณได้รับอนุญาตให้ทำเช่นนั้น
  • DKIM (DomainKeys Identified Mail) ใช้สตริงคีย์สาธารณะเพื่อตรวจสอบว่าอีเมล from ที่อยู่ถูกต้องและไม่ปลอมแปลง/ปลอมแปลง
  • DMARC (Domain-based Message Authentication, Reporting and Conformance) คือชุดคำสั่งที่บอกผู้ให้บริการอีเมลถึงวิธีตอบสนองเมื่ออีเมลไม่ผ่านการตรวจสอบ SPF หรือ DKIM

ขั้นตอนการตรวจสอบสิทธิ์ของ SendGrid จะแนะนำคุณตลอดการตั้งค่า SPF และ DKIM โดยเป็นส่วนหนึ่งของกระบวนการตรวจสอบสิทธิ์โดเมน แต่คุณจะต้องกำหนดค่า DMARC ด้วยตนเอง

ไปที่ผู้ให้บริการโฮสต์ DNS ของคุณและเข้าถึงการตั้งค่าการจัดการ DNS จากนั้นเพิ่ม TXT . ใหม่ บันทึกชื่อ _dmarc.yourdomain.com (แทนที่ yourdomain.com ด้วยโดเมนที่คุณกำหนดเอง)

โปรดทราบว่าผู้ให้บริการบางราย เช่น GoDaddy จะเพิ่มโดเมนของคุณต่อท้ายระเบียนโดยอัตโนมัติ ในกรณีนี้ ชื่อควรเป็น _dmarc .

ค่า ของบันทึกนี้ควรมีโครงสร้างคล้ายกับ:

"v=DMARC1; p=none; pct=100; rua=mailto:dmarc@yourdomain.com"
  • v=DMARC ระบุเวอร์ชันของกฎ DMARC ที่จะใช้ (ปัจจุบันมีเฉพาะเวอร์ชัน 1 เท่านั้น)
  • p=none ระบุการดำเนินการที่ผู้ให้บริการอีเมลควรทำเมื่ออีเมลล้มเหลวใน DKIM หรือ SPF การตั้งค่านี้ควรเริ่มต้นเป็น none เพื่อหลีกเลี่ยงผลกระทบต่อการส่งอีเมลของคุณ เมื่อคุณยืนยันว่า DKIM และ SPF ได้รับการกำหนดค่าอย่างถูกต้องแล้ว คุณสามารถอัปเดตค่านี้เป็น quarantine เพื่อให้ผู้ให้บริการกำหนดเส้นทางอีเมลที่ล้มเหลวไปยังโฟลเดอร์สแปมโดยอัตโนมัติ หรือ reject เพื่อให้ผู้ให้บริการปฏิเสธ/ตีกลับอีเมลที่ล้มเหลว
  • pct=100 ระบุเปอร์เซ็นต์ของอีเมลที่ล้มเหลวซึ่งควรดำเนินการ
  • rua=mailto:dmarc@yourdomain.com คือที่อยู่อีเมลที่จะส่งรายงานรวมไป รายงานเหล่านี้มีข้อมูลเกี่ยวกับอีเมลทั้งหมดจาก IP ของคุณที่ได้รับจากผู้ให้บริการรายใดรายหนึ่ง แทนที่ dmarc@yourdomain.com ด้วยที่อยู่อีเมลที่คุณต้องการรับรายงานเหล่านั้น

วิธีสร้างเทมเพลตแบบไดนามิกใน SendGrid

เครื่องมือที่เราจะสร้างในวันนี้ใช้คุณลักษณะเทมเพลตแบบไดนามิกของ SendGrid เพื่อกำหนดหัวเรื่องและเนื้อหาของอีเมล ในการตั้งค่านี้ ให้เลือกตัวเลือก "Email API" ในเมนูการนำทางด้านข้าง จากนั้นเลือก "เทมเพลตไดนามิก"

วิธีส่งจดหมายข่าวทางอีเมลด้วย SendGrid API
การตั้งค่าเมนูสำหรับเทมเพลตแบบไดนามิก

คุณจะเห็นหน้าจอพร้อมท์ให้สร้างเทมเพลตไดนามิกแรกของคุณ เลือกตัวเลือก "สร้างเทมเพลตแบบไดนามิก"

ตั้งชื่อเทมเพลตใหม่ของคุณ:"freeCodeCamp SendGrid Tutorial" SendGrid จะเพิ่มเทมเพลตนี้ในรายการเทมเพลตที่พร้อมใช้งาน เลือกเทมเพลตเพื่อดู Template ID (จดบันทึกสิ่งนี้ เนื่องจากเราต้องการเครื่องมือนี้ในภายหลัง) และคลิกปุ่ม "เพิ่มเวอร์ชัน"

วิธีส่งจดหมายข่าวทางอีเมลด้วย SendGrid API
ดูตัวอย่างเทมเพลตที่เพิ่มใหม่

เลือก "เทมเพลตเปล่า" บนหน้าจอที่ปรากฏขึ้น จากนั้นเลือก "ตัวแก้ไขโค้ด" ตอนนี้คุณควรเห็นมุมมองเอดิเตอร์ โปรแกรมแก้ไขของ SendGrid ใช้ HTML เพื่อสร้างเนื้อหาอีเมล อย่างไรก็ตาม เมื่อเราสร้างเครื่องมือ เราจะส่งเวอร์ชันข้อความธรรมดา

ในตอนนี้ ให้แทนที่เนื้อหาของตัวแก้ไขด้วยรหัสต่อไปนี้:

<p>This is a test email used with the freeCodeCamp SendGrid tutorial</p>
<p>Unsubscribe: {{{unsubscribeId}}}</p>
เครื่องมือของเราจะส่งอีเมลข้อความธรรมดา ดังนั้นจึงไม่จำเป็นต้องใช้เทมเพลต HTML เพิ่มเติม

คุณจะสังเกตเห็นว่าเราได้เพิ่ม {{{unsubscribeId}}} . เทมเพลตของ SendGrid ใช้ Handlebars เพื่อแทนที่ค่าแบบไดนามิก - เราจะใช้ประโยชน์จากคุณลักษณะนี้เมื่อเราสร้างเครื่องมือ

ตอนนี้ เลือกตัวเลือกการตั้งค่าจากด้านซ้ายบน - คุณอาจเลือกตั้งชื่อเวอร์ชันเทมเพลตของคุณได้ แต่ช่อง "หัวเรื่อง" คือสิ่งที่เราต้องการแก้ไข ตั้งค่านี้เป็น {{{subject}}} เพื่อโหลดค่าหัวเรื่องจากเครื่องมือของเราแบบไดนามิก

หากต้องการทดสอบเทมเพลตแบบไดนามิก ให้เลือกตัวเลือก "ทดสอบข้อมูล" จากเมนูด้านบน แทรกข้อมูล JSON นี้ลงในตัวแก้ไขที่นั่น:

{
    "unsubscribeId": "1",
    "subject": "Testing emails!"
}
จำไว้ว่า JSON ต้องใช้คีย์ในการใส่เครื่องหมายคำพูด!

ตอนนี้คุณควรเห็นการแสดงตัวอย่างทางด้านขวาของหน้าจอซึ่งแสดงถึงค่าเหล่านี้ในเทมเพลต อย่าลืมกด Save ปุ่มเพื่อบันทึกการเปลี่ยนแปลงของคุณ!

วิธีส่งจดหมายข่าวทางอีเมลด้วย SendGrid API
หน้าจอตัวแก้ไขและแสดงตัวอย่างแสดงการโหลดค่าเทมเพลตแบบไดนามิก

วิธีสร้างคีย์ API ใน SendGrid

ขั้นตอนสุดท้ายในการกำหนดค่าบัญชี SendGrid คือการสร้างคีย์ API เพื่อให้เครื่องมือของเราใช้งานได้

คลิกลูกศรย้อนกลับที่ด้านบนซ้ายเพื่อกลับไปยังหน้า SendGrid หลัก จากนั้นเลือก "การตั้งค่า" และ "คีย์ API" เลือก "สร้างคีย์ API" เพื่อสร้างคีย์ใหม่ คุณสามารถเลือกให้ "การเข้าถึงแบบเต็ม" กับคีย์ของคุณได้ แต่สำหรับจุดประสงค์ของบทช่วยสอนนี้ คุณจะต้องเข้าถึง "ส่งเมล" เท่านั้น

อย่าลืมตั้งชื่อที่สื่อความหมายให้กับคีย์ของคุณ เพื่อที่คุณจะจดจำจุดประสงค์ของคีย์ได้หากคุณเข้าถึงหน้าจอนี้อีกครั้ง เมื่อคุณกำหนดค่าการอนุญาตแล้ว ให้เลือก "สร้างและดู" เพื่อสร้างคีย์ - บันทึกไว้ในที่ที่ปลอดภัยเพราะคุณจะไม่สามารถดูได้อีก .

วิธีส่งจดหมายข่าวทางอีเมลด้วย SendGrid API
สร้างหน้าจอ API โดยเปิดใช้การอนุญาต Mail Send

วิธีสร้างเครื่องมืออีเมล

ตอนนี้ได้เวลาเขียนโค้ดเพื่อส่งอีเมลจริงๆ แล้ว คุณสามารถดูโค้ดสำหรับแอปพลิเคชันที่ใช้งานจริงได้ แต่สำหรับจุดประสงค์ของบทช่วยสอนนี้ เราจะสร้างเวอร์ชันที่ลดขนาดลงเล็กน้อยเพื่อเน้นที่การใช้ SendGrid API เป็นหลัก

ซอฟต์แวร์ที่จำเป็นสำหรับสคริปต์แคมเปญอีเมลที่กำหนดเอง

คุณจะต้องติดตั้งเครื่องมือต่อไปนี้เพื่อใช้งานโปรเจ็กต์นี้:

  • Node.js - แนะนำให้ใช้เวอร์ชัน LTS
  • IDE เช่น VSCode หรือ Atom

คุณยังอาจต้องการ git สำหรับการควบคุมเวอร์ชัน

เครื่องมือสดของเราใช้คลัสเตอร์ MongoDB Atlas แต่ตัวอย่างบทช่วยสอนของเราจะไม่ใช้ หากคุณไม่คุ้นเคยกับ MongoDB หลักสูตรของ freeCodeCamp จะมีส่วนที่ยอดเยี่ยมในการตั้งค่าและใช้งาน MongoDB

วิธีการเริ่มต้นโครงการ

สร้างไดเร็กทอรี (โฟลเดอร์) ที่จะใช้ในโครงการนี้ จากนั้นเปิดโฟลเดอร์นั้นด้วยเครื่องมือแก้ไขและเทอร์มินัลที่คุณเลือก

ในการเริ่มต้น เราจะต้องตั้งค่านี้เป็นโปรเจ็กต์โหนด วิธีที่เร็วที่สุดคือใช้ npm init ในเทอร์มินัลของคุณ ขั้นตอนนี้จะแนะนำคุณเกี่ยวกับการสร้าง package.json ซึ่งเป็นไฟล์หลักของแอปพลิเคชันโหนด

ค่าเริ่มต้นจะทำงานได้ดีสำหรับแอปพลิเคชันของเรา แต่เราจะต้องการแก้ไข scripts ส่วน:

  "scripts": {
    "build": "tsc",
    "send": "node ./prod/send.js"
  },
npm init จะสร้าง test สคริปต์ - สามารถลบออกสำหรับโครงการของเราได้

The build สคริปต์จะถูกใช้เพื่อรวบรวม TypeScript ของเราเป็น JavaScript และ send สคริปต์จะเรียกใช้แอปพลิเคชันของเรา

ต่อไปเราจะติดตั้งและตั้งค่า TypeScript หากคุณไม่คุ้นเคยกับ TypeScript มันจะเป็น superset ของ JavaScript ที่มีคำจำกัดความประเภทที่เข้มงวดกว่าและการตรวจสอบข้อผิดพลาดในการคอมไพล์

ในการติดตั้ง TypeScript ในโครงการของคุณ ให้เรียกใช้ npm install --save-dev typescript ในเทอร์มินัลของคุณ (The --save-dev แฟล็กบันทึกเป็นการพึ่งพาการพัฒนา - ไม่จำเป็นต้องใช้ TypeScript ที่รันไทม์ จึงสามารถล้างข้อมูลในสภาพแวดล้อมที่ใช้งานจริงได้)

TypeScript ต้องการไฟล์การกำหนดค่าของตัวเองเพื่อตั้งกฎที่ควรปฏิบัติตามเมื่อสร้างไฟล์ JavaScript สร้างไฟล์ในไดเรกทอรีรากของโปรเจ็กต์ชื่อ tsconfig.json และใส่ข้อความต่อไปนี้:

{
    "compilerOptions": {
      "target": "es5",
      "module": "commonjs",
      "strict": true,
      "esModuleInterop": true,
      "skipLibCheck": true,
      "forceConsistentCasingInFileNames": true,
      "outDir": "./prod",
      "rootDir": "./src"
    }
  }
หากคุณดูที่เก็บบทช่วยสอน คุณจะเห็น excludes พิเศษ คุณสมบัติ. ค่านั้นเฉพาะสำหรับโครงสร้างไฟล์บทช่วยสอน และคุณไม่จำเป็นต้องใช้

เพื่อความกระชับ เราจะไม่ลงลึกในการตั้งค่าการกำหนดค่าเหล่านี้ หากคุณต้องการข้อมูลเพิ่มเติม TypeScript มีเอกสารเชิงลึก

หากคุณกำลังใช้ git สำหรับการควบคุมเวอร์ชันและการอัปโหลดไปยังที่เก็บ (เช่น GitHub) คุณจะต้องสร้าง .gitignore ไฟล์ในไดเร็กทอรีรากของโปรเจ็กต์ของคุณ ไฟล์นี้ควรมี:

/node_modules/
.env
/prod/
  • /node_modules/ จะละเว้นแพ็คเกจที่ติดตั้ง นี่เป็นแนวทางปฏิบัติที่ดีที่สุดเมื่อทำงานกับการควบคุมเวอร์ชัน
  • .env จะละเว้นไฟล์ตัวแปรสภาพแวดล้อมของเรา สิ่งนี้สำคัญมากเพราะคุณไม่เคย ต้องการเปิดเผยความลับของคุณไปยังที่เก็บ
  • /prod/ จะละเว้นไฟล์ JavaScript ที่คอมไพล์ของเรา นอกจากนี้ เราจะใช้โฟลเดอร์นี้สำหรับรายชื่ออีเมลของเรา ดังนั้นสิ่งสำคัญคือต้องหลีกเลี่ยงการเปิดเผยข้อมูลส่วนตัวที่สามารถระบุตัวตนได้โดยไม่ได้ตั้งใจ

สร้าง .env ไฟล์ในไดเร็กทอรีโปรเจ็กต์รูทของคุณ เราจะโหลดตัวแปรสภาพแวดล้อมต่อไปนี้ผ่านไฟล์นี้:

SENDGRID_API_KEY=
SENDGRID_FROM=
SENDGRID_TEMPLATE_ID=

MAIL_SUBJECT=
เมื่อคุณกรอกค่า อย่าลืมใส่เครื่องหมายคำพูดคู่ และไม่มีช่องว่างรอบ = ลงชื่อ!
  • SENDGRID_API_KEY ควรเป็นคีย์ API ที่คุณสร้างในขั้นตอนก่อนหน้านี้
  • SENDGRID_FROM ควรเป็นที่อยู่อีเมลของคุณ (นี่คือที่อยู่ที่ใช้สำหรับ from )
  • SENDGRID_TEMPLATE_ID ควรเป็น id สตริงสำหรับเทมเพลตไดนามิกที่คุณสร้างไว้ก่อนหน้านี้
  • MAIL_SUBJECT จะเป็นหัวเรื่องของอีเมลที่คุณส่ง สำหรับตอนนี้ ให้ตั้งค่านี้เป็น "fCC Tutorial Email"

สุดท้าย สร้าง src โฟลเดอร์ในไดเรกทอรีโปรเจ็กต์รูทของคุณ และสร้าง send.ts ไฟล์ในโฟลเดอร์นั้น

วิธีการติดตั้งการพึ่งพาของคุณ

ก่อนอื่นเราต้องติดตั้ง sendgrid แพ็คเกจ Node.js แพ็คเกจนี้ทำหน้าที่เป็นตัวห่อหุ้มสำหรับ SendGrid API และจะปรับปรุงกระบวนการของเราในการเรียก API เพื่อส่งอีเมล เรียกใช้ npm install @sendgrid/mail เพื่อติดตั้งแพ็คเกจนี้

จากนั้นเราจำเป็นต้องมีการพึ่งพาการพัฒนาสองสามอย่าง เรียกใช้ npm install --save-dev dotenv @types/node .

  • dotenv จะทำให้เราสามารถโหลดตัวแปรสภาพแวดล้อมจาก .env ไฟล์ในเครื่อง
  • @types/node ให้คำจำกัดความประเภทสำหรับ Node.js - TypeScript อาศัยคำจำกัดความเหล่านี้เพื่อทำความเข้าใจโครงสร้างของวิธีการและฟังก์ชันในตัว

วิธีการเขียนลอจิก

ตอนนี้เราจะทำงานใน /src/send.ts . ของเรา ไฟล์ - นี่คือที่ที่เรากำลังสร้างตรรกะของแอปจำนวนมาก เราจะเริ่มต้นด้วยการนำเข้าค่าที่จำเป็นจากแพ็คเกจของเรา

ก่อนอื่นเราต้องการโหลด dotenv แพ็คเกจและแยกวิเคราะห์ตัวแปรสภาพแวดล้อมของเรา

import dotenv from "dotenv";
dotenv.config();
dotenv จำเป็นสำหรับการพัฒนาในพื้นที่เท่านั้น - โฮสต์ออนไลน์ส่วนใหญ่ เช่น Heroku และ Repl.it สามารถจัดการตัวแปรสภาพแวดล้อมได้แบบเนทีฟ

The dotenv.config() โทรอ่าน .env . ของเรา ไฟล์และโหลดค่าลงใน process.env โหนดวัตถุ

ต่อไปเราจะนำเข้าโมดูลที่จำเป็นจากแพ็คเกจ SendGrid:

import sgMail, { MailDataRequired } from "@sendgrid/mail";
TypeScript สามารถนำเข้าสิ่งต่าง ๆ ได้โดยอัตโนมัติ แต่ควรฝึกการนำเข้าด้วยตนเอง

sgMail เป็น wrapper API หลัก และ MailDataRequired เป็นคำจำกัดความประเภทที่เราต้องการ

สุดท้าย เรานำเข้าคุณสมบัติโหนดในตัวสำหรับจัดการไฟล์ของเรา:

import path from "path";
import { createWriteStream, readFile } from "fs";
{ ไวยากรณ์ } ใช้สำหรับการนำเข้าโมดูลเฉพาะจากแพ็คเกจ
  • path จะใช้เพื่อค้นหาไฟล์รายชื่ออีเมลของเราที่มีเส้นทางที่เกี่ยวข้อง
  • fs จะใช้ในการอ่านและเขียนไปยังไฟล์เหล่านั้น

ถึงเวลาเริ่มสร้างตรรกะ! แอปพลิเคชันของเราอาศัยค่าที่จำเป็นบางอย่างในการตั้งค่า .env ดังนั้นเราต้องเริ่มต้นด้วยการตรวจสอบว่าตัวแปรเหล่านั้นถูกตั้งค่าอย่างถูกต้อง หากขาดหายไป เราต้องการให้แอปพลิเคชันของเราออกก่อนเวลาเพื่อหลีกเลี่ยงข้อผิดพลาดเมื่อเราส่งอีเมล

// 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!";
The || ไวยากรณ์บอกรหัสว่าถ้า process.env.MAIL_SUBJECT ไม่ได้กำหนดหรือผิด ให้ใช้สตริงแทน

process.exit(1) การเรียกที่คุณเห็นในแต่ละเงื่อนไขการตรวจสอบบอกให้ Node ยุติกระบวนการ (แอปพลิเคชันของเรา) ด้วยรหัสออก 1 . นี่แสดงว่าแอปพลิเคชันของเราขัดข้องเนื่องจากการตรวจสอบอย่างใดอย่างหนึ่งเหล่านี้ล้มเหลว

SendGrid กำหนดให้เราต้องตั้งค่าคีย์ API ด้านล่างลอจิกตัวแปรสภาพแวดล้อม ให้เพิ่มการเรียกใช้ฟังก์ชันเพื่อตั้งค่าคีย์

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

ก่อนดำเนินการต่อ ให้เรียกใช้ npm run build ในเทอร์มินัลของคุณ - สิ่งนี้จะสร้าง prod โฟลเดอร์ที่มี JavaScript ที่คอมไพล์แล้วของเรา ตอนนี้คุณควรเห็นโครงสร้างไฟล์ต่อไปนี้:

วิธีส่งจดหมายข่าวทางอีเมลด้วย SendGrid API
แผนผังไฟล์สำหรับจุดนี้ในบทช่วยสอน

ณ จุดนี้ หากคุณกำลังใช้ git คุณต้องการที่จะ มั่นใจมาก ว่า prod โฟลเดอร์จะไม่ถูกผูกมัดกับที่เก็บของคุณ

ภายใน prod โฟลเดอร์ สร้าง validEmails.csv ไฟล์. แอพของเราจะใช้ไฟล์นี้เพื่ออ่านรายชื่ออีเมล เริ่มต้นไฟล์ด้วยเนื้อหาต่อไปนี้ (แทนที่ your@email.com ด้วยที่อยู่อีเมลจริงของคุณ):

email,unsubscribeId
your@email.com,1
iama@fake.email,2
.csv ไฟล์ไม่มีช่องว่างรอบเครื่องหมายจุลภาค

ตอนนี้เราสามารถเขียนโค้ดเพื่อแยกวิเคราะห์ลงในรายชื่ออีเมลได้แล้ว! ใน src/send.ts . ของคุณ ไฟล์เพิ่มรหัสนี้:

// 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)
});
เราใช้ไวยากรณ์ฟังก์ชันลูกศร ES6 ตลอดกระบวนการนี้ คุณสามารถใช้ function . ได้ ประกาศแทน ถ้าคุณต้องการ

ตอนนี้ถ้าคุณเรียกใช้ npm run build และ npm run send คุณควรเห็นเนื้อหาของ validEmail.csv . ของเรา ไฟล์ในเทอร์มินัล หากต้องการ คุณสามารถดูความคืบหน้าปัจจุบันของเราได้จนถึงจุดนี้

ยอดเยี่ยม! ตอนนี้ เราต้องแยกสตริงนั้นออกเป็นอาร์เรย์ของอ็อบเจ็กต์ เพื่อให้เราสามารถวนซ้ำและสร้างข้อความอีเมลของเราได้ อัปเดตฟังก์ชันการโทรกลับของเรา:

// 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] ใช้ destructuring เพื่อกำหนดค่าของ split array ให้กับตัวแปรสองตัวนั้น
  • .split("\n") แยกสตริงโดยตัวแบ่งบรรทัด หมายเหตุ :หากคุณใช้ Windows คุณอาจต้องเปลี่ยนการตั้งค่าสิ้นสุดบรรทัดสำหรับ validEmails.csv ของคุณ จาก CRLF ถึง LF (Windows แทรกอักขระขึ้นบรรทัดใหม่ที่จะส่งผลต่อการจัดการข้อมูลของเรา)
  • .slice(1) ลบองค์ประกอบแรกของอาร์เรย์นั้น (email,unsubscribeId . ของเรา บรรทัด)
  • ของเรา map ฟังก์ชั่นจะแปลงแต่ละ email,unsubscribeId สตริงลงใน {email, unsubscribeId} วัตถุ

ผลลัพธ์สุดท้ายของฟังก์ชันการแยกวิเคราะห์นี้จะเป็นอาร์เรย์ของวัตถุที่มี email และ unsubscribeId คุณสมบัติ - ใช้งานได้ง่ายกว่าสตริงมาก

วิธีส่งจดหมายข่าวทางอีเมลด้วย SendGrid API
ตัวอย่างเอาต์พุตจากฟังก์ชันการแยกวิเคราะห์

ถึงเวลาที่จะส่งอีเมลบางส่วน ด้านล่างฟังก์ชันการแยกวิเคราะห์ของคุณ (แต่ยังอยู่ใน readFile โทรกลับ) เพิ่มโครงสร้างสำหรับวิธีการวนซ้ำของเรา เนื่องจากเราต้องการเข้าถึงแต่ละค่าในอาร์เรย์ เราจะใช้ .forEach เข้าใกล้

  // Here we iterate through the emailList array
  emailList.forEach((user) => {});
The user พารามิเตอร์จะเป็น {email, unsubscribeId} วัตถุ. เราเรียกมันว่า user เพราะมันแสดงถึงออบเจ็กต์ข้อมูลผู้ใช้ freeCodeCamp ในแอปพลิเคชันแบบเต็ม

ภายในการโทรกลับสำหรับ .forEach เราสามารถสร้างวัตถุข้อความที่ SendGrid API คาดหวังได้

  // 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
        }
    }
    
  });

ก่อนดำเนินการต่อไป มาดูวัตถุข้อความนี้ให้ละเอียดยิ่งขึ้น MailDataRequired เรานำเข้าก่อนหน้านี้ใช้เป็นคำจำกัดความของประเภทที่นี่ ดังนั้น TypeScript สามารถแจ้งเตือนเราหากเราพลาดคุณสมบัติที่จำเป็น โชคดีที่เรามีคุณสมบัติที่จำเป็นทั้งหมด แต่มันหมายความว่าอย่างไร?

  • to: ที่อยู่อีเมลที่จะส่งข้อความถึง นี่จะเป็น email จากแต่ละบรรทัดของ validEmails.csv . ของเรา ไฟล์
  • from: ที่อยู่อีเมลที่จะส่งข้อความจาก มีการตั้งค่าใน .env . ของเรา ก่อนหน้านี้ (ควรเป็น ของคุณ ที่อยู่อีเมล)
  • subject: ฟิลด์นี้ไม่จำเป็น แต่ให้ค่าทางเลือกแก่เราในกรณีที่เทมเพลตไดนามิกแยกวิเคราะห์หัวเรื่องของเราไม่ถูกต้อง
  • text: ค่าข้อความนี้ถูกเขียนทับโดยเทมเพลต อย่างไรก็ตาม มันยังคงเป็นสิ่งสำคัญที่จะใช้ SendGrid สามารถส่งอีเมลเป็น plaintext หรือ html - โดยใช้ text คุณสมบัติแทน html ทรัพย์สิน เรามั่นใจว่าแม่แบบของเราจะถูกส่งเป็น plaintext . ผู้ให้บริการอีเมล มีแนวโน้มมากขึ้น เพื่อตั้งค่าสถานะข้อความ HTML ว่าเป็นสแปม จึงช่วยเพิ่มอัตราการส่งของเราได้
  • templateId: นี่คือรหัสสำหรับเทมเพลตแบบไดนามิกที่ SendGrid ควรใช้ในอีเมล
  • dynamicTemplateData: ค่าเหล่านี้เป็นค่าที่สอดคล้องกับสตริงแฮนด์บาร์ที่เราตั้งค่าไว้ในเทมเพลตไดนามิกก่อนหน้านี้

ยอดเยี่ยม! ขั้นตอนต่อไปของเราคือนำข้อความที่สร้างขึ้นนี้แล้วส่ง ด้านล่างวัตถุข้อความ (แต่ยังอยู่ใน .forEach โทรกลับ) มาเพิ่มการส่งของเรา:

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

การดำเนินการนี้จะส่งข้อความไปยังอีเมลแต่ละฉบับใน validEmails.csv . ของเรา . น่าเสียดายที่รหัสของเราจะทำงานโดยไร้เสียง และเราจะไม่ทราบว่าการส่งแต่ละครั้งสำเร็จหรือไม่ มาเพิ่มการจัดการข้อผิดพลาดกัน

.send() โทรกลับ Promise ดังนั้นเราจึงสามารถใช้ .then().catch() เพื่อจัดการกับผลตอบแทน

    // 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}`)
        });
คุณยังสามารถใช้ async/await ได้ แต่นี่เป็นกรณีที่ .then.catch ชัดเจนกว่า

ตอนนี้ถ้าคุณเรียกใช้ npm run build และ npm run send คุณควรเห็นอีเมลที่สวยงามในกล่องจดหมายของคุณ!

ณ จุดนี้ ตอนนี้คุณมีแอปพลิเคชันส่งอีเมลที่ใช้งานได้แล้ว ยินดีด้วย! คุณสามารถดูความคืบหน้าของเราจนถึงจุดนี้ได้หากต้องการ

อ่านต่อไปเพื่อดูวิธีจัดการกับอีเมลตีกลับและตรรกะเพิ่มเติมสำหรับความล้มเหลวในการส่ง ซึ่งเราจะพูดถึงต่อไป

วิธีจัดการอีเมลที่ถูกตีกลับใน SendGrid

คุณอาจสังเกตเห็นว่า iama@fake.email มากไม่ใช่ที่อยู่อีเมลจริง SendGrid จะสร้างรายงานตีกลับทุกวันสำหรับกิจกรรมของคุณในวันก่อนหน้า

อีเมลที่ถูกตีกลับทุกฉบับจะสร้างความเสียหายต่อชื่อเสียงของ SendGrid และอาจส่งผลให้ผู้ให้บริการอีเมลทำเครื่องหมายว่าอีเมลของคุณเป็นสแปม เราจึงต้องเพิ่มตรรกะเพื่อป้องกันการส่งไปยังที่อยู่ตีกลับที่ทราบ

เริ่มต้นด้วยการสร้าง bouncedEmails.csv ไฟล์ใน prod . ของคุณ โฟลเดอร์ (ควรอยู่ถัดจาก validEmails.csv . ของคุณ ). เราไม่ต้องการ unsubscribeId ค่าที่นี่ ดังนั้นเริ่มต้นด้วย:

email
iama@fake.email
เราได้เพิ่มอีเมลปลอมเพื่อการสาธิต

กลับไปที่ send.ts . ของเรา ไฟล์. ในบรรทัดที่ 38 ด้านล่าง filePath . ที่มีอยู่ของเรา ประกาศ กำหนดค่าเส้นทางสำหรับ bouncedEmails.csvใหม่ ไฟล์.

// 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 หมายถึงไดเร็กทอรีปัจจุบันของไฟล์นี้ (ในกรณีของเรา send.ts ไฟล์).

ยอดเยี่ยม! ตอนนี้เราต้องอ่านไฟล์นั้น ใต้การประกาศเส้นทางไฟล์เหล่านี้ทันที (ก่อน readFile . ที่มีอยู่ของเรา โทร) เพิ่มตรรกะในการอ่านไฟล์ที่ตีกลับ

// 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 เป็นแบบอะซิงโครนัส - ดังนั้นเราจึงจำเป็นต้องรวมฟังก์ชันการโทรกลับไว้รอบ ๆ ลอจิกการส่งที่มีอยู่ทั้งหมดของเรา . ตรวจสอบให้แน่ใจว่าปิด }) สำหรับการเรียกกลับนี้จะถูกย้ายไปยังส่วนท้ายสุดของไฟล์ของเรา

เราอ่าน bouncedEmails.csv แยกไฟล์ในบรรทัดใหม่ (จำไว้ว่าคุณจะต้องแน่ใจว่าส่วนท้ายบรรทัดของคุณคือ LF ) และลบ email ไลน์. สุดท้าย เราดำเนินการกับตรรกะการส่งที่มีอยู่ของเราต่อไป

กลับไปที่ตรรกะการส่งของเรา ภายใน .forEach . ของเรา ฟังก์ชั่น เพิ่มตรรกะเพื่อข้ามอีเมลที่ถูกบล็อก (เราจะเพิ่มสิ่งนี้ก่อนที่จะสร้างวัตถุข้อความเพื่อหลีกเลี่ยงการสร้างตัวแปรที่ไม่จำเป็น)

  // 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;
    }
    
ถ้าของเรา bounceList.csv ไฟล์ว่างเปล่า กำลังเรียก includes จะโยนข้อผิดพลาด ดังนั้นเราจึงตรวจสอบ .length ให้คุ้มค่าก่อน

โดยใช้ประโยชน์จาก return early ในยุคต้นๆ คำสั่ง เราจบ .forEach . นั้น วนซ้ำเมื่อ bounceList รวมถึงอีเมลนั้นด้วย ซึ่งจะป้องกันไม่ให้เราพยายามส่งไปยังที่อยู่อีเมลที่เคยถูกตีกลับ ตอนนี้ถ้าคุณเรียกใช้ npm run build และ npm run start คุณควรเห็นผลลัพธ์นี้ในเทอร์มินัลของคุณ:

วิธีส่งจดหมายข่าวทางอีเมลด้วย SendGrid API
ตัวอย่างเอาต์พุตคอนโซลสำหรับอีเมลที่ข้ามและอีเมลที่สำเร็จ

ดูความคืบหน้าของเราจนถึงจุดนี้

วิธีการดักจับอีเมลที่ล้มเหลวใน SendGrid

ขณะนี้แอปพลิเคชันของเราจะบันทึกข้อผิดพลาดหากส่งอีเมลไม่สำเร็จ วิธีนี้ใช้ได้กับกรณีการใช้งานขนาดเล็ก แต่เมื่อคุณขยายขนาดแอปพลิเคชัน คุณจะพบว่าการระบุความล้มเหลวเหล่านั้นและพยายามส่งอีกครั้งนั้นยากขึ้นเรื่อยๆ

แต่เราสามารถทำให้แอปพลิเคชันของเราบันทึกอีเมลเหล่านั้นในไฟล์ใหม่แทนได้

สร้าง failedEmails.csv ไฟล์ใน prod . ของคุณ โฟลเดอร์ ไฟล์นี้สามารถว่างเปล่าได้ เราจะเขียนโค้ดเพื่อเพิ่มแถวส่วนหัว

กลับไปที่ send.ts . ของเรา ไฟล์ ไปที่การประกาศเส้นทางของเราในบรรทัดที่ 38 มาเพิ่มอีกสำหรับ failedEmails.csv ใหม่ของเรา :

// 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");

เส้นทางนี้จะใช้สำหรับ write . ต่างจากเส้นทางอื่นๆ ของเรา การดำเนินการ. เนื่องจากเราต้องการเขียนอย่างต่อเนื่องในการประมวลผลอีเมล เราจึงต้องสร้างสตรีมเพื่อดำเนินการดังกล่าว ใต้การประกาศเส้นทางเหล่านี้ มาสร้างสตรีมนั้นและเพิ่มแถวส่วนหัวเริ่มต้นของเรา

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

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

ถึงเวลาปรับปรุงตรรกะการจัดการข้อผิดพลาดเพื่อรวมสตรีมใหม่นี้ เราต้องเพิ่มอีก write การดำเนินการกับข้อผิดพลาดของเราในการจัดการใน send โทร.

    // 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`)
      });
เราต้องการรักษาคำสั่งคอนโซลเพื่อให้แน่ใจว่าเราเห็นข้อเสนอแนะในขณะที่สคริปต์ทำงาน

สิ่งนี้จะเขียน email และ unsubscribeId ไปยัง failedEmails.csv . ใหม่ของเรา ในรูปแบบที่เหมาะสม - ทำให้เราสามารถคัดลอกข้อมูลนั้นลงใน validEmails.csv เพื่อลองส่งอีกครั้ง

ยินดีด้วย! ตอนนี้คุณได้สร้างเครื่องมือที่ประสบความสำเร็จและทำงานได้อย่างสมบูรณ์เพื่อส่งจดหมายข่าวทางอีเมล คุณสามารถดูรหัสที่เสร็จสมบูรณ์ได้หากต้องการยืนยันงานของคุณ แต่โปรดอ่านต่อเพื่อดูฟีเจอร์เสริม "น่ามี" สองสามอย่าง

คุณลักษณะเสริมสำหรับเครื่องมืออีเมลของคุณ

เนื่องจากเครื่องมือของเราเป็นแบบ CLI (หมายถึงใช้ในอินเทอร์เฟซบรรทัดคำสั่งหรือเทอร์มินัล) จึงไม่มีความคิดเห็นของผู้ใช้มากนัก เราสามารถใช้ประโยชน์จากฟังก์ชันคอนโซลเพิ่มเติมเพื่อให้ข้อมูลเพิ่มเติมเกี่ยวกับความคืบหน้าของสคริปต์ได้

เริ่มต้นด้วยการเพิ่ม "จุดตรวจ" ก่อนการตรวจสอบตัวแปรสภาพแวดล้อมของเรา ให้พิมพ์ข้อความว่าสคริปต์ได้เริ่มต้นแล้วและกำลังตรวจสอบตัวแปรอยู่:

console.info('Script started. Validating environment variables...')
console.info ระบุว่านี่เป็นข้อความแสดงข้อมูล

จากนั้น หลังจากตรวจสอบความถูกต้องแล้ว เราก็สามารถพิมพ์ข้อความแสดงความสำเร็จได้

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

console.info('Variables confirmed!')

ภายในฟังก์ชันของเราในการอ่านไฟล์ที่ตีกลับ เราสามารถเพิ่มข้อความสำหรับการเริ่มต้น ความล้มเหลว และความสำเร็จได้

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!')

และเช่นเดียวกันสำหรับรายชื่ออีเมลที่ถูกต้องของเรา:

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;
  }

ตอนนี้ คงจะดีมากถ้ามีการพิมพ์ข้อความเมื่อการดำเนินการเสร็จสิ้น อย่างไรก็ตาม หากเราเพิ่ม console.info ต่อจาก .forEach . ของเรา วนซ้ำ มันจะพิมพ์ ก่อน ส่งอีเมลเสร็จแล้ว!

ทั้งนี้เป็นเพราะ .send เมธอดสร้างการโทรผ่านเครือข่ายและส่งคืน Promise และ Promise นั้นอาจไม่ได้แก้ไข/ปฏิเสธก่อนที่การทำซ้ำของเราจะเสร็จสิ้น

ดังนั้นเราจึงสามารถสร้างตัวนับเพื่อติดตามจำนวนอีเมลที่เราส่งไปเทียบกับจำนวนอีเมลทั้งหมด ก่อนถึง .forEach . ของเรา วนซ้ำ เพิ่มตัวแปรเหล่านี้:

    // Here we create variables for counting
    const emailTotal = emailList.length;
    let emailCount = 0;
โดยการกำหนด .length ให้กับตัวแปร เราไม่ต้องอ่านมันในการวนซ้ำแต่ละครั้ง

เราต้องการนับอีเมลที่ถูกตีกลับเป็นการประมวลผล แม้ว่าเราจะข้ามไปก็ตาม

  // 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;
      }
    }

สุดท้ายเราต้องเพิ่มตรรกะเพื่อดูว่าอีเมลที่เราส่งเป็นอีเมลฉบับสุดท้ายหรือไม่ ตรรกะนี้ใช้กับตัวจัดการความสำเร็จและข้อผิดพลาดสำหรับการโทรส่ง:

    // 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!`
          );
        }
      });

และด้วยเหตุนี้ แอพของเราจึงสมบูรณ์! หากคุณเรียกใช้ npm run build และ npm run send สคริปต์ คุณควรเห็นผลลัพธ์นี้ในเทอร์มินัลของคุณ:

วิธีส่งจดหมายข่าวทางอีเมลด้วย SendGrid API
ตัวอย่างเอาต์พุตคอนโซลสำหรับแอปพลิเคชันที่เสร็จสมบูรณ์

และคุณควรได้รับอีเมลสองสามฉบับที่มีลักษณะคล้ายนี้:

วิธีส่งจดหมายข่าวทางอีเมลด้วย SendGrid API
ภาพตัวอย่างของผลการทดสอบอีเมล

คุณสามารถดูโค้ดสุดท้ายของเราได้ที่นี่ หรือดูเวอร์ชันเพิ่มเติมที่สร้างขึ้นสำหรับ freeCodeCamp