תיעוד · מדריכים
איך שולחים מייל מ-Node.js
מאפס למייל שנמסר: התקנה, שליחה, טיפול בשגיאות, ובדיקה מה קרה להודעה. כל הדוגמאות כאן הורצו ועובדות.
נבדק ב-13 באוקטובר 2026 עם Node.js 22 והספרייה bul-email 0.1.3.
מה צריך לפני שמתחילים
- חשבון בבול (יש חבילה חינמית: 3,000 מיילים בחודש, עד 300 ביום).
- דומיין מאומת — הכתובת שממנה שולחים (
from) חייבת להיות מדומיין שאימתתם. בדשבורד: דומיינים ← מוסיפים את הדומיין ← מעתיקים את הרשומות ל-DNS. המצב משתנה ל"מאומת" לבד, אחרי שהרשומות מתפרסמות. - מפתח API — בדשבורד: מפתחות API ← מפתח חדש. המפתח מוצג פעם אחת בלבד; שומרים אותו במשתנה סביבה, לא בקוד.
- Node.js 18 ומעלה.
BUL_API_KEY=bul_live_xxxxxxxx1. התקנה
npm install bul-email2. שליחת מייל
import { Bul } from "bul-email";
const bul = new Bul({ apiKey: process.env.BUL_API_KEY });
const { id } = await bul.emails.send(
{
from: "החנות שלי <orders@example.co.il>",
to: ["dana@example.com"],
subject: "ההזמנה שלך התקבלה",
html: "<p>תודה! ההזמנה מספר 1234 בטיפול.</p>",
text: "תודה! ההזמנה מספר 1234 בטיפול.",
},
{ idempotencyKey: "order-1234" },
);
console.log("נשלח:", id);from— כתובת מהדומיין המאומת שלכם. אפשר עם שם תצוגה, כמו בדוגמה.htmlו-text— כדאי לשלוח את שתיהן. גרסת טקסט עוזרת לתוכנות דואר שלא מציגות HTML, וגם למסירה.idempotencyKey— מזהה ייחודי לפעולה (למשל מספר ההזמנה). אם אותה בקשה נשלחת שוב עם אותו מזהה (רשת שנפלה, ניסיון חוזר), המייל לא יישלח פעמיים. הספרייה גם מנסה שוב לבד בשגיאות רשת ובעומס, עם אותו מזהה.- התשובה מחזירה
id— המזהה של ההודעה בבול. שומרים אותו כדי לבדוק אחר כך מה קרה איתה.
3. טיפול בשגיאות
כל שגיאה מה-API היא BulError, עם קוד HTTP (status), קוד קבוע (code) והסבר בעברית (message):
import { Bul, BulError } from "bul-email";
const bul = new Bul({ apiKey: process.env.BUL_API_KEY });
try {
await bul.emails.send({ from: "orders@example.co.il", to: ["לא-כתובת"], subject: "בדיקה", text: "בדיקה" });
} catch (err) {
if (err instanceof BulError) {
console.log(err.status, err.code, err.message);
} else {
throw err;
}
}מה שהדוגמה הזו מדפיסה בפועל:
400 invalid_to כתובת מייל לא תקינה: לא-כתובתכדאי לבנות את הלוגיקה על code ולא על ההודעה. הרשימה המלאה של הקודים — בתיעוד.
4. מה קרה למייל?
עם ה-id שקיבלתם בשליחה:
const email = await bul.emails.get(id);
console.log(email.status); // למשל: "sending", ואחר כך "delivered"המצבים העיקריים: queued (התקבל), sending / sent (בדרך), delivered (שרת הנמען קיבל), bounced (חזר — הכתובת לא קיימת או לא מקבלת), complained (הנמען סימן כספאם), opened / clicked.
במקום לשאול שוב ושוב — אפשר לקבל את השינויים ב-webhook: בול שולחת בקשה לשרת שלכם בכל פעם שמייל נמסר, חוזר או נפתח.
5. בלי ספרייה: fetch
אותה שליחה, ישירות מול ה-API — עובד בכל סביבה שיש בה fetch:
const res = await fetch("https://bul.friman.app/v1/emails", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.BUL_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": "order-1234",
},
body: JSON.stringify({
from: "החנות שלי <orders@example.co.il>",
to: ["dana@example.com"],
subject: "ההזמנה שלך התקבלה",
html: "<p>תודה!</p>",
}),
});
console.log(res.status, await res.json());תשובה מוצלחת היא 202, עם המזהה של ההודעה:
202 { id: "cbfd3ed2-…", recipient: "dana@example.com" }טיפים
- מייל שיווקי (ניוזלטר, מבצע) — שולחים עם
kind: "marketing". בול מוסיפה לבד כותרת הסרה בלחיצה אחת, שספקי הדואר דורשים. בליkindההודעה נחשבת טרנזקציונית (קבלה, אימות, איפוס סיסמה). - כתובת שחזרה, שהתלוננה או שביקשה להסיר את עצמה — בול חוסמת לבד, ומייל אליה לא יוצא.
- מפתח API — רק בצד השרת. לעולם לא בקוד שרץ בדפדפן.
