คู่มือ · email api

ทีมผลิตภัณฑ์ควรใช้ email API อย่างปลอดภัยอย่างไร

ใช้ email API เป็นเวิร์กโฟลว์แบบอะซิงโครนัสที่มีการกำหนดสิทธิ์ แทนการเรียกจากฟอร์มไปยังผู้ให้บริการโดยตรง ยืนยันตัวตนผู้เรียก ยืนยันว่าผู้เช่าเป็นเจ้าของโดเมน From ที่ยืนยันแล้ว ตรวจสอบและกำหนดขนาดของข้อความ กำหนดรหัสงานของแอปพลิเคชันที่คงที่ ใส่คิวเพียงครั้งเดียว และส่งจาก worker บันทึกรหัสข้อความของผู้ให้บริการเมื่อได้รับการยอมรับ รับอีเวนต์การส่งแบบ idempotent และระงับการส่งถึงอีเมลตีกลับถาวรและการร้องเรียน ใช้การลองใหม่แบบมีขอบเขตเมื่อควบคุมความเสี่ยงที่จะซ้ำได้เท่านั้น เก็บข้อมูลรับรองไว้ฝั่งเซิร์ฟเวอร์ ลดข้อมูลข้อความในบันทึกให้น้อยที่สุด และแยกแยะระหว่างการที่ API ยอมรับ การส่งถึงเมลเซิร์ฟเวอร์ และการเข้ากล่องจดหมาย

กำหนดขอบเขตของ API ก่อนเลือกผู้ให้บริการ

email API ควรเปิดเผยเจตนาของแอปพลิเคชัน โดยไม่ปล่อยรายละเอียดของผู้ให้บริการทุกอย่างรั่วเข้าสู่โค้ดผลิตภัณฑ์ กำหนดรีซอร์สสำหรับข้อความ โดเมนผู้ส่ง API key อีเวนต์ และการระงับการส่ง ตัดสินใจว่าผู้เรียกควบคุมฟิลด์ใดได้ รวมถึง From, To, Reply-To, หัวเรื่อง ข้อความ HTML และ allowlist ขนาดเล็กของเฮดเดอร์ ปฏิเสธเฮดเดอร์การขนส่งที่ผู้เรียกส่งมา ซึ่งอาจขัดแย้งกับการลงลายเซ็นหรือการกำหนดเส้นทางของผู้ให้บริการ ให้ถือว่าการส่งเป็นการเขียนที่มีผลกระทบสำคัญ โดยการตอบกลับควรระบุรีซอร์สข้อความของแอปพลิเคชันและสถานะปัจจุบัน ไม่ควรบ่งบอกผลลัพธ์ของกล่องจดหมาย เก็บบัญชีผู้ให้บริการ Region configuration set และตัวระบุการขนส่งไว้หลัง adapter ขอบเขตนี้ทำให้ย้ายผู้ให้บริการได้ และให้การอนุญาต การเก็บรักษาข้อมูล และการควบคุมการละเมิดมีที่อยู่ที่คงที่

ยืนยันตัวตนผู้เรียกและอนุญาตทุกโดเมนผู้ส่ง

เก็บ API key เป็นแฮชแบบทางเดียวเท่านั้น และแสดงความลับฉบับสมบูรณ์เพียงครั้งเดียว กำหนดเจ้าของเวิร์กสเปซ สถานะ เวลาที่สร้าง และเส้นทางเพิกถอนให้แต่ละ key เพิ่มขอบเขต (scope) ที่แคบลงเมื่อการเชื่อมต่อหนึ่งควรส่งอย่างเดียวหรืออ่านอีเวนต์อย่างเดียว การยืนยันตัวตนตอบว่าใครแสดงข้อมูลรับรอง ส่วนการอนุญาตตัดสินว่าผู้นั้นใช้โดเมน From และรีซอร์สข้อความที่ร้องขอได้หรือไม่ ตรวจสอบความเป็นเจ้าของโดเมนในทุกการส่ง รวมถึง endpoint แบบชุด แทนที่จะเชื่อตัวระบุโดเมนที่ไคลเอนต์ส่งมา กำหนดให้ผู้ให้บริการยืนยันก่อนเปิดทราฟฟิกใช้งานจริง อย่าใส่ข้อมูลรับรองของผู้ให้บริการหรือ API key ของเวิร์กสเปซใน JavaScript ของเบราว์เซอร์ query string ระบบวิเคราะห์ หรือข้อความแสดงข้อผิดพลาด การอนุญาตระดับอ็อบเจกต์สำคัญเป็นพิเศษสำหรับตัวระบุข้อความ อีเวนต์ การระงับการส่ง กล่องจดหมาย และโดเมนใน API แบบหลายผู้เช่า

