สวัสดีครับ ผมลองสร้างไลบรารีสำหรับส่งอีเมลขึ้นมาเองแล้วนำมาแชร์ครับ
ทำไมถึงสร้างขึ้นมา?
ช่วงหลังมานี้ระหว่างทำหลายโปรเจกต์ ผมได้ใช้งานรันไทม์หลากหลายแบบ เช่น Node.js, Deno, Bun เป็นต้น แต่ในส่วนของการส่งอีเมลนั้น ทุกครั้งก็มักต้องไปหาไลบรารีคนละตัว หรือไม่ก็ตั้งค่าใหม่อีกครั้ง ซึ่งค่อนข้างไม่สะดวก โดยเฉพาะใน Deno หรือ Bun ที่ไลบรารีส่งอีเมลสำหรับ Node.js มักทำงานได้ไม่สมบูรณ์
ด้วยเหตุนี้ ผมจึงสร้าง Upyo ขึ้นมาจากแนวคิดว่า ถ้ามีไลบรารีส่งอีเมลที่ “เขียนครั้งเดียวแล้วทำงานได้ทุกที่” ก็น่าจะดี
คุณสมบัติหลัก
ความเข้ากันได้แบบข้ามรันไทม์
ทำงานด้วยโค้ดเดียวกันได้บน Node.js, Deno, Bun และ edge functions โดยไม่ต้องมีการตั้งค่าที่ต่างกันตามรันไทม์หรือแก้โค้ดเพิ่มเติม
Zero dependency
โดยส่วนตัวผมไม่ค่อยชอบเวลามี dependency จำนวนมากพ่วงเข้ามา จึงทำให้ไลบรารีนี้เป็นแบบ zero dependency ตัวอย่างเช่น SMTP transport ก็ไม่ได้ใช้แพ็กเกจ smtp แต่พัฒนาขึ้นมาเองโดยตรง
API ที่เรียบง่าย
ตั้งใจออกแบบให้สามารถส่งอีเมลได้ในไม่กี่บรรทัดโดยไม่ต้องตั้งค่าซับซ้อน:
import { createMessage } from "@upyo/core";
import { MailgunTransport } from "@upyo/mailgun";
const message = createMessage({
from: "sender@example.com",
to: "recipient@example.com",
subject: "Hello from Upyo!",
content: { text: "อีเมลสั้นๆ ฉบับหนึ่ง" },
});
const transport = new MailgunTransport({
apiKey: process.env.MAILGUN_KEY,
domain: process.env.MAILGUN_DOMAIN,
});
const receipt = await transport.send(message);
ไม่ยึดติดกับผู้ให้บริการ
รองรับบริการอีเมลหลากหลาย เช่น SMTP, Mailgun, SendGrid และถึงจะเปลี่ยนผู้ให้บริการ โค้ดของแอปพลิเคชันก็ยังคงเดิมได้ เพียงแค่สลับ Transport เท่านั้น (ในเวอร์ชันถัดไปจะรองรับ Amazon SES ด้วย)
เป็นมิตรกับการทดสอบ
มี MockTransport ให้สำหรับทดสอบลอจิกอีเมลได้โดยไม่ต้องส่งอีเมลจริง ทำให้สามารถทดสอบระหว่างพัฒนาได้โดยไม่ต้องกังวลว่าจะเผลอส่งอีเมลจริงออกไป
ส่วนที่ยังขาดอยู่
- ใน SMTP transport ยังไม่ได้รองรับ STARTTLS
- บน edge functions ยังไม่รองรับ SMTP (ใช้ได้เฉพาะ transport ที่อิงกับ HTTP API)
- ยังอยู่ในช่วงเริ่มต้นของการพัฒนา จึงอาจมีการเปลี่ยนแปลง API ได้
ลองใช้งานดู
สามารถใช้งานได้บนรันไทม์หลายแบบ:
npm add @upyo/core @upyo/smtp
pnpm add @upyo/core @upyo/smtp
yarn add @upyo/core @upyo/smtp
deno add --jsr @upyo/core @upyo/smtp
bun add @upyo/core @upyo/smtp
แพ็กเกจ transport นอกจาก @upyo/smtp แล้ว ยังมี @upyo/mailgun, @upyo/sendgrid, @upyo/ses, @upyo/mock และมีแผนจะเพิ่มอีกในอนาคต
เอกสาร: https://upyo.org
โค้ด: https://github.com/dahlia/upyo
สรุปส่งท้าย
แม้จะเป็นโปรเจกต์ที่เริ่มต้นจากความต้องการส่วนตัว แต่ผมคิดว่าน่าจะเป็นประโยชน์กับคนที่กำลังเจอปัญหาคล้ายกัน จึงขอนำมาแชร์ครับ ตอนนี้ยังเป็นเวอร์ชัน 0.1.0 แต่ตั้งใจจะปรับปรุงอย่างต่อเนื่อง
ยินดีรับฟีดแบ็กหรือการมีส่วนร่วมเสมอครับ!
ชื่อ Upyo มาจากคำภาษาเกาหลีว่า “Upyo” ซึ่งหมายถึงแสตมป์ โดยตั้งใจให้สื่อถึงการส่งอีเมลเหมือนกับการส่งจดหมายด้วยแสตมป์
6 ความคิดเห็น
เป็นโปรเจ็กต์ที่อ่านแล้วรู้สึกอิน เพราะเคยมีประสบการณ์ต้องเปลี่ยน API อยู่ 2~3 ครั้งเหมือนกันครับ ดูเหมือนว่าทั้งเว็บไซต์และเอกสารก็ทำออกมาได้สะอาดและดีมากด้วย ระหว่างที่ให้บริการจริง บางครั้งก็มีกรณีที่บริการอีเมลบางเจ้าใช้งานไม่ได้ จนต้องทำ failover ไปใช้บริการอีเมลเจ้าอื่น เลยคิดว่าน่าจะดีถ้ามีโค้ดสำหรับจัดการ transport ในลักษณะของ pool ด้วย ถ้ารองรับ resend.com ได้ด้วยก็น่าจะดีครับ ถ้าถึงตอนจะเอาไปใช้แล้วยังไม่มี ผมอาจจะลองเข้าไปช่วย contribute เองด้วยครับ~!
ขอบคุณสำหรับฟีดแบ็กครับ! เราจะลองเพิ่ม
PoolTransportกับResendTransportเร็วๆ นี้ครับ!ลองเปลี่ยนสัญลักษณ์ “郵票” เป็น “แสตมป์” ดูไหมครับ?
ตอนนี้ก็สวยและลงตัวมากอยู่แล้ว เลยแอบพูดด้วยความระมัดระวังนิดนึงครับ..
โอ้~ ดีเลย~ เยี่ยมๆ
เป็นโปรเจกต์ของคนเดียวเหรอครับ?? สุดยอดจริง ๆ นะครับ..
ใช่ครับ ตอนนี้ผมยังทำมันคนเดียวอยู่ 😅