Skip to main content

การส่งอีเมล

ภาพรวม

ระบบต้องส่งอีเมลให้ผู้ใช้งาน CMS ใน 2 กรณี คือ การรีเซ็ตรหัสผ่าน และ การตั้งรหัสผ่านครั้งแรกสำหรับบัญชีที่เพิ่งถูกสร้าง การส่งจริงถูกแยกออกไปทำในคิว email เพื่อไม่ให้ SMTP ที่ตอบสนองช้ามาถ่วงเวลาตอบกลับของ API

Consumer ตัวนี้มีพฤติกรรมเฉพาะที่ถูกยกมาจากระบบเดิมแบบตรงตัว กล่าวคือ หากการส่งอีเมลล้มเหลว ระบบจะกลืนข้อผิดพลาดและ ack ข้อความเสมอ ไม่มีการ retry และไม่เข้า DLQ ในทางกลับกัน payload ที่ parse ไม่สำเร็จจะ ไม่ถูก ack และจะถูกส่งกลับมาใหม่

Business Flow

  1. รับ payload ที่ประกอบด้วยอีเมลปลายทาง, รหัสยืนยัน, วันหมดอายุทั้งในรูปแบบวันที่และข้อความ และธงระบุว่าเป็นบัญชีใหม่หรือไม่
  2. หาก unmarshal ไม่สำเร็จ ระบบจะบันทึก log แล้วส่ง error กลับ ทำให้ชั้น mq ไม่ ack และข้อความจะถูกส่งกลับมาใหม่ในรอบถัดไป พฤติกรรมนี้ตรงกับระบบเดิมที่การ parse JSON อยู่นอกบล็อก try จึง throw ก่อนถึงบรรทัด ack
  3. หากอีเมลปลายทางว่าง จะไม่ดำเนินการใดและ ack ข้อความทิ้ง
  4. ประกอบพารามิเตอร์สำหรับ template และสร้างลิงก์รีเซ็ตรหัสผ่านในรูปแบบ ${BASE_CONSOLE_WEB_URL}/reset-password?token=${code}
  5. เลือก template ตามธงบัญชีใหม่
    • บัญชีใหม่ ใช้ template สำหรับตั้งรหัสผ่านครั้งแรก หัวข้อ "Create a login password"
    • บัญชีเดิม ใช้ template รีเซ็ตรหัสผ่าน หัวข้อ "Reset password"
  6. หากส่งไม่สำเร็จ ระบบจะบันทึก log แล้วกลืนข้อผิดพลาด และ ack ข้อความเสมอ ตรงกับระบบเดิมที่เรียก ack ทั้งในบล็อก catch และที่บรรทัดสุดท้าย

ไฟล์และฟังก์ชันหลัก

ไฟล์หน้าที่
internal/mailconsumer/consumer.goConsumer.Handle ที่มีพฤติกรรมแยกระหว่างการ parse ล้มเหลวกับการส่งล้มเหลวตามที่อธิบายข้างต้น พร้อม Consumer.sendForgotPassword, Register, โครงสร้าง SendForgotPasswordPayload และ interface Mailer โดย package doc อธิบายพฤติกรรม ack และ redelivery ไว้อย่างละเอียด
internal/mailx/mailx.goMailer, New, SendForgotPassword, SendNewAccount และ ForgotPasswordParams
cmd/worker/main.gorunMain — สร้าง 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 ทันที ส่งผลให้ profile main ไม่ start consumer ตัวใดเลย