ยืนยันโดเมนและทำให้การยืนยันตัวตน align

โดเมนผู้ส่งต้องการมากกว่าแฟล็กในฐานข้อมูล ให้ทำการตรวจสอบความเป็นเจ้าของของผู้ให้บริการให้เสร็จ และเผยแพร่เรคคอร์ด DKIM ที่จำเป็น SPF อนุญาตโฮสต์สำหรับตัวตน SMTP MAIL FROM หรือ HELO ส่วน DKIM เชื่อมโยงโดเมนที่ลงลายเซ็นกับลายเซ็นเข้ารหัสของข้อความ DMARC ประเมินว่าตัวระบุ SPF หรือ DKIM ที่สำเร็จ align กับโดเมน From ตาม RFC 5322 ที่มองเห็นหรือไม่ และให้เจ้าของโดเมนเผยแพร่นโยบายการจัดการและการรายงาน เมื่อโดเมนมี SPF อยู่แล้ว ให้รวม mechanism ที่จำเป็นเข้าไปในเรคคอร์ดเดิม RFC 7208 ระบุว่าโดเมนต้องไม่เผยแพร่หลายเรคคอร์ดที่ทำให้เลือกเรคคอร์ด SPF ได้มากกว่าหนึ่งรายการ ให้เริ่มใช้นโยบาย DMARC ที่เข้มงวดขึ้นหลังจากข้อความทดสอบแบบควบคุมและรายงานแบบรวมแสดงว่าผู้ส่งที่ถูกต้องทุกรายอยู่ในสภาพ align แล้วเท่านั้น การยืนยันตัวตนลดการใช้โดเมนโดยไม่ได้รับอนุญาต แต่ไม่ได้ทำให้เข้ากล่องจดหมาย

ตรวจสอบโครงสร้างข้อความและรับอินพุตให้น้อยที่สุด

RFC 5322 นิยามข้อความอินเทอร์เน็ตว่าเป็นฟิลด์เฮดเดอร์ตามด้วยเนื้อหาที่เป็นทางเลือก โดยข้อกำหนด MIME ขยายเนื้อหาให้เกินกว่าข้อความพื้นฐาน API สามารถซ่อนรายละเอียดรูปแบบบนสายส่งได้เป็นส่วนใหญ่ ขณะเดียวกันก็ยังบังคับใช้ ให้ทำให้อาร์เรย์ผู้รับเป็นมาตรฐาน จำกัดจำนวนผู้รับและขนาดรวมหลังเข้ารหัส กำหนดให้มีเนื้อหาข้อความหรือ HTML อย่างน้อยหนึ่งอย่าง และตรวจสอบที่อยู่โดยไม่แสร้งว่าไวยากรณ์พิสูจน์ว่ากล่องจดหมายมีอยู่จริง ลบอักขระ carriage-return และ line-feed ออกจากฟิลด์ที่จะกลายเป็นเฮดเดอร์ สร้าง Message-ID หรือให้ผู้ให้บริการสร้าง อย่านำมาใช้ซ้ำเป็นรหัสงานของแอปพลิเคชัน เพราะข้อความเวอร์ชันใหม่อาจได้รับตัวระบุใหม่ได้อย่างถูกต้อง อนุญาตเฉพาะเฮดเดอร์กำหนดเองที่มีเอกสาร ปฏิเสธการซ้ำของฟิลด์ที่ได้รับการป้องกัน และเรนเดอร์เทมเพลตก่อนส่งให้ผู้ให้บริการ เพื่อให้ตัวแปรที่หายไปล้มเหลวในสถานะแอปพลิเคชันที่ควบคุมได้

