Sending Transactional Email from Node.js with fetch and Piisend
Learn how to send transactional emails from your Node.js applications using the native fetch API and Piisend's robust REST API. This guide covers basic email sending, error handling, and using templates for developers.
Section 1
Why Use Node.js fetch for Transactional Emails?
The native fetch API in Node.js provides a modern, promise-based way to make HTTP requests without external libraries. When combined with Piisend's transactional email API, it offers a streamlined and efficient method for developers to send critical emails like OTPs, password resets, and order confirmations. This approach simplifies your dependency management while ensuring reliable email delivery for your Node.js applications.
Section 2
Sending Your First Transactional Email with Node.js fetch
The fetch API in Node.js allows you to send transactional emails by making a POST request to the Piisend email API endpoint. You must include your Authorization header with a Bearer token and set the Content-Type to application/json. The request body specifies recipients, subject, and the email content. This example demonstrates a complete function for sending a basic HTML email and handling its response.
1async function sendBasicEmail(recipientEmail, subject, htmlContent, textContent) {2 const apiKey = "YOUR_API_KEY";3 try {4 const response = await fetch("https://api.piisend.com/api/v1/emails", {5 method: "POST",6 headers: {7 "Authorization": `Bearer ${apiKey}`,8 "Content-Type": "application/json"9 },10 body: JSON.stringify({11 to: [recipientEmail],12 subject: subject,13 html: htmlContent,14 text: textContent15 })16 });17 18 if (response.ok) {19 const data = await response.json();20 console.log("Email sent successfully. Message ID:", data.message_id);21 return data;22 } else {23 const errorData = await response.json();24 console.error("Failed to send email:", response.status, errorData);25 throw new Error(`Piisend API error: ${response.status} - ${errorData.error || JSON.stringify(errorData)}`);26 }27 } catch (error) {28 console.error("Network or unexpected error:", error);29 throw error;30 }31}32 33// Example usage:34// sendBasicEmail(35// "user@example.com",36// "Your Order Confirmation",37// "<h1>Thank you for your order!</h1><p>Your order #123 has been confirmed.</p>",38// "Thank you for your order! Your order #123 has been confirmed."39// );Section 3
Leveraging Email Templates for Dynamic Content
For consistent branding and dynamic content, Piisend supports sending emails using pre-defined templates. Instead of providing html and text directly, you specify a template_id and pass an object of template_vars. These variables will be merged into your template, allowing for personalized emails like password reset links or OTP verification codes without embedding logic in your application.
1async function sendTemplatedEmail(recipientEmail, templateId, templateVars) {2 const apiKey = "YOUR_API_KEY";3 try {4 const response = await fetch("https://api.piisend.com/api/v1/emails", {5 method: "POST",6 headers: {7 "Authorization": `Bearer ${apiKey}`,8 "Content-Type": "application/json"9 },10 body: JSON.stringify({11 to: [recipientEmail],12 template_id: templateId,13 template_vars: templateVars14 })15 });16 17 if (response.ok) {18 const data = await response.json();19 console.log("Templated email sent successfully. Message ID:", data.message_id);20 return data;21 } else {22 const errorData = await response.json();23 console.error("Failed to send templated email:", response.status, errorData);24 throw new Error(`Piisend API error: ${response.status} - ${errorData.error || JSON.stringify(errorData)}`);25 }26 } catch (error) {27 console.error("Network or unexpected error:", error);28 throw error;29 }30}31 32// Example usage:33// sendTemplatedEmail(34// "user@example.com",35// "welcome_email_template",36// {37// "user_name": "Alice",38// "login_link": "https://app.example.com/login"39// }40// );Section 4
Preventing Duplicate Emails with Idempotency Keys
In distributed systems, network issues can sometimes lead to duplicate API requests. To prevent sending the same transactional email multiple times, Piisend supports idempotency. By including a unique Idempotency-Key header with each request, you ensure that even if the request is retried, the email is processed only once. This is crucial for critical emails like OTPs or order confirmations, enhancing the reliability of your email for developers.
1async function sendIdempotentEmail(recipientEmail, subject, htmlContent, idempotencyKey) {2 const apiKey = "YOUR_API_KEY";3 try {4 const response = await fetch("https://api.piisend.com/api/v1/emails", {5 method: "POST",6 headers: {7 "Authorization": `Bearer ${apiKey}`,8 "Content-Type": "application/json",9 "Idempotency-Key": idempotencyKey // Unique key for this request10 },11 body: JSON.stringify({12 to: [recipientEmail],13 subject: subject,14 html: htmlContent15 })16 });17 18 if (response.ok) {19 const data = await response.json();20 console.log("Idempotent email sent successfully. Message ID:", data.message_id);21 return data;22 } else {23 const errorData = await response.json();24 console.error("Failed to send idempotent email:", response.status, errorData);25 throw new Error(`Piisend API error: ${response.status} - ${errorData.error || JSON.stringify(errorData)}`);26 }27 } catch (error) {28 console.error("Network or unexpected error:", error);29 throw error;30 }31}32 33// Example usage:34// const uniqueRequestId = "order-123-confirmation-attempt-1"; // Generate a unique ID per logical send35// sendIdempotentEmail(36// "user@example.com",37// "Order #123 Confirmed",38// "<p>Your order has been confirmed!</p>",39// uniqueRequestId40// );