Streamlining Your Workflow: How to Generate and Send PDFs via AWS SES using Node.js

Streamlining Your Workflow: How to Generate and Send PDFs via AWS SES using Node.js

Many times, we find ourselves needing to generate a PDF from HTML content or plain text and then send it via AWS SES service. While it may seem complex at first, breaking down the process into individual requirements can make it easier to accomplish.

In this article, we will create a Node.js application from scratch and configure it to meet the requirements. Join me as we explore the process step by step.

First step First

Creating your node application

(1) Let's first start with the folder creation where our application will exist

mkdir SendPdf

cd SendPdf

(2) Creating the application

npm init -y


Let's now install all the required dependencies

npm i express aws-sdk cors body-parser pdfkit html-to-text@5.1.1 dotenv

Here's an explanation of the npm packages that are being installed with this command:

  • express: Express is a popular web application framework for Node.js that provides a set of features for building web applications and APIs. It's used in this project to handle incoming HTTP requests and generate HTTP responses.

  • aws-sdk: The AWS SDK for JavaScript is a collection of libraries that enables JavaScript developers to build applications that interact with Amazon Web Services (AWS). It's used in this project to send email using the AWS SES service.

  • cors: CORS (Cross-Origin Resource Sharing) is a mechanism that allows web pages to make AJAX requests to a different domain than the one that served the web page. It's used in this project to enable CORS for the HTTP endpoints exposed by the Express application.

  • body-parser: Body-parser is a middleware for Express that parses incoming request bodies in a middleware before your handlers, available under the req.body property.

  • pdfkit: pdfkit is a PDF generation library for Node.js that provides a set of high-level APIs for creating PDF documents programmatically.

  • html-to-text: html-to-text is a library that converts HTML to plain text. It's used in this project to convert the HTML content of the report into plain text, so that it can be added to the PDF document.

  • dotenv: dotenv is a zero-dependency module that loads environment variables from a .env file into process.env. It's used in this project to load sensitive information like AWS access keys and secret access keys from a local .env file so that they're not exposed in the code.

Creating the index file

Create an index.js file and add the following starter code, to get started with the basic server which can start listening to the request

Configuring the AWS

(1) Create a .env file and place your AWS credentials here

(2) Configure your AWS SDK in the index.js file. Place the below code just before the PORT assignment

Creating a function that can send a raw email along with the pdf

Place the above function anywhere in the code, this will be called from the post api which we will be writing below.

This code defines an async function called sendEmail that takes two parameters: pdfPath, which is the path to the PDF file that needs to be sent as an email attachment, and email, which is the recipient's email address.

The function first reads the contents of the PDF file using the fs.readFileSync function and stores the bytes in a variable called pdfBytes.

Then it generates a random boundary string that will be used to separate the different parts of the email message.

The function then creates the email message using a MIME format. It sets the Content-Type header to multipart/mixed with the boundary string, and specifies two parts: a text message that simply says "Here is the survey report you requested", and the PDF attachment.

The function then creates an object called params that contains the necessary information to send the email using Amazon SES (Simple Email Service). This includes the email message, the recipient's email address, and the sender's email address.

The function then adds a subject to the email by appending "Subject: Your Subject\n" before the email message.

Finally, the function sends the email using the ses.sendRawEmail method, which is a method provided by the AWS SDK for sending email messages. If there's an error while sending the email, the function sends an HTTP response containing the error message, otherwise, it sends a response with a status code of 200 to indicate that the email was sent successfully.

Creating the POST API where the real magic begins

The above endpoint is /generate_and_send_pdf, and it expects a request body containing a text field and an email field.

The function first creates HTML content using the request body and defines it as a string variable htmlContent.

Then it creates a new PDF document using the PDFDocument module from pdfkit, which is a popular module for generating PDF files in Node.js.

After that, it converts the HTML content to plain text using the fromString function imported from html-to-text node module and adds it to the PDF document using the doc.text() function.

Next, it creates a write stream to save the PDF file to a temporary location on the server using the fs.createWriteStream function.

The PDF document is then piped to the write stream using the doc.pipe(stream) function, and finally, the PDF document is ended using the doc.end() function.

The code listens for the finish event of the write stream and triggers the sendEmail function, which sends an email with the PDF attachment to the specified email address.

If there's an error while creating the write stream or sending the email, the code sends an HTTP response containing the error message.


Finally, if the above post API endpoint is hit with the required body parameters - text and email, the pdfkit is responsible for the pdf generation and aws ses is responsible for the email sending.

In this article, we went through a tutorial on generating a PDF from HTML and sending it via AWS SES using Node.js, specifically on AWS Lambda. We discussed the steps involved in setting up the environment, defining endpoints, and writing the code. We also explained the key concepts and methods used throughout the process. By following this guide, developers can easily implement this functionality in their projects.

Here is the link to the git repo for the implementation -