ใส่คิวเพียงครั้งเดียวและใช้ตัวระบุของแอปพลิเคชันที่คงที่

คำขอของผู้ใช้ควรสร้างงานข้อความที่คงทนหนึ่งรายการในทรานแซกชัน จากนั้น worker จึงเรียกผู้ให้บริการ กำหนดตัวระบุที่คงที่ให้งาน และบันทึก request fingerprint หรือ idempotency key ที่ผู้เรียกให้มา เมื่อสัญญารองรับ HTTP กำหนดให้ POST ไม่ idempotent โดยค่าเริ่มต้น และเตือนไม่ให้ลองใหม่อัตโนมัติ เว้นแต่ไคลเอนต์ทราบว่าการดำเนินการนั้น idempotent อย่างมีผล หรือทราบว่าคำขอเดิมไม่ได้ถูกนำไปใช้ เรื่องนี้สำคัญสำหรับอีเมล เพราะการหมดเวลาอาจเกิดขึ้นหลังจากผู้ให้บริการยอมรับข้อความแล้วแต่ก่อนที่ worker จะได้รับการตอบกลับ เมื่อเกิดความล้มเหลวที่กำกวม ให้กระทบยอดงานที่เก็บไว้กับสถานะของผู้ให้บริการก่อน แทนการสร้างการส่งใหม่ ใช้รูปแบบ outbox เมื่อสถานะของแอปพลิเคชันและการเผยแพร่เข้าคิวต้องเคลื่อนไปด้วยกัน และวาง uniqueness constraint รอบขอบเขต idempotency

ออกแบบการลองใหม่ตามประเภทของความล้มเหลว

แยกการตรวจสอบความถูกต้อง การอนุญาต การจำกัดอัตรา การปฏิเสธของผู้ให้บริการ ความล้มเหลวในการขนส่งชั่วคราว และความล้มเหลวในการส่งถึงผู้รับ ออกจากกัน อินพุตที่ไม่ถูกต้องและโดเมน From ที่ไม่ได้รับอนุญาตควรล้มเหลวโดยไม่ลองใหม่ rate limit ของผู้ให้บริการและข้อผิดพลาดชั่วคราวของบริการลองใหม่ได้ด้วย exponential backoff แบบมีขอบเขต jitter เพดานจำนวนครั้ง และ visibility timeout ของคิวที่นานกว่าเส้นตายของคำขอของ worker การหมดเวลาของเครือข่ายที่กำกวมต้องการการกระทบยอดที่คำนึงถึงการซ้ำ ไม่ใช่คำขอใหม่แบบไม่มีเงื่อนไข SMTP เองแยกการตอบกลับชั่วคราว 4xx และถาวร 5xx แต่แอปพลิเคชันที่ใช้ API ของผู้ให้บริการควรทำตามความหมายของข้อผิดพลาดที่ผู้ให้บริการระบุไว้ ย้ายงานที่ลองจนหมดไปยังสถานะ dead-letter ที่ตรวจสอบได้ และเก็บเหตุผลที่ทำความสะอาดแล้ว อย่าลองใหม่กับอีเมลตีกลับถาวรของผู้รับราวกับเป็น API ล่ม และอย่าเปลี่ยนการร้องเรียนให้เป็นความพยายามส่งอีกครั้ง

บันทึกการยอมรับและรับอีเวนต์การส่ง

