Timesheet Report Generator with Markdown and Email

Overview

This workflow generates a beautifully formatted HTML timesheet report from sample timesheet data, complete with user avatars, grouped by user and task, with subtotals for each task. It demonstrates how to transform structured data into a professional markdown report, convert it to HTML, and optionally email it as an attachment. The workflow is ideal for teams that need to visualize and share timesheet data in a clean, readable format.

Workflow Steps

  1. On clicking 'execute' (Manual Trigger) — No auth. This is the manual trigger that starts the workflow when you click the "Execute Workflow" button in the n8n editor. Useful for testing and on-demand report generation.

  2. GetTimesheetRecords (Function Node) — No auth. This node contains hardcoded sample timesheet data for two users (User 1 - Lead Programmer and User 2 - Designer) with multiple tasks, dates, hours, notes, and avatar URLs. In a real scenario, you would replace this with a database query, API call, or Google Sheets lookup.

  3. SortElements (Item Lists) — No auth. Sorts the incoming timesheet records by three fields in order: UserName, TaskTitle, and date. This ensures the report groups data correctly by user and task in chronological order.

  4. GetImg (Item Lists) — No auth. Removes duplicate entries based on the UserAvatar field, keeping only one record per unique avatar URL. This prepares the data for fetching each user's avatar image only once.

  5. ImgBinary (HTTP Request) — No auth. Fetches each unique avatar URL as a binary file (image). The response format is set to "file" to store the image data as binary. This uses Gravatar URLs with different default styles (robohash, identicon).

  6. Merge2 (Merge) — No auth. Merges the sorted timesheet data (from SortElements) with the binary avatar images (from ImgBinary) by index. This combines each user's avatar image with their timesheet records for the report.

  7. CreateMDReport (Function Node) — No auth. This is the core of the workflow. It contains JavaScript code that:

    • Builds a markdown report with a custom HTML table style
    • Groups entries by user (with avatar embedded as base64)
    • Groups entries by task within each user
    • Creates a table with Date, Hours, and Task Description columns
    • Calculates and displays subtotals for each task
    • Adds a generation timestamp at the end
    • Returns the complete markdown string as mdreport
  8. Markdown (Markdown) — No auth. Converts the markdown report (from $json["mdreport"]) into HTML. Options include table support, simple line breaks, and a complete HTML document structure.

  9. Move Binary Data1 (Move Binary Data) — No auth. Converts the HTML report from JSON to binary format, setting the filename to "report.html" and MIME type to "text/html". This prepares the report for email attachment.

  10. Send Email (Email Send) — No auth (requires SMTP credentials). Currently disabled. Would send the HTML report as an email attachment with subject "TimeSheet report". The attachment is the binary data from the previous node.

