All articles
Build Guides

Automate Daily Slack Channel Summaries with n8n and Groq’s Free Tier

FDE Coach EditorialAugust 16, 202610 min read

What We’re Building

A fully automated daily digest pipeline. Every morning the workflow grabs all messages posted in a source Slack channel over the previous 24 hours, feeds the transcript to Groq’s free Mixtral 8x7B endpoint, and posts a structured summary into a dedicated #daily-summaries channel. Zero infrastructure cost, zero scheduled scripts to maintain.

Feature list:

  • Pulls yesterday’s messages from any public channel via the Slack Web API
  • Strips bot noise and formats threads into readable context
  • Summarizes with Groq’s free-tier Mixtral model (8,000 requests/day, 30 requests/minute)
  • Posts the digest as a clean Slack block with a date header and bulleted takeaways
  • Runs on a cron schedule inside n8n — no external cron job needed
  • Entirely visual; every step is inspectable and debuggable

Architecture Overview

Data flows top-to-bottom. The cron node fires at 8:00 UTC, the Slack node pulls raw messages, a Function node cleans and concatenates them, another Function node wraps the text in a summarization prompt, Groq returns the digest, and a final Slack node publishes it. Every component talks JSON; there’s no intermediate database or file system.

Prerequisites (All Free Tier)

ComponentWhat You NeedWhere to Get It
n8nRunning instance (cloud or self-hosted)n8n.io — free cloud tier gives 20 workflows and 500 executions/month
GroqAPI key for Mixtral 8x7Bconsole.groq.com — free tier includes 8k requests/day
SlackBot token with channels:history and chat:write scopesapi.slack.com/apps — create a new app, install to workspace
A Slack workspaceSource channel + target #daily-summaries channelYour existing workspace

All three services have generous free tiers that easily cover daily summarization for a busy channel.

Step 1: Create a Slack App and Grab a Token

Head to api.slack.com/apps and click Create New AppFrom scratch. Name it something like Daily Digest Bot and pick your workspace.

Under OAuth & Permissions, add these Bot Token Scopes:

channels:history
chat:write

Click Install to Workspace, authorize, and copy the Bot User OAuth Token (starts with xoxb-). You’ll also need the channel ID of your source channel. Right-click the channel in Slack → Copy link → the ID is the segment after /archives/ (e.g., C05ABCDEF). Do the same for your target #daily-summaries channel.

Step 2: Spin Up n8n and Add Slack Credentials

If you’re using n8n cloud, log in at app.n8n.cloud. For self-hosted, npx n8n gets you a local instance on port 5678.

Add your Slack credentials once so they’re reusable across workflows:

  1. Go to Settings → Credentials → Add Credential
  2. Choose Slack API
  3. Paste your Bot User OAuth Token
  4. Name it Slack Daily Digest Bot

Repeat for Groq:

  1. Add Credential → Groq
  2. Paste your Groq API key from console.groq.com/keys
  3. Name it Groq Free Tier

Step 3: Fetch Yesterday’s Messages from Slack

Add a Schedule Trigger node. Set it to daily at your preferred UTC hour (8:00 UTC catches end-of-day for US timezones).

Next, add a Slack node → Resource: ChannelOperation: Get History. Select your Slack Daily Digest Bot credential. For Channel ID, hardcode your source channel ID.

We need to calculate oldest and latest timestamps dynamically. Add a Function node before the Slack node with this code:

// Calculate yesterday's boundaries in Unix seconds
const now = new Date();
const startOfToday = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()));
const endOfYesterday = Math.floor(startOfToday.getTime() / 1000);
const startOfYesterday = endOfYesterday - 86400;

return {
  oldest: startOfYesterday,
  latest: endOfYesterday
};

Pass these as query parameters to the Slack node. In the Slack node’s Parameters, set Oldest to {{ $json.oldest }} and Latest to {{ $json.latest }}. Set Limit to 200 — if your channel exceeds that, you’ll need pagination (see Extensions).

