31 คะแนน โดย hongminhee 2025-07-14 | 6 ความคิดเห็น | แชร์ทาง WhatsApp

สวัสดีครับ ผมลองสร้างไลบรารีสำหรับส่งอีเมลขึ้นมาเองแล้วนำมาแชร์ครับ

ทำไมถึงสร้างขึ้นมา?

ช่วงหลังมานี้ระหว่างทำหลายโปรเจกต์ ผมได้ใช้งานรันไทม์หลากหลายแบบ เช่น 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 ความคิดเห็น

 
davidshim 2025-08-13

เป็นโปรเจ็กต์ที่อ่านแล้วรู้สึกอิน เพราะเคยมีประสบการณ์ต้องเปลี่ยน API อยู่ 2~3 ครั้งเหมือนกันครับ ดูเหมือนว่าทั้งเว็บไซต์และเอกสารก็ทำออกมาได้สะอาดและดีมากด้วย ระหว่างที่ให้บริการจริง บางครั้งก็มีกรณีที่บริการอีเมลบางเจ้าใช้งานไม่ได้ จนต้องทำ failover ไปใช้บริการอีเมลเจ้าอื่น เลยคิดว่าน่าจะดีถ้ามีโค้ดสำหรับจัดการ transport ในลักษณะของ pool ด้วย ถ้ารองรับ resend.com ได้ด้วยก็น่าจะดีครับ ถ้าถึงตอนจะเอาไปใช้แล้วยังไม่มี ผมอาจจะลองเข้าไปช่วย contribute เองด้วยครับ~!

 
hongminhee 2025-08-13

ขอบคุณสำหรับฟีดแบ็กครับ! เราจะลองเพิ่ม PoolTransport กับ ResendTransport เร็วๆ นี้ครับ!

 
nemorize 2025-07-15

ลองเปลี่ยนสัญลักษณ์ “郵票” เป็น “แสตมป์” ดูไหมครับ?
ตอนนี้ก็สวยและลงตัวมากอยู่แล้ว เลยแอบพูดด้วยความระมัดระวังนิดนึงครับ..

 
zinisuni 2025-07-15

โอ้~ ดีเลย~ เยี่ยมๆ

 
cgl00 2025-07-15

เป็นโปรเจกต์ของคนเดียวเหรอครับ?? สุดยอดจริง ๆ นะครับ..

 
hongminhee 2025-07-15

ใช่ครับ ตอนนี้ผมยังทำมันคนเดียวอยู่ 😅