เก็บตัวระบุข้อความของผู้ให้บริการทันทีหลังการยอมรับ และแมปกับ message ID ของแอปพลิเคชัน อีเวนต์ของผู้ให้บริการจึงอัปเดต resource ที่ถูกต้องได้ แม้รายงานการร้องเรียนปกปิดรายละเอียดผู้รับ ตัวอย่างเช่น Amazon SES แยกการส่งสำเร็จออกจากการส่งถึงเซิร์ฟเวอร์อีเมลของผู้รับ และสามารถเผยแพร่อีเวนต์ delivery, bounce, complaint, reject, delivery delay, rendering failure, open และ click ตรวจสอบความแท้จริงของ webhook ด้วยกลไกที่ผู้ให้บริการระบุ ตรวจสอบ schema อีเวนต์ กำจัดรายการซ้ำด้วยตัวระบุอีเวนต์ของผู้ให้บริการหรือ fingerprint ที่กำหนดได้ และอนุญาตให้ส่งอีเวนต์เดิมซ้ำโดยไม่เกิดผลข้างเคียงซ้ำ จัดเก็บ payload ดิบเฉพาะเมื่อจำเป็น โดยเข้ารหัส ควบคุมการเข้าถึง และจำกัด retention สถานะที่ normalize แล้วควรแยกผลลัพธ์ accepted, delivered-to-server, bounced, complained, delayed, rejected และ suppressed

ทำให้การระงับการส่งเป็นการควบคุมในขณะส่ง

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

ปกป้องการส่งแบบชุดและโฟลว์ธุรกิจที่ละเอียดอ่อน

endpoint แบบชุดขยายผลกระทบของข้อผิดพลาดด้านการอนุญาตหรือการตรวจสอบเป็นทวีคูณ ให้ใช้การตรวจสอบความเป็นเจ้าของโดเมน การระงับการส่ง ขนาด และเนื้อหาเดียวกันกับทุกรายการ กำหนดความยาวชุดสูงสุดที่เข้มงวด และคืนผลลัพธ์รายรายการโดยไม่เปิดเผยข้อมูลของผู้เช่าอื่น rate limit ควรมีในระดับข้อมูลรับรอง เวิร์กสเปซ โดเมน และผู้ให้บริการ โดยควบคุม burst และปริมาณแบบเลื่อนแยกกัน ขีดจำกัดคำขอต่อวินาทีระดับโกลบอลเพียงอย่างเดียวไม่เพียงพอ เพราะคำขอหนึ่งอาจมีผู้รับจำนวนมาก ในเครื่องมือที่ขับเคลื่อนด้วยเอเจนต์ ให้กำหนดการยืนยันอย่างชัดเจนก่อนส่งชุดที่มีผลกระทบสูง แยกสิทธิ์ transactional และการตลาดเมื่อกฎการยินยอมและการปฏิบัติงานต่างกัน เฝ้าติดตามการเติบโตของผู้รับที่ผิดปกติ โดเมนที่ถูกปฏิเสธซ้ำ การเปลี่ยนแปลงของอีเมลตีกลับหรือการร้องเรียนที่สูง และการสร้าง key อย่างรวดเร็ว rate limit สนับสนุนความปลอดภัย แต่ไม่ได้แทนที่การยืนยันตัวตน การอนุญาตระดับอ็อบเจกต์ การยินยอมที่ยืนยันแล้ว หรือการตอบสนองต่อการละเมิด

ทดสอบเส้นทางความล้มเหลวก่อนใช้งานจริง

ใช้ตัวจำลองของผู้ให้บริการหรือกล่องจดหมายที่ควบคุมได้ เพื่อทดสอบการยอมรับ การส่งถึงเซิร์ฟเวอร์ผู้รับ hard bounce การร้องเรียน ความล่าช้า โดเมนไม่ถูกต้อง key ที่ถูกเพิกถอน การจำกัดอัตรา การหมดเวลาของผู้ให้บริการ webhook ซ้ำ และการส่งคิวซ้ำ ยืนยันว่า idempotency key เดียวกันสร้างข้อความของแอปพลิเคชันเพียงหนึ่งรายการ อีเวนต์ที่เล่นซ้ำไม่ก่อผลข้างเคียงซ้ำ และผู้เช่ารายหนึ่งอ่านหรือส่งด้วยโดเมนหรือรหัสข้อความของผู้เช่าอีกรายไม่ได้ ตรวจสอบข้อความจริงที่ได้รับสำหรับ From, Return-Path, DKIM, SPF, DMARC alignment การเรนเดอร์ข้อความและ HTML พฤติกรรมการยกเลิกการรับเมื่อเกี่ยวข้อง และลิงก์ ทดสอบโหลดคิวให้ต่ำกว่าขีดจำกัดของผู้ให้บริการที่ได้รับอนุมัติ และตรวจสอบ backpressure แทนที่จะข้ามไป เพิ่มการแจ้งเตือนสำหรับอายุคิว การลองใหม่ที่หมดแล้ว ความล้มเหลวในการรับอีเวนต์ ช่วงเผื่อโควตา การเปลี่ยนแปลงของอีเมลตีกลับและการร้องเรียน และ callback ของผู้ให้บริการที่หายไป เช็กลิสต์ก่อนเปิดตัวควรระบุเจ้าของสำหรับแต่ละการแจ้งเตือนและการดำเนินการกู้คืน