Step 4: Shape the Raw JSON into a Prompt

Slack returns an array of message objects under messages. Add another Function node to clean and concatenate:

const messages = $input.all()[0].json.messages || [];

// Filter out bot messages and subtype noise
const humanMessages = messages.filter(m => {
  return !m.bot_id && !m.subtype;
});

// Reverse to chronological order, extract text
const lines = humanMessages.reverse().map(m => {
  const user = m.user || 'unknown';
  const text = m.text.replace(/<@(\w+)>/g, '@user').replace(/<!(\w+)>/g, '@channel');
  return `[${user}]: ${text}`;
});

const transcript = lines.join('\n');

return {
  transcript: transcript,
  messageCount: lines.length
};

Now build the prompt. Add a third Function node:

const transcript = $input.first().json.transcript;
const date = new Date(Date.now() - 86400000).toISOString().split('T')[0];

const systemPrompt = `You are a concise Slack digest writer. Given a transcript of messages from a team channel, produce a structured summary with:
- 1-2 sentence high-level overview
- Key decisions made
- Action items with assignees if mentioned
- Important announcements
- Links or references shared

Use bullet points. Keep it under 300 words.`;

const userPrompt = `Here is the transcript from ${date}:\n\n${transcript}\n\nProduce the daily digest.`;

return {
  system: systemPrompt,
  user: userPrompt,
  date: date
};

Step 5: Summarize with Groq’s Free Mixtral Endpoint

Add an HTTP Request node. Even though n8n has a native Groq node, the HTTP Request gives you finer control over the Mixtral model selection.

Configure it as:

  • Method: POST
  • URL: https://api.groq.com/openai/v1/chat/completions
  • Authentication: Header Auth, key Authorization, value Bearer {{ $credentials.groqApiKey }} (you’ll need to create a Header Auth credential or use an environment variable)

For simplicity, create a Header Auth credential:

  • Name: Groq API Key
  • Header Name: Authorization
  • Header Value: Bearer gsk_your_actual_key_here

Body (JSON):

{
  "model": "mixtral-8x7b-32768",
  "messages": [
    { "role": "system", "content": "{{ $json.system }}" },
    { "role": "user", "content": "{{ $json.user }}" }
  ],
  "temperature": 0.3,
  "max_tokens": 600
}

Add a final Function node to extract the summary text:

const completion = $input.first().json.choices[0].message.content;
return {
  summary: completion,
  date: $('Build Prompt').first().json.date
};

Step 6: Post the Digest Back to Slack

Add a Slack node → Resource: ChatOperation: Post Message. Select the same Slack credential. Channel ID is your #daily-summaries channel.

For the message, use Slack Block Kit for a clean look:

{
  "blocks": [
    {
      "type": "header",
      "text": {
        "type": "plain_text",
        "text": "📋 Daily Digest — {{ $json.date }}"
      }
    },
    {
      "type": "section",
      "text": {
        "type": "mrkdwn",
        "text": "{{ $json.summary }}"
      }
    },
    {
      "type": "context",
      "elements": [
        {
          "type": "mrkdwn",
          "text": "_Generated by Groq Mixtral 8x7B · Free tier_"
        }
      ]
    }
  ]
}

Note: n8n’s Slack node expects either a simple text field or blocks as a JSON array. Paste the above directly into the Blocks field.

Step 7: Activate the Workflow and Run It

Click Execute Workflow to test immediately. Check the execution log — you’ll see each node light up green and can inspect the JSON payload at every step.

Once it works, toggle Active to on. The cron trigger will fire daily. For production, set up error notifications: add a Slack node on the error output of the Groq HTTP Request to DM you if the API fails.

Extensions That Ship Value

Multi-channel aggregation. Duplicate the Slack fetch + clean nodes for multiple channels, merge the transcripts before the prompt node. One digest covering the entire org’s engineering chatter.

