[テンプレート] - ダッシュボードチャット
上級
これは自動化ワークフローで、30個のノードを含みます。主にN8n, Set, Code, Merge, Webhookなどのノードを使用。 AIモデル使用ダッシュボード:LLMワークフローのトークン指標とコストを追跡
前提条件
- •HTTP Webhookエンドポイント(n8nが自動生成)
- •OpenAI API Key
使用ノード (30)
カテゴリー
-
ワークフロープレビュー
ノード接続関係を可視化、ズームとパンをサポート
ワークフローをエクスポート
以下のJSON設定をn8nにインポートして、このワークフローを使用できます
{
"id": "Yu2P4qvlbmpPT3mg",
"meta": {
"instanceId": "b35269c8495db354f1459fb10ec8f343e34cd6c71fb24a004bb668ccda72b4e6",
"templateCredsSetupCompleted": true
},
"name": "[Template] - Dashboard Chat",
"tags": [],
"nodes": [
{
"id": "85c930e9-cb8a-47ad-8082-5ae97c945b4b",
"name": "チャットメッセージ受信時",
"type": "@n8n/n8n-nodes-langchain.chatTrigger",
"position": [
-320,
1264
],
"webhookId": "09b95814-ef46-410f-adfb-7ef2683d499d",
"parameters": {
"public": true,
"options": {}
},
"typeVersion": 1.3
},
{
"id": "cbd8fb15-5cf0-4993-a5f5-c732496c3efe",
"name": "AIエージェント",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
-96,
1264
],
"parameters": {
"text": "=Réponds à ce message : \n{{ $json.chatInput }}\n",
"options": {},
"promptType": "define"
},
"typeVersion": 2.2
},
{
"id": "e0decd9d-dc72-4283-815b-08f79b1b33b9",
"name": "シンプルメモリ",
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"position": [
-48,
1456
],
"parameters": {},
"typeVersion": 1.3
},
{
"id": "522553ba-e4eb-42d9-ae80-d6de88577792",
"name": "付箋1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-416,
1648
],
"parameters": {
"color": 3,
"width": 1968,
"height": 464,
"content": "## 🧠 Mini Workflow — Token Tracking\n"
},
"typeVersion": 1
},
{
"id": "0f270c23-7f82-49b4-8bbb-4362d12fcd60",
"name": "OpenAI Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
-224,
1456
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4.1-mini"
},
"options": {}
},
"credentials": {
"openAiApi": {
"id": "Eyt0iPqZCLeZxqlC",
"name": "OpenAi account"
}
},
"typeVersion": 1.2
},
{
"id": "d36b0ff3-8367-4790-ae92-141df8205be1",
"name": "実行IDを取得",
"type": "n8n-nodes-base.set",
"position": [
272,
1440
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "3677fb1a-e0b3-4468-bd10-6250ee768329",
"name": "id",
"type": "string",
"value": "={{$execution.id}}"
},
{
"id": "44775e78-8260-4316-a358-39b8b941313e",
"name": "model",
"type": "string",
"value": "={{$('OpenAI Chat Model').params.model}}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "6f390583-909a-4ecd-822e-12feb703ff30",
"name": "モデル/トークン情報",
"type": "n8n-nodes-base.set",
"position": [
576,
1872
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "701dd054-2196-489d-8c9c-05d802ddf0d9",
"name": "model_name",
"type": "string",
"value": "={{ $('OpenAI Chat Model').params.model.value }}"
},
{
"id": "4ec60898-644f-46c4-9b14-a306c64c2da9",
"name": "completionTokens",
"type": "number",
"value": "={{ $json.data.resultData.runData['OpenAI Chat Model'][0].data.ai_languageModel[0][0].json.tokenUsage.completionTokens }}"
},
{
"id": "10c28ae4-4618-48c9-9787-63acd3fe66b3",
"name": "promptTokens",
"type": "number",
"value": "={{ $json.data.resultData.runData['OpenAI Chat Model'][0].data.ai_languageModel[0][0].json.tokenUsage.promptTokens }}"
},
{
"id": "41d5534d-dc94-4751-a233-446b039c3a43",
"name": "totalTokens",
"type": "number",
"value": "={{ $json.data.resultData.runData['OpenAI Chat Model'][0].data.ai_languageModel[0][0].json.tokenUsage.totalTokens }}"
},
{
"id": "ec0edb07-dabe-44fd-93df-a901838472c8",
"name": "executionId",
"type": "string",
"value": "={{ $json.id }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "a47a978e-c1aa-4f98-89b4-e25294ff9d63",
"name": "行を挿入2",
"type": "n8n-nodes-base.dataTable",
"position": [
496,
1440
],
"parameters": {
"columns": {
"value": {
"action": "={{ $('When chat message received').item.json.action }}",
"output": "={{ $('AI Agent').item.json.output }}",
"chatInput": "={{ $('When chat message received').item.json.chatInput }}",
"sessionId": "={{ $('When chat message received').item.json.sessionId }}",
"executionId": "={{ $json.id }}"
},
"schema": [
{
"id": "sessionId",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "sessionId",
"defaultMatch": false
},
{
"id": "action",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "action",
"defaultMatch": false
},
{
"id": "output",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "output",
"defaultMatch": false
},
{
"id": "chatInput",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "chatInput",
"defaultMatch": false
},
{
"id": "completionTokens",
"type": "number",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "completionTokens",
"defaultMatch": false
},
{
"id": "promptTokens",
"type": "number",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "promptTokens",
"defaultMatch": false
},
{
"id": "totalTokens",
"type": "number",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "totalTokens",
"defaultMatch": false
},
{
"id": "globalCost",
"type": "number",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "globalCost",
"defaultMatch": false
},
{
"id": "modelName",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "modelName",
"defaultMatch": false
},
{
"id": "executionId",
"type": "number",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "executionId",
"defaultMatch": false
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"dataTableId": {
"__rl": true,
"mode": "list",
"value": "GyHAqQLTtmZbynYI",
"cachedResultUrl": "/projects/E58XbkoO8SgET2Sl/datatables/GyHAqQLTtmZbynYI",
"cachedResultName": "Template - data"
}
},
"typeVersion": 1
},
{
"id": "7b0b70b9-5b36-4e36-b811-da21af4dbaae",
"name": "実行を取得",
"type": "n8n-nodes-base.n8n",
"position": [
352,
1872
],
"parameters": {
"options": {
"activeWorkflows": true
},
"resource": "execution",
"operation": "get",
"executionId": "={{ $json.executionId }}",
"requestOptions": {}
},
"credentials": {
"n8nApi": {
"id": "sqvLt8TzAknSm5NM",
"name": "n8n account 2"
}
},
"typeVersion": 1
},
{
"id": "cdd04485-cdbc-4015-85a1-fdd5c359f4f4",
"name": "スケジュールトリガー",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-320,
1872
],
"parameters": {
"rule": {
"interval": [
{
"field": "minutes",
"minutesInterval": 30
}
]
}
},
"typeVersion": 1.2
},
{
"id": "6552176e-15d3-4886-b8b8-f463d0c49e08",
"name": "行を取得",
"type": "n8n-nodes-base.dataTable",
"position": [
-96,
1872
],
"parameters": {
"filters": {
"conditions": [
{
"keyName": "modelName",
"condition": "isEmpty"
}
]
},
"operation": "get",
"returnAll": true,
"dataTableId": {
"__rl": true,
"mode": "list",
"value": "GyHAqQLTtmZbynYI",
"cachedResultUrl": "/projects/E58XbkoO8SgET2Sl/datatables/GyHAqQLTtmZbynYI",
"cachedResultName": "Template - data"
}
},
"typeVersion": 1
},
{
"id": "ca373635-6cc4-44e1-b4f5-d44ed3d487b1",
"name": "行を更新",
"type": "n8n-nodes-base.dataTable",
"position": [
1376,
1856
],
"parameters": {
"columns": {
"value": {
"modelName": "={{ $json.model_name }}",
"globalCost": "={{ $json.globalCost }}",
"totalTokens": "={{ $json.promptTokens }}",
"promptTokens": "={{ $json.promptTokens }}",
"completionTokens": "={{ $json.completionTokens }}"
},
"schema": [
{
"id": "sessionId",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "sessionId",
"defaultMatch": false
},
{
"id": "action",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "action",
"defaultMatch": false
},
{
"id": "output",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "output",
"defaultMatch": false
},
{
"id": "chatInput",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "chatInput",
"defaultMatch": false
},
{
"id": "completionTokens",
"type": "number",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "completionTokens",
"defaultMatch": false
},
{
"id": "promptTokens",
"type": "number",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "promptTokens",
"defaultMatch": false
},
{
"id": "totalTokens",
"type": "number",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "totalTokens",
"defaultMatch": false
},
{
"id": "globalCost",
"type": "number",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "globalCost",
"defaultMatch": false
},
{
"id": "modelName",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "modelName",
"defaultMatch": false
},
{
"id": "executionId",
"type": "number",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "executionId",
"defaultMatch": false
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"filters": {
"conditions": [
{
"keyName": "executionId",
"keyValue": "={{ $json.executionId }}"
}
]
},
"operation": "update",
"dataTableId": {
"__rl": true,
"mode": "list",
"value": "GyHAqQLTtmZbynYI",
"cachedResultUrl": "/projects/E58XbkoO8SgET2Sl/datatables/GyHAqQLTtmZbynYI",
"cachedResultName": "Template - data"
}
},
"typeVersion": 1
},
{
"id": "63788429-3fd4-423d-8b29-6b8d4101720e",
"name": "フィールドを編集",
"type": "n8n-nodes-base.set",
"position": [
-128,
992
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "95f26c22-8da0-4d86-91f5-ee633cc72e98",
"name": "today",
"type": "string",
"value": "={{ $today }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "a3372fa9-18a2-4152-891d-2e40faf0b31f",
"name": "行を挿入1",
"type": "n8n-nodes-base.dataTable",
"position": [
-304,
2256
],
"parameters": {
"columns": {
"value": {
"name": "={{ $json.name }}",
"promptTokensPrice": "={{ $json.promptTokensPrice }}",
"completionTokensPrice": "={{ $json.completionTokensPrice }}"
},
"schema": [
{
"id": "name",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "name",
"defaultMatch": false
},
{
"id": "promptTokensPrice",
"type": "number",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "promptTokensPrice",
"defaultMatch": false
},
{
"id": "completionTokensPrice",
"type": "number",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "completionTokensPrice",
"defaultMatch": false
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"dataTableId": {
"__rl": true,
"mode": "list",
"value": "5tsC5vulvGwYGS2g",
"cachedResultUrl": "/projects/E58XbkoO8SgET2Sl/datatables/5tsC5vulvGwYGS2g",
"cachedResultName": "Model - Price"
}
},
"typeVersion": 1
},
{
"id": "a61ae8a0-85a6-4e1f-b3ec-8f4248839816",
"name": "付箋",
"type": "n8n-nodes-base.stickyNote",
"position": [
-416,
2144
],
"parameters": {
"color": 5,
"width": 544,
"height": 272,
"content": "## 📊 LLM Pricing Table for n8n\n\n\n"
},
"typeVersion": 1
},
{
"id": "c89ef6c5-8b35-45d3-8e21-b54125323bee",
"name": "行を取得1",
"type": "n8n-nodes-base.dataTable",
"position": [
80,
992
],
"parameters": {
"operation": "get",
"returnAll": true,
"dataTableId": {
"__rl": true,
"mode": "list",
"value": "GyHAqQLTtmZbynYI",
"cachedResultUrl": "/projects/E58XbkoO8SgET2Sl/datatables/GyHAqQLTtmZbynYI",
"cachedResultName": "Template - data"
}
},
"typeVersion": 1
},
{
"id": "9f4069e9-1d31-455c-9d4c-782ff0857ba0",
"name": "フィールドを編集1",
"type": "n8n-nodes-base.set",
"position": [
-80,
2256
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "f52f1004-3bed-448b-9655-b6c61d238f57",
"name": "",
"type": "string",
"value": ""
}
]
}
},
"typeVersion": 3.4
},
{
"id": "c3c21917-4e60-4545-b524-2f5bb28789bf",
"name": "アイテムをループ",
"type": "n8n-nodes-base.splitInBatches",
"position": [
128,
1872
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "451c7483-b793-47d9-869b-695bea8771ab",
"name": "何もしない",
"type": "n8n-nodes-base.noOp",
"position": [
352,
1680
],
"parameters": {},
"typeVersion": 1
},
{
"id": "e9c3fa27-22b9-42f5-bf51-e51f78abbe94",
"name": "付箋2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-416,
912
],
"parameters": {
"color": 6,
"width": 1152,
"height": 256,
"content": "## Generate Dashboard"
},
"typeVersion": 1
},
{
"id": "a92b9155-33e0-4d53-8e48-7d6ccd48a433",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"position": [
-320,
992
],
"webhookId": "176f23d4-71b3-41e0-9364-43bea6be01d3",
"parameters": {
"path": "176f23d4-71b3-41e0-9364-43bea6be01d3",
"options": {},
"responseMode": "responseNode"
},
"typeVersion": 2.1
},
{
"id": "3ce8907e-c978-4769-942a-806cd7182351",
"name": "行を取得3",
"type": "n8n-nodes-base.dataTable",
"position": [
784,
1744
],
"parameters": {
"operation": "get",
"returnAll": true,
"dataTableId": {
"__rl": true,
"mode": "list",
"value": "5tsC5vulvGwYGS2g",
"cachedResultUrl": "/projects/E58XbkoO8SgET2Sl/datatables/5tsC5vulvGwYGS2g",
"cachedResultName": "Model - Price"
}
},
"typeVersion": 1
},
{
"id": "0d493cb2-d367-4eb7-968e-1b05e8e0dee5",
"name": "結合1",
"type": "n8n-nodes-base.merge",
"position": [
944,
1856
],
"parameters": {
"mode": "combine",
"options": {},
"advanced": true,
"mergeByFields": {
"values": [
{
"field1": "name",
"field2": "model_name"
}
]
}
},
"typeVersion": 3.2
},
{
"id": "4f7b3e8e-8b1b-4ccc-af0f-2371ca846d95",
"name": "JavaScriptコード1",
"type": "n8n-nodes-base.code",
"position": [
1152,
1856
],
"parameters": {
"jsCode": "// Parcours tous les items reçus\nreturn items.map(item => {\n // Récupération des valeurs depuis l'item\n const completionTokens = item.json.completionTokens || 0;\n const promptTokens = item.json.promptTokens || 0;\n const completionTokensPrice = item.json.completionTokensPrice || 0;\n const promptTokensPrice = item.json.promptTokensPrice || 0;\n\n // Calcul du coût global\n const globalCost = (completionTokens * completionTokensPrice) + (promptTokens * promptTokensPrice);\n\n // Retourner l'item avec globalCost ajouté\n return {\n json: {\n ...item.json,\n globalCost\n }\n };\n});\n"
},
"typeVersion": 2
},
{
"id": "a5c21eed-3dcf-4a38-a341-d8bc42aaaf22",
"name": "付箋3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-416,
1200
],
"parameters": {
"color": 4,
"width": 1104,
"height": 416,
"content": "## Chat Example :\n\n\n"
},
"typeVersion": 1
},
{
"id": "07c09e80-88a2-443b-bd8a-59db83d8c0a1",
"name": "何もしない1",
"type": "n8n-nodes-base.noOp",
"position": [
272,
1264
],
"parameters": {},
"typeVersion": 1
},
{
"id": "10c02d77-5179-44a5-a219-213921b41377",
"name": "JavaScriptコード",
"type": "n8n-nodes-base.code",
"position": [
288,
992
],
"parameters": {
"jsCode": "// === Calcul des KPI pour les conversations ===\nlet totalConversations = 0;\nlet totalCompletionTokens = 0;\nlet totalPromptTokens = 0;\nlet totalTokens = 0;\nlet totalCost = 0;\nlet sessions = new Set();\nlet modelUsage = {};\nlet conversationsParJour = [];\n\nfor (const item of items) {\n const data = item.json;\n\n totalConversations += 1;\n totalCompletionTokens += data.completionTokens || 0;\n totalPromptTokens += data.promptTokens || 0;\n totalTokens += data.totalTokens || 0;\n\n // Calcul du coût global si absent\n let globalCost = data.globalCost;\n if (globalCost === null || globalCost === undefined) {\n const completionTokensPrice = data.completionTokensPrice || 0;\n const promptTokensPrice = data.promptTokensPrice || 0;\n globalCost = (data.completionTokens || 0) * completionTokensPrice + (data.promptTokens || 0) * promptTokensPrice;\n }\n totalCost += globalCost;\n\n // Comptage des sessions uniques\n if (data.sessionId) sessions.add(data.sessionId);\n\n // Comptage messages par modèle\n const model = data.modelName || \"unknown\";\n if (!modelUsage[model]) modelUsage[model] = 0;\n modelUsage[model] += 1;\n\n // Tableau journalier\n if (data.createdAt) {\n const day = data.createdAt.split(\"T\")[0];\n let dayEntry = conversationsParJour.find(d => d.date === day);\n if (!dayEntry) {\n dayEntry = { date: day, count: 0, totalCost: 0, promptTokens: 0, completionTokens: 0 };\n conversationsParJour.push(dayEntry);\n }\n dayEntry.count += 1;\n dayEntry.totalCost += globalCost;\n dayEntry.promptTokens += data.promptTokens || 0;\n dayEntry.completionTokens += data.completionTokens || 0;\n }\n}\n\n// Tri par date\nconversationsParJour = conversationsParJour.sort((a, b) => a.date.localeCompare(b.date));\n\n// Moyennes\nconst avgTokensPerConversation = totalConversations > 0 ? (totalTokens / totalConversations).toFixed(2) : 0;\nconst avgCostPerConversation = totalConversations > 0 ? (totalCost / totalConversations).toFixed(6) : 0;\n\n// === Génération HTML ===\nconst html = `\n<!DOCTYPE html>\n<html lang=\"fr\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<title>Dashboard Conversations</title>\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js\"></script>\n<link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css\">\n<style>\n:root {\n --radius: 0.65rem;\n --background: #ffffff;\n --foreground: #000000;\n --card: #f8f9fa;\n --card-foreground: #000000;\n --primary: #3b82f6;\n --chart-conversations: #3b82f6;\n --chart-tokens-prompt: #3b82f6;\n --chart-tokens-completion: #10b981;\n --destructive: #ef4444;\n --muted: #9ca3af;\n --border: #e5e7eb;\n}\nbody.dark {\n --background: #0b142c;\n --foreground: #f1f5f9;\n --card: #1e293b;\n --card-foreground: #f1f5f9;\n --primary: #60a5fa;\n --chart-conversations: #60a5fa;\n --chart-tokens-prompt: #60a5fa;\n --chart-tokens-completion: #34d399;\n --destructive: #f87171;\n --muted: #64748b;\n --border: #334155;\n}\n * {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n }\n\n body {\n background: var(--background);\n color: var(--foreground);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n padding: 20px;\n transition: background-color 0.3s ease, color 0.3s ease;\n }\n\n .container {\n max-width: 1400px;\n margin: 0 auto;\n }\n\n .header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 40px;\n }\n\n .header h1 {\n font-size: 2.5rem;\n font-weight: 700;\n }\n\n .section-title-header {\n font-size: 2.5rem;\n font-weight: 600;\n margin-top: 40px;\n margin-bottom: 20px;\n display: flex;\n align-items: center;\n gap: 12px;\n }\n\n .section-title-header i {\n color: var(--chart-topup);\n font-size: 2.5rem;\n }\n\n .section-title {\n font-size: 1.5rem;\n font-weight: 600;\n margin-top: 40px;\n margin-bottom: 20px;\n display: flex;\n align-items: center;\n gap: 12px;\n }\n\n .section-title i {\n color: var(--primary);\n font-size: 1.75rem;\n }\n\n .kpi-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 1rem;\n margin-bottom: 30px;\n }\n\n .kpi-card {\n background: var(--card);\n border-radius: 0.625rem;\n padding: 20px;\n border: 1px solid var(--border);\n transition: background-color 0.3s ease, border-color 0.3s ease;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n }\n\n .kpi-value {\n font-size: 2rem;\n font-weight: 700;\n margin-bottom: 8px;\n color: var(--card-foreground);\n transition: color 0.3s ease;\n }\n\n .kpi-positive {\n color: var(--chart-investment);\n }\n\n .kpi-negative {\n color: var(--destructive);\n }\n\n .kpi-label {\n font-size: 0.875rem;\n color: var(--muted-foreground);\n transition: color 0.3s ease;\n }\n\n .charts-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(500px, 1fr));\n gap: 20px;\n margin-bottom: 30px;\n }\n\n .chart-container {\n background: var(--card);\n border-radius: 0.625rem;\n padding: 20px;\n border: 1px solid var(--border);\n transition: background-color 0.3s ease, border-color 0.3s ease;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n position: relative;\n height: 400px;\n }\n\n .chart-wrapper {\n position: relative;\n height: 100%;\n }\n\n .theme-toggle {\n display: flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n }\n\n .toggle-switch {\n width: 48px;\n height: 24px;\n background: var(--border);\n border-radius: 12px;\n position: relative;\n cursor: pointer;\n transition: background-color 0.3s ease;\n }\n\n .toggle-switch::after {\n content: '';\n position: absolute;\n width: 20px;\n height: 20px;\n background: var(--card);\n border-radius: 50%;\n top: 2px;\n left: 2px;\n transition: transform 0.3s ease;\n box-shadow: 0 1px 3px rgba(0,0,0,0.3);\n }\n\n body.dark .toggle-switch::after {\n transform: translateX(24px);\n }\n\n @media (max-width: 768px) {\n .kpi-grid {\n grid-template-columns: 1fr;\n }\n .charts-grid {\n grid-template-columns: 1fr;\n }\n .header {\n flex-direction: column;\n gap: 20px;\n }\n }\n\n</style>\n</head>\n<body class=\"dark\">\n<div class=\"container\">\n <div class=\"header\">\n <h1><i class=\"fas fa-comments\"></i> Dashboard Conversations</h1>\n <div class=\"theme-toggle\" onclick=\"toggleTheme()\">\n <span>🌙</span>\n <div class=\"toggle-switch\"></div>\n <span>☀️</span>\n </div>\n </div>\n\n <div class=\"section-title\"><i class=\"fas fa-wallet\"></i> Statistiques Clés</div>\n <div class=\"kpi-grid\">\n <div class=\"kpi-card\">\n <div class=\"kpi-value kpi-positive\">${totalConversations.toLocaleString('fr-FR')}</div>\n <div class=\"kpi-label\">Total Messages</div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-value kpi-positive\">${sessions.size.toLocaleString('fr-FR')}</div>\n <div class=\"kpi-label\">Sessions uniques</div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-value kpi-positive\">${totalTokens.toLocaleString('fr-FR')}</div>\n <div class=\"kpi-label\">Total Tokens</div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-value kpi-positive\">${avgTokensPerConversation}</div>\n <div class=\"kpi-label\">Tokens moyens par message</div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-value kpi-negative\">${totalCost.toFixed(6)} €</div>\n <div class=\"kpi-label\">Coût total</div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-value kpi-negative\">${avgCostPerConversation} €</div>\n <div class=\"kpi-label\">Coût moyen par message</div>\n </div>\n </div>\n\n <div class=\"section-title\"><i class=\"fas fa-chart-bar\"></i> Historique Journalier</div>\n <div class=\"charts-grid\">\n <div class=\"chart-container\"><div class=\"chart-wrapper\"><canvas id=\"conversationsChart\"></canvas></div></div>\n <div class=\"chart-container\"><div class=\"chart-wrapper\"><canvas id=\"tokensChart\"></canvas></div></div>\n </div>\n</div>\n\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js\"></script>\n<script>\nconst conversationsParJour = ${JSON.stringify(conversationsParJour)};\n\nlet charts = {};\n\nfunction getCSSVariable(varName){return getComputedStyle(document.documentElement).getPropertyValue(varName).trim();}\nfunction getThemeColors(){const isDark=document.body.classList.contains('dark'); return {textPrimary:isDark?'#f1f5f9':'#000', textSecondary:isDark?'#94a3b8':'#6b7280', gridColor:isDark?'rgba(148,163,184,0.1)':'rgba(0,0,0,0.1)', borderColor:isDark?'#475569':'#d1d5db', tooltip:isDark?'rgba(15,23,42,0.9)':'rgba(0,0,0,0.9)', chartColor:getCSSVariable('--chart-conversations'), chartPrompt:getCSSVariable('--chart-tokens-prompt'), chartCompletion:getCSSVariable('--chart-tokens-completion')}};\n\nfunction createChartOptions(label){\n const colors=getThemeColors();\n return {responsive:true, maintainAspectRatio:false, plugins:{title:{display:true,text:label,color:colors.textPrimary,font:{size:16,weight:'bold'},padding:20},legend:{display:true,position:'top'},tooltip:{backgroundColor:colors.tooltip,titleColor:'#ffffff',bodyColor:'#ffffff',borderColor:colors.borderColor,borderWidth:1,padding:12,displayColors:true}}, scales:{x:{grid:{display:true,color:colors.gridColor,drawBorder:false},ticks:{color:colors.textSecondary,font:{size:11}}},y:{grid:{display:true,color:colors.gridColor,drawBorder:false},ticks:{color:colors.textSecondary,font:{size:11}},beginAtZero:true}}};\n}\n\nfunction initCharts(){\n const colors=getThemeColors();\n const ctx=document.getElementById('conversationsChart').getContext('2d');\n charts.conversations=new Chart(ctx,{type:'bar',data:{labels:conversationsParJour.map(d=>new Date(d.date).toLocaleDateString('fr-FR',{day:'2-digit',month:'2-digit'})),datasets:[{label:'Nombre de messages',data:conversationsParJour.map(d=>d.count),backgroundColor:colors.chartColor,borderColor:colors.chartColor,borderWidth:0,borderRadius:6}]},options:createChartOptions('Messages journaliers')});\n\n // Graphique tokens empilé\n const ctxTokens=document.getElementById('tokensChart').getContext('2d');\n charts.tokens=new Chart(ctxTokens,{type:'bar',data:{labels:conversationsParJour.map(d=>new Date(d.date).toLocaleDateString('fr-FR',{day:'2-digit',month:'2-digit'})),datasets:[{label:'Prompt Tokens',data:conversationsParJour.map(d=>d.promptTokens),backgroundColor:colors.chartPrompt},{label:'Completion Tokens',data:conversationsParJour.map(d=>d.completionTokens),backgroundColor:colors.chartCompletion}]},options:{...createChartOptions('Tokens utilisés par jour'),scales:{x:{stacked:true,grid:{display:true,color:colors.gridColor,drawBorder:false},ticks:{color:colors.textSecondary,font:{size:11}}},y:{stacked:true,grid:{display:true,color:colors.gridColor,drawBorder:false},ticks:{color:colors.textSecondary,font:{size:11}},beginAtZero:true}}}});\n}\n\nfunction updateChartsTheme(){\n const colors=getThemeColors();\n if(charts.conversations){\n charts.conversations.data.datasets[0].backgroundColor=colors.chartColor;\n charts.conversations.data.datasets[0].borderColor=colors.chartColor;\n charts.conversations.options.plugins.title.color=colors.textPrimary;\n charts.conversations.options.scales.x.grid.color=colors.gridColor;\n charts.conversations.options.scales.x.ticks.color=colors.textSecondary;\n charts.conversations.options.scales.y.grid.color=colors.gridColor;\n charts.conversations.options.scales.y.ticks.color=colors.textSecondary;\n charts.conversations.options.plugins.tooltip.backgroundColor=colors.tooltip;\n charts.conversations.update();\n }\n if(charts.tokens){\n charts.tokens.data.datasets[0].backgroundColor=colors.chartPrompt;\n charts.tokens.data.datasets[1].backgroundColor=colors.chartCompletion;\n charts.tokens.options.plugins.title.color=colors.textPrimary;\n charts.tokens.options.scales.x.grid.color=colors.gridColor;\n charts.tokens.options.scales.x.ticks.color=colors.textSecondary;\n charts.tokens.options.scales.y.grid.color=colors.gridColor;\n charts.tokens.options.scales.y.ticks.color=colors.textSecondary;\n charts.tokens.options.plugins.tooltip.backgroundColor=colors.tooltip;\n charts.tokens.update();\n }\n}\n\nfunction toggleTheme(){document.body.classList.toggle('dark'); updateChartsTheme();}\ndocument.addEventListener('DOMContentLoaded',initCharts);\n</script>\n</body>\n</html>\n`;\n\n// Retourner le HTML en binaire pour la node n8n\nreturn [{ binary: { data: Buffer.from(html, 'utf8') } }];\n"
},
"typeVersion": 2
},
{
"id": "63aae3c1-6479-477f-a26b-85f3d589a6bc",
"name": "Webhookに応答",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
496,
992
],
"parameters": {
"options": {},
"respondWith": "binary"
},
"typeVersion": 1.4
},
{
"id": "b2f02fbb-2604-4f60-9449-6a8fa76ee670",
"name": "付箋4",
"type": "n8n-nodes-base.stickyNote",
"position": [
-976,
912
],
"parameters": {
"width": 496,
"height": 352,
"content": "## 🤖 n8n AI Workflow Dashboard\n\n### This template helps you collect and visualize data from your AI workflows in a simple and interactive way.\n\n- Track messages, sessions, tokens, and costs for each model.\n- Interactive HTML dashboard with KPIs: messages, sessions, tokens, and costs.\n- Compatible with any AI Agent or RAG workflow in n8n.\n\n### Use this dashboard to monitor AI activity and usage metrics at a glance, and easily identify trends or anomalies in your workflows."
},
"typeVersion": 1
},
{
"id": "19d31dbb-e89e-40c6-853d-f898ebbe1122",
"name": "付箋5",
"type": "n8n-nodes-base.stickyNote",
"position": [
-976,
1296
],
"parameters": {
"width": 496,
"height": 464,
"content": "## ⚙️ Setup & Run\n\n### Follow these steps to get your workflow up and running in n8n:\n\n- Import the JSON workflow into your n8n instance.\n- Create the Model price and Messages tables.\n- Import token cost data for your LLM models (LLM Pricing).\n- Configure the “chat message” node according to your input channels.\n- Once messages are collected, the Token Tracking sub-workflow calculates token usage and costs.\n- Visualize the dashboard using the HTML response returned by the webhook.\n\n### After setup, your workflow will automatically track AI activity, compute costs, and provide a live dashboard to monitor all your KPIs."
},
"typeVersion": 1
}
],
"active": true,
"pinData": {
"Edit Fields1": [
{
"json": {
"name": "claude-4.5-sonnet",
"promptTokensPrice": 0.000003,
"completionTokensPrice": 0.000015
}
},
{
"json": {
"name": "claude-4.5-sonnet-extended-context",
"promptTokensPrice": 0.000006,
"completionTokensPrice": 0.0000225
}
},
{
"json": {
"name": "gpt-5",
"promptTokensPrice": 0.00000125,
"completionTokensPrice": 0.00001
}
},
{
"json": {
"name": "gpt-5-mini",
"promptTokensPrice": 2.5e-7,
"completionTokensPrice": 0.000002
}
},
{
"json": {
"name": "gpt-5-nano",
"promptTokensPrice": 5e-8,
"completionTokensPrice": 4e-7
}
},
{
"json": {
"name": "Gemini-2.5-Pro",
"promptTokensPrice": 0.00000125,
"completionTokensPrice": 0.00000125
}
},
{
"json": {
"name": "Gemini-1.5-Flash",
"promptTokensPrice": 7.5e-7,
"completionTokensPrice": 0.000003
}
},
{
"json": {
"name": "gpt-4o",
"promptTokensPrice": 0.0000025,
"completionTokensPrice": 0.00001
}
},
{
"json": {
"name": "gpt-4o-mini",
"promptTokensPrice": 1.5e-7,
"completionTokensPrice": 6e-7
}
},
{
"json": {
"name": "gpt-4.1-mini",
"promptTokensPrice": 4e-7,
"completionTokensPrice": 0.0000016
}
},
{
"json": {
"name": "gpt-4.1-nano",
"promptTokensPrice": 1e-7,
"completionTokensPrice": 4e-7
}
},
{
"json": {
"name": "o3-mini",
"promptTokensPrice": 0.0000011,
"completionTokensPrice": 0.0000044
}
},
{
"json": {
"name": "Gemini-2.0-Flash-Lite",
"promptTokensPrice": 7.5e-8,
"completionTokensPrice": 3e-7
}
},
{
"json": {
"name": "DeepSeek-V3",
"promptTokensPrice": 2.7e-7,
"completionTokensPrice": 0.0000011
}
},
{
"json": {
"name": "Claude-3.7-Sonnet",
"promptTokensPrice": 0.000003,
"completionTokensPrice": 0.000015
}
},
{
"json": {
"name": "gpt-oss-20b",
"promptTokensPrice": 3e-8,
"completionTokensPrice": 1.4e-7
}
}
]
},
"settings": {
"executionOrder": "v1"
},
"versionId": "d1513dc9-185a-4183-bdcd-531b250483c3",
"connections": {
"0d493cb2-d367-4eb7-968e-1b05e8e0dee5": {
"main": [
[
{
"node": "4f7b3e8e-8b1b-4ccc-af0f-2371ca846d95",
"type": "main",
"index": 0
}
]
]
},
"a92b9155-33e0-4d53-8e48-7d6ccd48a433": {
"main": [
[
{
"node": "63788429-3fd4-423d-8b29-6b8d4101720e",
"type": "main",
"index": 0
}
]
]
},
"cbd8fb15-5cf0-4993-a5f5-c732496c3efe": {
"main": [
[
{
"node": "07c09e80-88a2-443b-bd8a-59db83d8c0a1",
"type": "main",
"index": 0
},
{
"node": "d36b0ff3-8367-4790-ae92-141df8205be1",
"type": "main",
"index": 0
}
]
]
},
"6552176e-15d3-4886-b8b8-f463d0c49e08": {
"main": [
[
{
"node": "c3c21917-4e60-4545-b524-2f5bb28789bf",
"type": "main",
"index": 0
}
]
]
},
"63788429-3fd4-423d-8b29-6b8d4101720e": {
"main": [
[
{
"node": "c89ef6c5-8b35-45d3-8e21-b54125323bee",
"type": "main",
"index": 0
}
]
]
},
"c89ef6c5-8b35-45d3-8e21-b54125323bee": {
"main": [
[
{
"node": "10c02d77-5179-44a5-a219-213921b41377",
"type": "main",
"index": 0
}
]
]
},
"3ce8907e-c978-4769-942a-806cd7182351": {
"main": [
[
{
"node": "0d493cb2-d367-4eb7-968e-1b05e8e0dee5",
"type": "main",
"index": 0
}
]
]
},
"a3372fa9-18a2-4152-891d-2e40faf0b31f": {
"main": [
[
{
"node": "9f4069e9-1d31-455c-9d4c-782ff0857ba0",
"type": "main",
"index": 0
}
]
]
},
"e0decd9d-dc72-4283-815b-08f79b1b33b9": {
"ai_memory": [
[
{
"node": "cbd8fb15-5cf0-4993-a5f5-c732496c3efe",
"type": "ai_memory",
"index": 0
}
]
]
},
"ca373635-6cc4-44e1-b4f5-d44ed3d487b1": {
"main": [
[
{
"node": "c3c21917-4e60-4545-b524-2f5bb28789bf",
"type": "main",
"index": 0
}
]
]
},
"d36b0ff3-8367-4790-ae92-141df8205be1": {
"main": [
[
{
"node": "a47a978e-c1aa-4f98-89b4-e25294ff9d63",
"type": "main",
"index": 0
}
]
]
},
"c3c21917-4e60-4545-b524-2f5bb28789bf": {
"main": [
[
{
"node": "451c7483-b793-47d9-869b-695bea8771ab",
"type": "main",
"index": 0
}
],
[
{
"node": "7b0b70b9-5b36-4e36-b811-da21af4dbaae",
"type": "main",
"index": 0
}
]
]
},
"7b0b70b9-5b36-4e36-b811-da21af4dbaae": {
"main": [
[
{
"node": "6f390583-909a-4ecd-822e-12feb703ff30",
"type": "main",
"index": 0
}
]
]
},
"6f390583-909a-4ecd-822e-12feb703ff30": {
"main": [
[
{
"node": "3ce8907e-c978-4769-942a-806cd7182351",
"type": "main",
"index": 0
},
{
"node": "0d493cb2-d367-4eb7-968e-1b05e8e0dee5",
"type": "main",
"index": 1
}
]
]
},
"cdd04485-cdbc-4015-85a1-fdd5c359f4f4": {
"main": [
[
{
"node": "6552176e-15d3-4886-b8b8-f463d0c49e08",
"type": "main",
"index": 0
}
]
]
},
"0f270c23-7f82-49b4-8bbb-4362d12fcd60": {
"ai_languageModel": [
[
{
"node": "cbd8fb15-5cf0-4993-a5f5-c732496c3efe",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"10c02d77-5179-44a5-a219-213921b41377": {
"main": [
[
{
"node": "63aae3c1-6479-477f-a26b-85f3d589a6bc",
"type": "main",
"index": 0
}
]
]
},
"4f7b3e8e-8b1b-4ccc-af0f-2371ca846d95": {
"main": [
[
{
"node": "ca373635-6cc4-44e1-b4f5-d44ed3d487b1",
"type": "main",
"index": 0
}
]
]
},
"85c930e9-cb8a-47ad-8082-5ae97c945b4b": {
"main": [
[
{
"node": "cbd8fb15-5cf0-4993-a5f5-c732496c3efe",
"type": "main",
"index": 0
}
]
]
}
}
}よくある質問
このワークフローの使い方は?
上記のJSON設定コードをコピーし、n8nインスタンスで新しいワークフローを作成して「JSONからインポート」を選択、設定を貼り付けて認証情報を必要に応じて変更してください。
このワークフローはどんな場面に適していますか?
上級
有料ですか?
このワークフローは完全無料です。ただし、ワークフローで使用するサードパーティサービス(OpenAI APIなど)は別途料金が発生する場合があります。
関連ワークフロー
n8nノードの探索(可視化リファレンスライブラリ内)
n8nノードを可視化リファレンスライブラリで探索
If
Ftp
Set
+
If
Ftp
Set
113 ノードI versus AI
その他
OpenAI・LangChain・アピ業間連携によるワークフレーム自動化入門ガイド
OpenAI、LangChain、API を使用したワークフロー自動化の初心者ガイド
If
Set
Code
+
If
Set
Code
33 ノードMeelioo
コンテンツ作成
[テンプレート] AIペットショップ v8
AIペットショップアシスタント - GPT-4o、Googleカレンダー、WhatsApp/Instagram/Facebookを統合
If
N8n
Set
+
If
N8n
Set
244 ノードAmanda Benks
営業
AI エージェント レストラン [テンプレート]
🤖 WhatsApp、Instagram、MessengerのAIレストランアシスタント
If
N8n
Set
+
If
N8n
Set
239 ノードAmanda Benks
その他
基于AIのMISエージェント
基于AIの管理信息系统エージェント
If
Set
Code
+
If
Set
Code
129 ノードKumar Shivam
サポート
Microsoft Teams会議分析をGPT-4.1、Outlook、Mem.aiを使用して自動化
GPT-4.1、Outlook、Mem.aiを使ってMicrosoft Teams会議の分析を自動化する
If
Set
Code
+
If
Set
Code
61 ノードWayne Simpson
人事
ワークフロー情報
難易度
上級
ノード数30
カテゴリー-
ノードタイプ15
作成者
Hugo
@hugo-miseryGrowth engineer focused on AI, data automation, and custom integrations. Use to turn complex ideas into simple, and scalable workflows with solid infrastructure
外部リンク
n8n.ioで表示 →
このワークフローを共有