ใช้รูปแบบนี้กับ SendHQ อย่างระมัดระวัง

SendHQ มี bearer key ระดับเวิร์กสเปซ การตรวจสอบโดเมน From ที่ยืนยันแล้ว การสร้างข้อความเดี่ยวและแบบ batch กล่องจดหมายขาเข้า อีเวนต์ข้อความ และ resource การระงับการส่ง ฟีเจอร์เหล่านี้รองรับสถาปัตยกรรมในคู่มือนี้: เก็บ key ไว้ฝั่งเซิร์ฟเวอร์ สร้าง message resource เก็บ ID ของมัน และอ่านอีเวนต์ภายหลัง แทนการถือว่า response แรกคือการส่งถึงขั้นสุดท้าย ไม่ว่าแพลตฟอร์มใด ผู้เรียกยังรับผิดชอบต่อผู้รับที่ตั้งใจไว้ อีเมลที่ชอบด้วยกฎหมายและผู้รับคาดหวัง ความถูกต้องของเนื้อหา และการอนุมัติอย่างรอบคอบสำหรับการส่งที่มีผลสำคัญ

คำถามที่พบบ่อย

email API ควรส่งแบบซิงโครนัสจากคำขอเว็บหรือไม่

โดยปกติไม่ ให้สร้างข้อความของแอปพลิเคชันที่คงทนและใส่เข้าคิว แล้วให้ worker เรียกผู้ให้บริการ วิธีนี้แยกความหน่วง รองรับการลองใหม่แบบมีขอบเขต และทำให้กระทบยอดผลลัพธ์ที่กำกวมของผู้ให้บริการได้ง่ายขึ้น

ป้องกันอีเมลซ้ำเมื่อคำขอหมดเวลาได้อย่างไร

ใช้รหัสงานของแอปพลิเคชันที่คงที่และขอบเขต idempotency ที่มี uniqueness constraint เมื่อหมดเวลาแบบกำกวม ให้กระทบยอดงานที่มีอยู่ก่อนส่งให้ผู้ให้บริการอีกครั้งด้วยตัวตนใหม่

การตอบกลับ email API ที่สำเร็จหมายความว่าส่งถึงแล้วหรือไม่

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

email API ต้องใช้เรคคอร์ด DNS อะไรบ้าง

เรคคอร์ดที่แน่นอนขึ้นอยู่กับผู้ให้บริการ แต่การส่งในระบบจริงมักต้องมีการยืนยันโดเมนและ DKIM รวมถึงกลยุทธ์ SPF ที่ถูกต้อง และนโยบาย DMARC ที่ align กับสตรีมการส่งที่ถูกต้อง

ควรเก็บ API key ในโค้ดของเบราว์เซอร์หรือไม่

ไม่ ให้เก็บข้อมูลรับรองของเวิร์กสเปซและผู้ให้บริการไว้ในที่เก็บความลับฝั่งเซิร์ฟเวอร์ แฮช API key ของแอปพลิเคชันขณะจัดเก็บเมื่อเป็นไปได้ แสดงความลับฉบับสมบูรณ์เพียงครั้งเดียว และจัดให้มีเส้นทางเพิกถอนและหมุนเวียนอย่างรวดเร็ว

email API ควรจัดการอีเมลตีกลับถาวรอย่างไร

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

แหล่งอ้างอิง