การส่งอีเมล
ภาพรวม
ระบบต้องส่งอีเมลให้ผู้ใช้งาน CMS ใน 2 กรณี คือ การรีเซ็ตรหัสผ่าน และ
การตั้งรหัสผ่านครั้งแรกสำหรับบัญชีที่เพิ่งถูกสร้าง การส่งจริงถูกแยกออกไปทำในคิว email
เพื่อไม่ให้ SMTP ที่ตอบสนองช้ามาถ่วงเวลาตอบกลับของ API
Consumer ตัวนี้มีพฤติกรรมเฉพาะที่ถูกยกมาจากระบบเดิมแบบตรงตัว กล่าวคือ หากการส่งอีเมลล้มเหลว ระบบจะกลืนข้อผิดพลาดและ ack ข้อความเสมอ ไม่มีการ retry และไม่เข้า DLQ ในทางกลับกัน payload ที่ parse ไม่สำเร็จจะ ไม่ถูก ack และจะถูกส่งกลับมาใหม่
Business Flow
- รับ payload ที่ประกอบด้วยอีเมลปลายทาง, รหัสยืนยัน, วันหมดอายุทั้งในรูปแบบวันที่และข้อความ และธงระบุว่าเป็นบัญชีใหม่หรือไม่
- หาก unmarshal ไม่สำเร็จ ระบบจะบันทึก log แล้วส่ง error กลับ ทำให้ชั้น mq ไม่ ack และข้อความจะถูกส่งกลับมาใหม่ในรอบถัดไป พฤติกรรมนี้ตรงกับระบบเดิมที่การ parse JSON อยู่นอกบล็อก try จึง throw ก่อนถึงบรรทัด ack
- หากอีเมลปลายทางว่าง จะไม่ดำเนินการใดและ ack ข้อความทิ้ง
- ประกอบพารามิเตอร์สำหรับ template และสร้างลิงก์รีเซ็ตรหัสผ่านในรูปแบบ
${BASE_CONSOLE_WEB_URL}/reset-password?token=${code} - เลือก template ตามธงบัญชีใหม่
- บัญชีใหม่ ใช้ template สำหรับตั้งรหัสผ่านครั้งแรก หัวข้อ "Create a login password"
- บัญชีเดิม ใช้ template รีเซ็ตรหัสผ่าน หัวข้อ "Reset password"
- หากส่งไม่สำเร็จ ระบบจะบันทึก log แล้วกลืนข้อผิดพลาด และ ack ข้อความเสมอ ตรงกับระบบเดิมที่เรียก ack ทั้งในบล็อก catch และที่บรรทัดสุดท้าย
ไฟล์และฟังก์ชันหลัก
| ไฟล์ | หน้าที่ |
|---|---|
internal/mailconsumer/consumer.go | Consumer.Handle ที่มีพฤติกรรมแยกระหว่างการ parse ล้มเหลวกับการส่งล้มเหลวตามที่อธิบายข้างต้น พร้อม Consumer.sendForgotPassword, Register, โครงสร้าง SendForgotPasswordPayload และ interface Mailer โดย package doc อธิบายพฤติกรรม ack และ redelivery ไว้อย่างละเอียด |
internal/mailx/mailx.go | Mailer, New, SendForgotPassword, SendNewAccount และ ForgotPasswordParams |
cmd/worker/main.go | runMain — สร้าง mailer แล้วลงทะเบียน consumer เข้ากับ registrar |
คิวที่เกี่ยวข้อง: email ซึ่งชื่อมาจากตัวแปร RABBITMQ_QUEUE_SENDMAIL และมีค่าเริ่มต้นเป็น email
ทำงานบน profile main
จุดเชื่อมต่อกับ Service อื่น
- รับงานจาก cms-api-go ในโดเมน auth และ user ได้แก่ ฟีเจอร์ลืมรหัสผ่านและการเชิญผู้ใช้ใหม่
- SMTP — กำหนดค่าผ่านตัวแปรแวดล้อม
MAIL_SMTP_HOST,MAIL_SMTP_PORT,MAIL_SMTP_SECURE,MAIL_SMTP_USERNAME,MAIL_SMTP_PASSWORD,MAIL_SMTP_FROM_NAMEและMAIL_SMTP_FROM_EMAILADDRESS - ตัวแปรแวดล้อม
BASE_CONSOLE_WEB_URL— ใช้เป็นฐานของลิงก์รีเซ็ตรหัสผ่านที่ฝังในอีเมล - ไม่แตะฐานข้อมูล และไม่เรียก LINE API
- ข้อควรระวังตอน deploy — หากสร้าง mailer ไม่สำเร็จตอนบูต
runMainจะบันทึก log แล้ว return ทันที ส่งผลให้ profilemainไม่ start consumer ตัวใดเลย