Setup Instructions

  1. Prerequisites: You need an n8n instance (self-hosted or cloud).
  2. Replace Sample Data: The GetTimesheetRecords node contains hardcoded sample data. Replace this with your actual data source:
    • Use a Google Sheets node to fetch timesheet data
    • Use a PostgreSQL or MySQL node to query a database
    • Use an HTTP Request node to call an API
  3. Avatar Images: The workflow fetches avatars from Gravatar. If you use different avatar URLs, ensure they are publicly accessible or adjust authentication.
  4. Email Setup: To enable email sending, configure SMTP credentials in n8n's credentials manager and enable the Send Email node. You'll need an SMTP server (e.g., Gmail, SendGrid, or your company's mail server).
  5. Test: Click "Execute Workflow" to generate the report. Check the output of the Markdown node to see the HTML report.

Use Cases and Variations

  • Team Timesheet Reports: Replace sample data with your team's actual timesheet data from Google Sheets, Airtable, or a database.
  • Automated Weekly Reports: Add a Schedule Trigger (Cron) to run this workflow every Monday morning and email the report to managers.
  • Project Status Reports: Modify the JavaScript to include project names, status, or other metrics.
  • Invoice Generation: Adapt the report format to create HTML invoices with line items and totals.
  • Slack Integration: Instead of email, use a Slack node to post the report to a channel.
  • PDF Conversion: Add a HTML to PDF node (e.g., using a PDF generation service) to send PDF reports.
  • Multi-format Output: Output both HTML and plain text versions for different audiences.
10 nodesmanual triggerProductivity
Item ListsMarkdownFunctionEmail SendHTTP RequestMergeMove Binary Data

Workflow JSON

{
  "nodes": [
    {
      "name": "On clicking 'execute'",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        120,
        560
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "name": "SortElements",
      "type": "n8n-nodes-base.itemLists",
      "position": [
        480,
        560
      ],
      "parameters": {
        "options": {},
        "operation": "sort",
        "sortFieldsUi": {
          "sortField": [
            {
              "fieldName": "UserName"
            },
            {
              "fieldName": "TaskTitle"
            },
            {
              "fieldName": "date"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "name": "Markdown",
      "type": "n8n-nodes-base.markdown",
      "position": [
        1340,
        580
      ],
      "parameters": {
        "mode": "markdownToHtml",
        "options": {
          "tables": true,
          "noHeaderId": true,
// ... truncated (copy to see full JSON)

How to Import This Workflow

  1. 1Copy the workflow JSON above using the Copy Workflow JSON button.
  2. 2Open your n8n instance and go to Workflows.
  3. 3Click Import from JSON and paste the copied workflow.

Don't have an n8n instance? Start your free trial at n8nautomation.cloud

Related Templates

Telegram Bot TikTok Video Downloader (No Watermark)

Overview This workflow transforms your Telegram bot into a powerful TikTok video downloader without watermarks. When a user sends a TikTok link to the bot, it automatically validates the URL, fetches the video page, extracts the clean video URL, downloads the file, and sends it back to the user with statistics (views, likes, author). The entire process is handled seamlessly with real-time status updates and robust error handling. This is perfect for content curators, social media managers, or anyone who wants to save TikTok videos without watermarks directly from Telegram. The bot provides a smooth user experience with progress messages and clear error feedback. Workflow Steps Telegram Trigger (No auth) — Listens for incoming messages from Telegram users. Configured to receive only updates. This node requires a Telegram Bot Token set up in n8n credentials. Validate TikTok URL (No auth) — An IF node that checks if the received message contains in the text. Uses string contains operator with loose type validation. Routes valid URLs to the processing path and invalid ones to an error message. Send Invalid URL Message (Telegram API Key auth) — Sends a friendly error message to the user explaining they need to provide a valid TikTok link with examples. Uses the chat ID from the original trigger message. Send Chat Action (Telegram API Key auth) — Sends a "uploading video" chat action to show the user that the bot is processing their request. This provides visual feedback in the Telegram chat. Send Processing Message (Telegram API Key auth) — Sends a status message "⏳ Downloading video... Please wait!" to keep the user informed about the progress. Configure Variables (No auth) — A Set node that stores the video URL (trimmed) and chat ID as named variables for use in subsequent nodes. This ensures data persistence through the workflow. Get TikTok Page HTML (No auth) — An HTTP Request node that fetches the TikTok video page HTML. Uses browser-like headers (User-Agent, Accept, Accept-Language) to mimic a real browser request. Configured with a 30-second timeout and full response capture. On error, it continues to the error handling path. Extract Video URL (No auth) — A Code node running JavaScript that parses the HTML to find the script tag containing video metadata. Extracts the video URL (playAddr or downloadAddr), cookies, description, author, and statistics (plays, likes, comments). On error, it routes to the error handler. Download Video File (No auth) — An HTTP Request node that downloads the actual video file using the extracted URL. Includes cookies from the previous step, proper referrer header, and a 60-second timeout. Configured to return binary file data. On error, it routes to the error handler. Delete Process Notif (Telegram API Key auth) — Deletes the "Processing..." status message to clean up the chat after the video is ready. Uses the message ID from the earlier status message. Send Video to User (Telegram API Key auth) — Sends the downloaded video file to the user with a formatted caption showing the author, view count, and like count. Uses binary data mode for file upload. Format Error (No auth) — A Code node that captures error messages from failed nodes and formats them into a user-friendly error object with the chat ID for response. Send Error Message (Telegram API Key auth) — Sends a detailed error message to the user explaining possible reasons for failure (deleted video, invalid link, maintenance, restrictions) with HTML formatting. Setup Instructions Prerequisites Telegram Bot Token: Create a bot via @BotFather on Telegram and get your API token n8n Instance: Self-hosted or cloud n8n (n8n.io) Configuration Steps Telegram Credentials: In n8n, go to Credentials → New → Telegram API. Enter your bot token from BotFather Webhook Setup: The Telegram Trigger node automatically sets up a webhook URL. Make sure your n8n instance is publicly accessible or use a tunnel (ngrok) Test the Bot: Send any TikTok video link to your bot (e.g., ) Use Cases & Variations Primary Use Case Personal Video Archiving: Save your favorite TikTok videos without watermarks for offline viewing Content Curation: Collect videos for repurposing on other platforms Social Media Management: Download client videos for scheduling tools Possible Adaptations Add Multiple Platforms: Extend the workflow to support Instagram Reels, YouTube Shorts, or Twitter videos by adding additional validation and extraction logic Database Storage: Add a Google Sheets or Airtable node to log downloaded videos with metadata Admin Notifications: Add a second Telegram channel to notify you when someone downloads a video Rate Limiting: Implement user rate limiting using n8n's Wait node or a database Video Processing: Add FFmpeg or other processing nodes to convert formats or add watermarks Multi-language Support: Modify error messages and captions based on user language preferences

23 nodes

YouTube Video Summarizer with Telegram Notification

High-Level Summary This workflow automatically processes YouTube videos by fetching their transcripts, generating a structured AI-powered summary using OpenAI's GPT-4o-mini, and sending the summary along with video metadata to a Telegram chat. It is triggered via a webhook, making it easy to integrate with other tools or services (e.g., a browser extension, a form, or another automation). The workflow is ideal for content curators, researchers, or teams who want to quickly digest video content without watching the full video. Workflow Steps Webhook — Receives an incoming HTTP POST request containing a YouTube URL in the request body. This is the entry point of the workflow. (No auth) Get YouTube URL (Set node) — Extracts the field from the incoming webhook payload and stores it as a string variable for downstream use. (No auth) YouTube Video ID (Code node) — Runs a JavaScript function that parses the YouTube URL using a regex pattern to extract the 11-character video ID (supports both and formats). (No auth) Get YouTube Video (YouTube node) — Uses the extracted video ID to fetch video metadata (title, description, etc.) from the YouTube Data API v3. (OAuth2 — requires a Google Cloud project with YouTube Data API enabled) YouTube Transcript (Community node: ) — Fetches the transcript/captions for the video. This node requires the video ID (passed from the previous step). (No auth — uses public YouTube captions) Split Out (SplitOut node) — Splits the transcript array into individual items so each text segment can be processed separately. (No auth) Concatenate (Summarize node) — Concatenates all transcript text segments into a single string, separated by spaces, to prepare the full transcript for analysis. (No auth) gpt-4o-mini (OpenAI Chat Model node) — Configures the OpenAI language model (GPT-4o-mini) that will be used for summarization. (API Key auth — requires an OpenAI API key) Summarize & Analyze Transcript (LLM Chain node) — Sends the concatenated transcript to the GPT-4o-mini model with a detailed prompt asking for a structured summary with headers, bullet points, bold terms, and tables. The output is a markdown-formatted analysis. (No auth — uses the model configured in the previous node) Response Object (Set node) — Assembles the final output object containing: - : The AI-generated summary text - : An empty array (placeholder for future use) - : The video title from YouTube metadata - : The video description from YouTube metadata - : The YouTube video ID - : The original YouTube URL from the webhook (No auth) Respond to Webhook — Sends the assembled response object back to the original webhook caller (e.g., a browser extension or app). (No auth) Telegram — Sends a message to a specified Telegram chat containing the video title and the YouTube URL. (API Key auth — requires a Telegram Bot Token and chat ID) Setup Instructions To use this workflow, you will need the following accounts and credentials: OpenAI Account: Create an account at platform.openai.com and generate an API key. Add this as a credential in n8n under "OpenAI". Google Cloud Project: Enable the YouTube Data API v3 in your Google Cloud Console, create OAuth 2.0 credentials (Desktop app type), and add them in n8n under "YouTube OAuth2 API". Telegram Bot: Create a bot via @BotFather on Telegram to get a Bot Token. Find your chat ID (e.g., by messaging your bot and visiting ). Add the token as a credential in n8n under "Telegram API". Webhook URL: After activating the workflow, copy the production webhook URL (e.g., ). You will send POST requests to this URL with a JSON body like . Use Cases and Variations Content Curation: Automatically summarize long conference talks, tutorials, or webinars and share them with your team on Telegram. Research Assistant: Collect video transcripts and AI summaries for later reference or database storage. Browser Extension Integration: Pair this workflow with a browser extension that sends the current YouTube URL to the webhook when clicked. Variations: - Replace Telegram with Slack, Discord, or email notifications. - Store summaries in a Google Sheet or Airtable for a searchable archive. - Add a filter to skip videos shorter than a certain duration. - Use a different LLM (e.g., Claude, Gemini) by swapping the OpenAI node. - Add error handling to notify you if a video has no captions.

12 nodes

Daily Berlin Weather SMS Alert via Plivo

Daily Berlin Weather SMS Alert This workflow automatically sends an SMS message every morning at 9 AM with the current temperature in Berlin. It combines a scheduled trigger, a weather data API, and an SMS service to deliver a simple, useful notification straight to your phone. How It Works Cron (No auth) — Runs the workflow every day at 9:00 AM. The parameter is set to hour 9, with no specific minute (defaults to 0), so it fires once daily. OpenWeatherMap (API Key auth) — Fetches current weather data for the city of Berlin. The parameter is set to "berlin". An API key is required (stored as a credential). The node returns JSON data including the main temperature in Celsius. Plivo (Auth ID + Auth Token) — Sends an SMS using the Plivo SMS API. The parameter is an expression: It dynamically inserts the temperature value from the previous node. The recipient phone number is configured in the Plivo credential (or can be set in the node parameters if adjusted). Setup Instructions OpenWeatherMap: Create a free account at openweathermap.org and generate an API key. In n8n, add a new credential of type "OpenWeatherMap API" and paste your API key. Plivo: Sign up at plivo.com and obtain your Auth ID and Auth Token (found in the Plivo console). Also ensure you have a Plivo phone number that can send SMS. In n8n, add a credential of type "Plivo API" with these details. Cron: No setup required – just ensure the workflow is active. After configuring the credentials, the workflow will run automatically at 9 AM each day. You can change the city by editing the parameter in the OpenWeatherMap node, or modify the message text in the Plivo node. Use Cases & Variations Different city: Replace "berlin" with any other city name (e.g., "London", "Paris"). Multiple recipients: Duplicate the Plivo node or use a separate node per phone number. Weather conditions: Extend the message to include humidity, weather description (e.g., "Clear sky") by adding more expressions. Other triggers: Replace the Cron trigger with a webhook or manual trigger for on-demand checks. Alternative services: Swap OpenWeatherMap for another weather API, or use Twilio instead of Plivo for SMS. This template is an excellent starting point for learning how to combine scheduled triggers, API calls, and messaging services in n8n.

3 nodes

Ready to automate with n8n?

Get affordable managed n8n hosting with 24/7 support.