Pagination for high-volume channels. The Slack API returns max 200 messages per call. If your channel exceeds that, add a loop: check response_metadata.next_cursor, pass it back to the Slack node until exhausted. n8n’s Loop Over Items node handles this cleanly.

Thread-aware summaries. Slack’s conversations.replies endpoint pulls threaded messages. For each parent message with thread_ts, fetch the thread and inline it beneath the parent. This surfaces decisions buried in threads — often where the real work happens.

Sentiment and tone tagging. Extend the Groq prompt to classify each day’s sentiment (positive/neutral/tense) and flag any message that sounds like a blocker. A simple traffic-light emoji in the digest header gives leadership a one-glance pulse.

If you’re hungry for more automation patterns after this, the Build a Multi-Agent Research Assistant with Groq, Tavily, and a Free Planner guide shows how to chain Groq calls into a planning-execution loop. For code-review automation, Build a GitHub PR Review Bot That Comments on Diffs Using Groq and a Local Ollama Model walks through a similar free-tier stack applied to pull requests.

Common Pitfalls

Slack token scope errors. If the Slack node returns missing_scope, double-check you installed the app after adding scopes. Reinstall forces Slack to re-prompt for the new permissions.

Empty transcripts crashing Groq. If a channel had zero human messages yesterday, the prompt node passes an empty string. Add a guard in the prompt Function node: if transcript.length === 0, return a hardcoded fallback message like “No messages yesterday.” and skip the Groq call entirely using an IF node.

Groq rate limiting. The free tier allows 30 requests/minute. A single daily digest won’t hit this, but if you add multi-channel processing or re-run tests rapidly, you’ll see 429 errors. Space out Groq nodes with a Wait node (5 seconds) between calls.

n8n cloud execution timeouts. Free n8n cloud has a 30-second execution limit. The Groq Mixtral call typically returns in 5-15 seconds, but if your transcript is enormous (thousands of messages), token count bloats and response time climbs. Trim transcripts aggressively or split into chunks.

Timezone confusion. The Function node uses UTC. If your team spans timezones, adjust the oldest/latest calculation or add a user-configurable offset. A Slack slash command that lets users request “summarize last 8 hours” is a natural v2.

FAQ

Q: Can I use a different Groq model? A: Absolutely. Swap mixtral-8x7b-32768 for llama3-70b-8192 or gemma-7b-it in the HTTP Request body. All are free-tier eligible. Mixtral strikes the best speed/quality balance for summarization.

Q: What if my Slack channel has private threads? A: The bot can only read threads in channels it’s been added to. For private channels, you’ll need to invite the bot and add the groups:history scope.

Q: How do I debug a failed Groq call? A: In n8n’s execution log, click the Groq HTTP Request node. The Output tab shows the exact request body and the API’s error response. Common failures: invalid model name, missing auth header, or content filter triggers on the transcript.

Q: Can I schedule it for multiple times per day? A: Yes — add multiple Schedule Trigger nodes or use a cron expression like 0 8,14,20 * * * for 8 AM, 2 PM, and 8 PM UTC. Each execution is independent.

Q: How do I avoid summarizing weekends? A: Add an IF node after the cron trigger that checks new Date().getUTCDay() — if it’s 0 (Sunday) or 6 (Saturday), route to a NoOp node that ends the workflow.

If you’re thinking about how this kind of pipeline fits into a broader customer-facing automation practice, The FDE Weekly Rhythm: Embed, Ship, and Expand in a Customer Environment lays out the pattern for identifying, building, and iterating on exactly these high-leverage internal tools during an engagement.

#slack#automation#n8n#groq

Want to build like a Forward Deployed Engineer?

FDE Coach is a cohort-based program in frontend, backend, AWS, and AI. Build real products and get referred to 200+ hiring partners.

Explore the program

More build guides

August 15 · 0d left
Enroll Now