DEV Community

Oleg
Oleg

Posted on

This Automated Email Digest Saves Me Dozens of Hours Weekly

Every day, we open our inboxes to dozens of new emails.

But let’s be honest—not all of them get our full attention. It’s easy to miss something important in that flood of messages.

Now, imagine this: every morning, there’s just one message waiting for you—a simple summary of all the key emails from the past 24 hours.

Here’s how it works:

Email Digest Template

  • We gather up all the emails you received over the last day
  • Filter out only the ones that actually need your attention
  • Compile a brief, clear summary highlighting what matters and eliminating the noise
  • Send it to your preferred channel (Telegram, Slack, etc.)

Now, let’s walk through the steps.

First, we set up a scheduled trigger with the cron expression 0 8 * * *, meaning the scenario will run every day at 8:00 a.m. Additionally, we specify your time zone to ensure correct timing.

Schedule Node in Emeail Digest Template

Next, we need to retrieve all emails from the past day (since the last scenario execution). We use the “find email” node and set a filter following standard search operators. In this case, to get emails from the last 24 hours, we use the filter newer_than:24h.

Gmail Integration in Email Digest Template

Then, I added an optional JavaScript node to extract only the key information from the emails (such as subject, sender, and message text) and filter out messages based on specific keywords I don’t want to see (like emails from certain organizations, individuals, or known spam terms). Here’s the code:

/** u/CustomParams
{
  "messages": {
    "title": "Email Messages",
    "key": "messages",
    "description": "JSON array of email messages",
    "type": "string"
  },
  "exclude_keywords": {
    "title": "Exclude Keywords",
    "key": "exclude_keywords",
    "description": "Comma-separated list of keywords to exclude messages",
    "type": "string"
  }
}
*/

export default async function run({ data }) {
  const messages = JSON.parse(data.messages);
  const excludeKeywords = data.exclude_keywords ? data.exclude_keywords.split(',').map(keyword => keyword.trim()) : [];

  const extractedMessages = messages
    .filter(msg => {
      let bodyData = '';
      if (msg.payload.parts) {
        msg.payload.parts.forEach(part => {
          if (part.body && part.body.data) {
            bodyData += part.body.data;
          }
        });
      }

      const body = Buffer.from(bodyData, 'base64').toString('utf-8');
      return !excludeKeywords.some(keyword => body.includes(keyword));
    })
    .map(msg => {
      const subjectHeader = msg.payload.headers.find(header => header.name === "Subject");
      const fromHeader = msg.payload.headers.find(header => header.name === "From");

      let body = "No Body";
      if (msg.payload.parts) {
        const bodyPart = msg.payload.parts.find(part => part.mimeType === "text/plain");
        if (bodyPart && bodyPart.body && bodyPart.body.data) {
          body = Buffer.from(bodyPart.body.data, 'base64').toString('utf-8');
        }
      }

      return { subject: subjectHeader?.value || "No Subject", from: fromHeader?.value || "No Sender", body };
    });

  return { extractedMessages };
}
Enter fullscreen mode Exit fullscreen mode

After running this node, I receive a structured array of filtered, essential email data.

Then, I passed this array into a ChatGPT node with a prompt that categorizes the emails and specifies the response format:

`Use the following data from emails received over the past day:
{{$40.extractedMessages}}

Categorize the emails into the following categories, if applicable:

- Work or Meetings – work-related messages or meeting invitations.
- Newsletters and Updates – subscriptions to blogs, product updates, newsletters.
- Notifications – event reminders, updates, notifications.
- Confirmations and Receipts – order confirmations, payments, registrations.
- Promotions – marketing emails, discount offers, sales.

Ignore any emails that are clearly spam or irrelevant to the above categories. Group emails under their respective category using bullet points. Do not include categories with no emails. For each email, provide a concise summary in the format below:

📰 Newsletters and Updates:
Sender Name: Brief summary of key content.
🛒 Promotions:
Sender Name: Brief description of the promotion.
🔔 Notifications:
Sender Name: Brief description of the notification.
📅 Work or Meetings:
Sender Name: Brief description of the meeting invitation.
📄 Confirmations and Receipts:
Sender Name: Brief description of the confirmation.`
Enter fullscreen mode Exit fullscreen mode

Responses should be concise and grouped by category using bullet points. If there are no emails for a category, omit that category entirely.

Afterward, you can send the summarized message to your preferred channel! For convenience, I created three options in this example: Slack, Telegram, or Discord.

The Output of the Email Digest Automation

Cool, Right?

And remember, future modifications are entirely in your hands!

This simple automation will save you time and ensure you never miss a beat. Want this template? Check it out here!

Want to learn how to build complex systems like this on Latenode? Use this form to book a paid workshop with our manager. If you run an automation agency and are interested in Latenode’s features and partner program, please mention it in the same form to schedule a free call.

Top comments (0)