This workflow corresponds to n8n.io template #10922 — we link there as the canonical source.
This workflow follows the Agent → Google Sheets recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"name": "Track and Visualize Daily Moods with OpenAI, Wolfram Alpha, and Google Sheets",
"tags": [],
"nodes": [
{
"id": "8eccdbf8-3950-4660-bad1-d97a744341f2",
"name": "Webhook: Mood Input",
"type": "n8n-nodes-base.webhook",
"position": [
544,
832
],
"parameters": {
"path": "mood",
"options": {},
"httpMethod": "POST",
"responseMode": "responseNode"
},
"typeVersion": 2.1
},
{
"id": "9383f009-71d7-4146-ad93-5b1d1220ebf7",
"name": "Parse AI Response",
"type": "n8n-nodes-base.set",
"position": [
1120,
736
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "id-1",
"name": "valence",
"type": "number",
"value": "={{ JSON.parse($json.output).valence }}"
},
{
"id": "id-2",
"name": "energy",
"type": "number",
"value": "={{ JSON.parse($json.output).energy }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "05a99125-61a9-444f-a18d-21bf4b742113",
"name": "Prepare Data Fields",
"type": "n8n-nodes-base.set",
"position": [
1344,
736
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "id-1",
"name": "moodText",
"type": "string",
"value": "={{ $json.mood || $('Webhook: Mood Input').first().json.body.mood }}"
},
{
"id": "id-2",
"name": "userId",
"type": "string",
"value": "={{ $json.userId || $('Webhook: Mood Input').first().json.body.userId }}"
},
{
"id": "id-3",
"name": "valence",
"type": "number",
"value": "={{ $json.valence }}"
},
{
"id": "id-4",
"name": "energy",
"type": "number",
"value": "={{ $json.energy }}"
},
{
"id": "id-5",
"name": "createdAt",
"type": "string",
"value": "={{ $now.toISO() }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "9d4ed4b4-3fdf-4a02-9501-0bbf1766c8cb",
"name": "Create Wolfram Query",
"type": "n8n-nodes-base.set",
"position": [
1568,
736
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "id-1",
"name": "wolframQuery",
"type": "string",
"value": "=plot y = {{ $json.valence }} * x from x = 0 to 10"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "af63908c-0915-4286-997d-50610c8ec6d1",
"name": "Generate Mood Graph",
"type": "n8n-nodes-base.httpRequest",
"position": [
2144,
736
],
"parameters": {
"url": "https://api.wolframalpha.com/v1/simple",
"options": {
"response": {
"response": {
"responseFormat": "file"
}
}
},
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "appid",
"value": "<__PLACEHOLDER_VALUE__YOUR_WOLFRAMALPHA_APP_ID__>"
},
{
"name": "i",
"value": "={{ $('Create Wolfram Query').first().json.wolframQuery }}"
}
]
}
},
"typeVersion": 4.3
},
{
"id": "ce61267c-863e-4ce2-acc2-44fbbec5c123",
"name": "Log Mood to Google Sheet",
"type": "n8n-nodes-base.googleSheets",
"position": [
2368,
736
],
"parameters": {
"columns": {
"values": {
"energy": "={{ $('Prepare Data Fields').first().json.energy }}",
"userId": "={{ $('Prepare Data Fields').first().json.userId }}",
"valence": "={{ $('Prepare Data Fields').first().json.valence }}",
"feedback": "={{ $('AI: Generate Feedback').first().json.response }}",
"moodText": "={{ $('Prepare Data Fields').first().json.moodText }}",
"createdAt": "={{ $('Prepare Data Fields').first().json.createdAt }}",
"wolframQuery": "={{ $('Create Wolfram Query').first().json.wolframQuery }}"
}
},
"options": {},
"operation": "append",
"sheetName": "Sheet1",
"documentId": "<__PLACEHOLDER_VALUE__YOUR_GOOGLE_SHEET_ID__>"
},
"typeVersion": 4.2
},
{
"id": "e404fca8-8ce1-452c-a7dd-8614755f8c6b",
"name": "Return API Response",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
2592,
736
],
"parameters": {
"options": {},
"respondWith": "json",
"responseBody": "={\n \"mood\": \"{{ $('Prepare Data Fields').first().json.moodText }}\",\n \"valence\": {{ $('Prepare Data Fields').first().json.valence }},\n \"energy\": {{ $('Prepare Data Fields').first().json.energy }},\n \"wolframQuery\": \"{{ $('Create Wolfram Query').first().json.wolframQuery }}\",\n \"feedback\": \"{{ $('AI: Generate Feedback').first().json.response }}\",\n \"graph\": \"{{ $('Generate Mood Graph').first().binary.data.dataUrl }}\"\n}"
},
"typeVersion": 1.4
},
{
"id": "45bb5ad6-42e5-41d0-ab50-785bbb313900",
"name": "Webhook: History Request",
"type": "n8n-nodes-base.webhook",
"position": [
320,
1072
],
"parameters": {
"path": "history",
"options": {},
"httpMethod": "POST"
},
"typeVersion": 2.1
},
{
"id": "16c4e99c-fc86-4cdf-9e8c-8589e68125e0",
"name": "Get History from Sheet",
"type": "n8n-nodes-base.googleSheets",
"position": [
544,
1072
],
"parameters": {
"options": {},
"sheetName": "Sheet1",
"documentId": "<__PLACEHOLDER_VALUE__YOUR_GOOGLE_SHEET_ID__>"
},
"typeVersion": 4.2
},
{
"id": "d03f826e-bb96-4dc8-9ee9-593c76513102",
"name": "Create Time Series Query",
"type": "n8n-nodes-base.code",
"position": [
768,
1072
],
"parameters": {
"jsCode": "// Get all items from the previous node ('Get History from Sheet').\nconst allItems = $input.all();\n\n// Get the target userId and limit from the initial webhook trigger.\nconst webhookData = $('Webhook: History Request').first().json.body;\nconst targetUserId = webhookData.userId;\nconst limit = webhookData.limit || 30;\n\n// 1. Filter items for the target user.\n// NOTE: We check for 'userId' (correct) and 'userid' (from your sheet) to be safe.\nconst userItems = allItems.filter(item => {\n const currentUserId = item.json.userId || item.json.userid;\n return currentUserId === targetUserId;\n});\n\n// 2. Sort items by createdAt descending to get the most recent ones.\nconst sortedDesc = userItems.sort((a, b) => new Date(b.json.createdAt) - new Date(a.json.createdAt));\n\n// 3. Limit to the specified number of records.\nconst limitedItems = sortedDesc.slice(0, limit);\n\n// 4. Sort again by createdAt ascending for the time series plot.\nconst sortedAsc = limitedItems.sort((a, b) => new Date(a.json.createdAt) - new Date(b.json.createdAt));\n\n// Format as time series data points for Wolfram Alpha.\nconst dataPoints = sortedAsc\n .filter(item => {\n const v = item.json.valence;\n return v !== null && v !== undefined && v !== '';\n })\n .map(item => {\n const date = new Date(item.json.createdAt);\n // IMPORTANT: Ensure the date is correctly formatted\n const dateStr = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;\n const valenceNum = parseFloat(item.json.valence);\n return `{\"${dateStr}\", ${valenceNum}}`;\n }).join(', ');\n\n// Create Wolfram Alpha time series plot query.\nconst wolframQuery = `time series plot {${dataPoints}}`;\n\n// Return the query string and the history data.\nreturn [{\n json: {\n wolframTimeSeriesQuery: wolframQuery,\n history: sortedAsc.map(i => i.json)\n }\n}];"
},
"typeVersion": 2
},
{
"id": "87887a97-3202-4b5a-952e-22e102aea84d",
"name": "Generate History Graph",
"type": "n8n-nodes-base.httpRequest",
"position": [
992,
1072
],
"parameters": {
"url": "https://api.wolframalpha.com/v1/simple",
"options": {
"response": {
"response": {
"responseFormat": "file"
}
}
},
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "appid",
"value": "<__PLACEHOLDER_VALUE__YOUR_WOLFRAMALPHA_APP_ID__>"
},
{
"name": "i",
"value": "={{ $json.wolframTimeSeriesQuery }}"
}
]
}
},
"typeVersion": 4.3
},
{
"id": "97e9edfc-b6f0-4e20-98de-925f9f1e7e63",
"name": "AI: Analyze Mood to Numbers",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
768,
640
],
"parameters": {
"text": "=# Instruction\nAnalyze the user's text and evaluate the valence (mood) and energy (vitality) of the emotion.\n\n# Constraints\n- You must act as an API and respond only in JSON format.\n- Valence is a number ranging from -1.0 to 1.0, where -1.0 is the most negative and 1.0 is the most positive.\n- Energy is a number ranging from 0.0 to 1.0, where 0.0 is the lowest energy and 1.0 is the highest.\n- Absolutely do not include explanations, preambles, or markdown like ```json ... ```. Output only a pure JSON object.\n\n# Example Output Format\n{ \"valence\": 0.8, \"energy\": 0.7 }\n\n# Text to Analyze\n{{ $json.mood || $('Webhook: Mood Input').first().json.body.mood }}",
"options": {},
"promptType": "define"
},
"typeVersion": 3
},
{
"id": "e2f0fb66-caca-499a-a5dd-1f9bea436793",
"name": "OpenAI Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
768,
800
],
"parameters": {
"model": "gpt-4o-mini",
"options": {}
},
"typeVersion": 1.2
},
{
"id": "ef72599f-e8fa-4961-8818-bffcd9917f39",
"name": "AI: Generate Feedback",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
1792,
736
],
"parameters": {
"text": "=You are an expert at analyzing a user's mood and providing brief advice. Based on the user's mood text and its quantified valence (brightness) and energy (vitality), generate a positive and short piece of advice in 1-2 sentences in English on how to spend their day.\n\n---\nUser Information:\nOriginal Mood Text: \"{{ $('Prepare Data Fields').first().json.moodText }}\"\nNumerical Analysis Results:\n- valence: {{ $('Prepare Data Fields').first().json.valence }}\n- energy: {{ $('Prepare Data Fields').first().json.energy }}\n---\n\nBased on this information, generate the advice.",
"options": {},
"promptType": "define"
},
"typeVersion": 3
},
{
"id": "d243908b-cd0c-4a8f-bb1e-a2ddbdc5e8f3",
"name": "OpenAI Chat Model1",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
1792,
896
],
"parameters": {
"model": "gpt-4o-mini",
"options": {}
},
"typeVersion": 1.2
},
{
"id": "182df94f-42ac-4394-9d1d-1b75d78677dc",
"name": "Manual Trigger",
"type": "n8n-nodes-base.manualTrigger",
"position": [
320,
640
],
"parameters": {},
"typeVersion": 1
},
{
"id": "7a14d6b7-9439-4d85-b845-1948763f93e9",
"name": "Set Test Data",
"type": "n8n-nodes-base.set",
"position": [
544,
640
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "5ed22629-60ca-4f8b-a325-93dc95d7445b",
"name": "mood",
"type": "string",
"value": "What a great day to build a workflow!"
},
{
"id": "b887a15f-3429-4faa-b33e-f3799b58afdb",
"name": "userId",
"type": "string",
"value": "n8n-user-123"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "efdcd499-5e33-4bed-8622-6228664c0c8b",
"name": "Mood Graph Studio",
"type": "n8n-nodes-base.stickyNote",
"position": [
0,
0
],
"parameters": {
"color": "#FBEB93",
"width": 1040,
"height": 592,
"content": "## Track and Visualize Daily Moods\nThis workflow analyzes your daily mood using OpenAI, visualizes it with Wolfram Alpha, and logs everything to Google Sheets. It also includes a feature to retrieve and graph your mood history.\n\n## How it works\n1. **Analyze**: An AI Agent quantifies your mood text into `valence` (positivity) and `energy`.\n2. **Graph**: Wolfram Alpha generates a linear graph based on these scores.\n3. **Feedback**: A second AI provides personalized advice.\n4. **Log**: All data is saved to Google Sheets.\n5. **History**: A separate flow fetches past data and posts a time-series graph to Slack.\n\n## Setup steps\n1. **Credentials**: Configure credentials for OpenAI, Google Sheets, and Slack in the respective nodes.\n2. **Wolfram Alpha**: Get a free App ID from the Developer Portal and paste it into the `appid` field in both `Generate...Graph` nodes.\n3. **Google Sheet**: Create a new Sheet and add its ID to both Google Sheets nodes.\n **Crucial**: The first row must have these exact headers:\n `userId`, `moodText`, `valence`, `energy`, `createdAt`, `wolframQuery`, `feedback`\n\n## How to Use\n- **Test**: Edit the \"Set Test Data\" node and click \"Execute Workflow\".\n- **Production**: Send a POST request to the `/mood` or `/history` webhook URLs."
},
"typeVersion": 1
},
{
"id": "ea201318-01da-4775-939f-bff6c9a797b8",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
112,
832
],
"parameters": {
"color": 7,
"width": 336,
"height": 176,
"content": "## 1. How to Start\nFor testing, edit `Set Test Data` and hit 'Execute Workflow'. For real use, send a POST request to the `/mood` webhook. The workflow is smart enough to handle both!"
},
"typeVersion": 1
},
{
"id": "9344e177-639f-4fcf-badc-105ccf826bdc",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
1088,
464
],
"parameters": {
"color": 7,
"width": 352,
"height": 176,
"content": "## 2. Analyze & Prep\nHere's where the magic starts. An AI quantifies your mood into scores. We then parse the response and gather all the data needed, like your `userId` and a timestamp."
},
"typeVersion": 1
},
{
"id": "34122569-d531-461d-a7a0-e73e884d6bf0",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1728,
464
],
"parameters": {
"color": 7,
"width": 336,
"content": "## 3. Generate Output\nA second AI writes you an encouraging message. At the same time, we build a query and send it to Wolfram Alpha, which returns your cool new mood graph."
},
"typeVersion": 1
},
{
"id": "41ddc8ed-166e-412c-95a0-242349fb1dab",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
2352,
480
],
"parameters": {
"color": 7,
"width": 352,
"height": 176,
"content": "## 4. Log & Respond\nTime to save our work. We log the complete record to your Google Sheet. If you used the webhook, we also send a JSON response back with all the analysis and a link to your graph."
},
"typeVersion": 1
},
{
"id": "0bcdfdfc-9df3-4fe0-87a0-2630a42452ac",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
96,
1264
],
"parameters": {
"color": 6,
"width": 352,
"height": 208,
"content": "## 5. History Graph Flow\nThis separate flow looks back at your mood history. Triggered by a POST request to `/history`, it fetches your data, builds a query, and posts a time-series graph to Slack."
},
"typeVersion": 1
},
{
"id": "5a2bdb8b-6a75-4b44-acd8-8152c0efd00e",
"name": "Upload a file",
"type": "n8n-nodes-base.slack",
"position": [
1200,
1072
],
"parameters": {
"options": {},
"resource": "file"
},
"typeVersion": 2.3
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "",
"connections": {
"Set Test Data": {
"main": [
[
{
"node": "AI: Analyze Mood to Numbers",
"type": "main",
"index": 0
}
]
]
},
"Manual Trigger": {
"main": [
[
{
"node": "Set Test Data",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Chat Model": {
"ai_languageModel": [
[
{
"node": "AI: Analyze Mood to Numbers",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Parse AI Response": {
"main": [
[
{
"node": "Prepare Data Fields",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Chat Model1": {
"ai_languageModel": [
[
{
"node": "AI: Generate Feedback",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Generate Mood Graph": {
"main": [
[
{
"node": "Log Mood to Google Sheet",
"type": "main",
"index": 0
}
]
]
},
"Prepare Data Fields": {
"main": [
[
{
"node": "Create Wolfram Query",
"type": "main",
"index": 0
}
]
]
},
"Webhook: Mood Input": {
"main": [
[
{
"node": "AI: Analyze Mood to Numbers",
"type": "main",
"index": 0
}
]
]
},
"Create Wolfram Query": {
"main": [
[
{
"node": "AI: Generate Feedback",
"type": "main",
"index": 0
}
]
]
},
"AI: Generate Feedback": {
"main": [
[
{
"node": "Generate Mood Graph",
"type": "main",
"index": 0
}
]
]
},
"Generate History Graph": {
"main": [
[
{
"node": "Upload a file",
"type": "main",
"index": 0
}
]
]
},
"Get History from Sheet": {
"main": [
[
{
"node": "Create Time Series Query",
"type": "main",
"index": 0
}
]
]
},
"Create Time Series Query": {
"main": [
[
{
"node": "Generate History Graph",
"type": "main",
"index": 0
}
]
]
},
"Log Mood to Google Sheet": {
"main": [
[
{
"node": "Return API Response",
"type": "main",
"index": 0
}
]
]
},
"Webhook: History Request": {
"main": [
[
{
"node": "Get History from Sheet",
"type": "main",
"index": 0
}
]
]
},
"AI: Analyze Mood to Numbers": {
"main": [
[
{
"node": "Parse AI Response",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow, "Mood Graph Studio," offers a comprehensive solution to track and visualize your emotional well-being. By simply inputting a single sentence about your mood, this template uses AI to perform a sentiment analysis, generates a visual graph via Wolfram Alpha,…
Source: https://n8n.io/workflows/10922/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This n8n workflow orchestrates a powerful suite of AI Agents and automations to manage and optimize various aspects of an e-commerce operation, particularly for platforms like Shopify. It leverages La
This workflow automates the creation and publishing of LinkedIn posts with AI-generated content and human approval via Slack, using Google Sheets, OpenAI (GPT-4), Slack Interactive Messages, and the L
🧾 Short Description
This workflow automates legislative compliance analysis by coordinating multiple specialized OpenAI agents to interpret regulatory documents, evaluate organizational impact, and manage stakeholder com
[](https://www.youtube.com/watch?v=NAn5BSr15Ks) > This workflow connects a Slack chatbot with AI agents and Google Sheets to automate candidate resume evaluation. It extracts resume details, identi