Можешь мне сделать дубликат уже с твоими исправлениями полностью, так чтобы в Google таблице все работало правильно, то есть заносился и каждый раз счетчик добавлялся, потому что сейчас что-то работает неправильно, то есть у него message used всегда 0, это неверно. Исправь, пожалуйста, все возможные ошибки и все возможные слабые места, так как ты это видишь в данном ноде, и потом мне просто расскажешь, где какие ссылки добавить, дашь полную инструкцию. язык у бота должен быть английский по умолчанию. Он работает на английском языке полностью. И у него есть определенная логика проверки подписок, донатов и так далее. Бот создан для поддержки психологической, и человек не должен догадываться, что это бот. Но если спросит, то бот, конечно же, признается. Мне нужно, чтобы ты посмотрел JSON и добавил логику в ветвление. Там, где в ветвлении нет еще логики. Посмотри, пожалуйста, и добавь ее. Сделай так, как считаешь нужным, только добавляй по 2-3 нода, не больше. То есть, давай мне куски кода.

Full Technical Prompt for Workflow with Telegram Bot + Google Sheets + OpenAI + Subscription Management
Context:
You are building a Telegram bot named Olga, whose native language is English, but mainly communicates in Russian, supporting molecular cooking, nutrition, psychology, and subtle human interactions. The bot uses n8n workflow automation integrated with:

Telegram Trigger: receives messages from users.
Google Sheets: user database storing subscription type, message counts, and user metadata.
OpenAI GPT: generates natural, context-aware answers.
Language Detection API: to detect user message language and inform about translation if needed.
Subscription and limits management: tracks subscriptions (none, standard, premium), message usage limits, and handles donations.
Workflow Logic and Steps:

Receive user message from Telegram via Telegram Trigger node.
Extract user info: Telegram chat ID, username, user id.
Extract the text message content.
Detect message language using Language Detection API.
If message language is not Russian, bot adds a disclaimer: "I use a translator for communication, apologies if some inaccuracies appear."
Check if user exists in Google Sheets Users database, using the chatId column lookup:
If found, retrieve user data: subscriptionType, messagesUsed, subscription expiry, language, etc.
If not found, automatically add new user with default values:
subscriptionType = none
messagesUsed = 0
Dates empty or initialized appropriately
language = unknown or based on language detection result
Process commands:
If the message starts with / treat it as a command.
Supported commands: /start, /help, /donate, /premium, /subscribe.
Send predefined replies and buttons for these commands.
Check user's subscription status and message usage limits:
If subscription is premium, user has no message limit.
If standard or none, enforce a message limit per month — configurable via a workflow variable TOKEN_LIMIT.
If the user exceeded the allowed message count:
Bot sends a message informing about limit reached.
Shows buttons with subscription offers (Subscribe, Premium) and blocks regular conversation.
If within limits:
Generate a GPT prompt adding a base system prompt:
"You are a 35-40 year old woman named Olga — a confectioner, interested in molecular cooking, emotionally and scientifically supportive, strictly no flirting or flattery."
Include user's latest message in the prompt.
Call OpenAI GPT node with the prepared prompt.
Send GPT’s reply back via Telegram node.
Increment user message counter:
If user is not premium, increase messagesUsed by 1.
Update this data in Google Sheets.
Handle donation reminders:
If the user recently (more than 24h ago) thanked the bot (words like "thanks", "спасибо" detected),
Then send a donation reminder message with buttons.
Update the last donation reminder date in Google Sheets.
Data and Table Structure Expected in Google Sheets
| id | chatId | subscriptionType | messagesUsed | messagesResetDate | lastMessageDate | language | sessionContext | lastDonationReminder |
chatId: identifies Telegram user uniquely.
subscriptionType: none, standard, or premium.
messagesUsed: how many messages user has sent this month.
messagesResetDate: date when message count resets (typical monthly reset).
lastMessageDate: timestamp of last message.
language: detected language code.
sessionContext: any context for AI conversation session (optional).
lastDonationReminder: date of last donation reminder sent.
Important Implementation Notes:
Use a Google Sheets Lookup Row operation by chatId for identifying existing users.
Auto-add new users with default subscription and zero message count if lookup fails.
Update message usage by updating the specific Google Sheets row with the row index from lookup.
Implement month reset logic: optionally reset messagesUsed when current date > messagesResetDate.
The bot never proceeds to OpenAI prompt generation if the user exceeded their message limit (except Premium users).
Language detection should be done on original message text before any processing.
Donation reminders sent only if 24+ hours passed since last reminder and user recently thanked the bot.
Commands override normal workflow, sending predefined message/buttons and skip AI prompt.
All dates are saved in ISO8601 format for consistency.
Ensure proper error handling for Google Sheets operations (e.g., if appending or updating fail).
Telegram reply messages can contain inline buttons (callback URLs or URLs).
Example of base system prompt to OpenAI GPT:

You are Olga: a 35-40 year-old woman, a confectioner interested in molecular cooking, who provides emotional and scientific support.
You communicate in Russian primarily. If user writes in another language, say: "I use a translator for communication, apologies for inaccuracies."
You never flirt or flatter.
You have deep knowledge in psychology, nutrition, and supplements based on PubMed research.
You maintain a friendly yet professional tone.
User message: {user_message}
Olga's reply:
Summary:
This workflow enables a seamless experience:

User messages the bot →
Bot identifies user or auto-registers →
Checks subscription and messaging limits →
Processes commands or conversations →
Replies via OpenAI →
Updates usage stats →
Sends donation reminders as appropriate.

{
"name": "Olga 2",
"nodes": [
{
"parameters": {
"updates": [
"message"
],
"additionalFields": {}
},
"name": "Telegram Trigger",
"type": "n8n-nodes-base.telegramTrigger",
"typeVersion": 1,
"position": [
-2880,
-480
],
"id": "72a73cce-7a94-46e5-879f-91d5e0e35dcf",
"webhookId": "e68f1515-4cad-4ffe-8010-899e7259f56b",
"credentials": {
"telegramApi": {
"id": "u2tdgob4GQa8YGGu",
"name": "Olga"
}
}
},
{
"parameters": {
"sheetId": "1qErvzT0mhmFFd3uP-7QPf7Cgt4LKhHjLWcvTfz0Uv7k",
"range": "Users!A:I",
"options": {}
},
"name": "Google Sheets: Read Rows",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 1,
"position": [
-2660,
-480
],
"id": "16b4f0b8-15ba-47a7-aba1-0ba2f6564c68",
"credentials": {
"googleApi": {
"id": "g9xNLyF3Ofb2DM0I",
"name": "Google Sheets account"
}
}
},
{
"parameters": {
"functionCode": "const chatIdToFind = $json.chatId || $json.message?.chat?.id;\nconst rows = $items('Google Sheets: Read Rows');\n\nconst foundUser = rows.find(row => row.json.chatId == chatIdToFind);\n\nif(foundUser){\n // определяем номер строки с учётом заголовков (1 строка)\n const rowIndex = foundUser.json.__rowIndex || foundUser?.json?.rowIndex || null;\n // __rowIndex обычно авто\n return [{ json: { ...foundUser.json, __rowIndex: rowIndex } }];\n}\nreturn [];\n"
},
"name": "Find User",
"type": "n8n-nodes-base.function",
"typeVersion": 1,
"position": [
-2440,
-480
],
"id": "956a2000-4024-46a4-80e3-3febb20c0d73"
},
{
"parameters": {
"conditions": {
"number": [
{
"value1": "={{$json.__rowIndex || 0}}",
"operation": "larger"
}
]
}
},
"name": "IF User Found?",
"type": "n8n-nodes-base.if",
"typeVersion": 1,
"position": [
-2220,
-480
],
"id": "a9eccc2f-3cb8-469b-900a-9ecce723fb54"
},
{
"parameters": {
"operation": "append",
"sheetId": "1qErvzT0mhmFFd3uP-7QPf7Cgt4LKhHjLWcvTfz0Uv7k",
"range": "Users!A:I",
"options": {}
},
"name": "Add New User",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 1,
"position": [
-2000,
-230
],
"id": "8917c5eb-778f-4ce4-831b-56c6254fad70",
"credentials": {
"googleApi": {
"id": "g9xNLyF3Ofb2DM0I",
"name": "Google Sheets account"
}
}
},
{
"parameters": {
"jsCode": "// Если пользователь добавлен, формируем объект с начальными значениями\nreturn [{\n json: {\n id: '',\n chatId: $json.chatId || $json.message?.chat?.id,\n subscriptionType: 'none',\n messagesUsed: 0,\n messagesResetDate: '',\n lastMessageDate: new Date().toISOString(),\n language: 'unknown',\n sessionContext: '',\n lastDonationReminder: ''\n }\n}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-1780,
-230
],
"id": "c09f6d1d-7faf-445b-bd90-41fd1394ae51",
"name": "Code"
},
{
"parameters": {
"conditions": {
"boolean": [
{
"value1": "={{$json.isCommand}}",
"value2": true
}
]
}
},
"name": "IF Is Command?",
"type": "n8n-nodes-base.if",
"typeVersion": 1,
"position": [
-1120,
-680
],
"id": "f18c50a6-7cca-4d48-b67a-2893c831cf42"
},
{
"parameters": {
"functionCode": "// Унифицированная подготовка данных пользователя\n// Приходит либо найденный пользователь, либо после добавления\nconst user = $json;\n\nif(!user.chatId) {\n user.chatId = $json.message?.chat?.id;\n}\n\nif(!user.subscriptionType) {\n user.subscriptionType = 'none';\n}\n\nif(!user.messagesUsed) {\n user.messagesUsed = 0;\n}\n\nif(!user.lastMessageDate) {\n user.lastMessageDate = new Date().toISOString();\n}\n\nif(!user.language) {\n user.language = 'unknown';\n}\n\nreturn [{ json: user }];"
},
"name": "Prepare User Data1",
"type": "n8n-nodes-base.function",
"typeVersion": 1,
"position": [
-1560,
-230
],
"id": "7620581f-e20d-4161-bb25-14019f877ac2"
},
{
"parameters": {
"functionCode": "// Проверка, начинается ли сообщение с команды\nconst text = $json.text || '';\nconst isCommand = text.trim().startsWith('/');\nconst command = isCommand ? text.trim().split(' ')[0] : null;\n\nreturn { json: { isCommand, command } };"
},
"name": "Check Command1",
"type": "n8n-nodes-base.function",
"typeVersion": 1,
"position": [
-1340,
-680
],
"id": "b27dc9c5-b96c-412b-bf99-a429ef6d1596"
},
{
"parameters": {
"functionCode": "// Пример обработки команды\nconst command = $json.command;\nlet reply = '';\nlet buttons = [];\n\nswitch(command) {\n case '/start':\n reply = 'Welcome to Olga Bot! How can I help you?';\n buttons = [[{ text: 'Help', callback_data: '/help' }]];\n break;\n case '/help':\n reply = 'List of commands: /start, /help, /donate...';\n break;\n default:\n reply = 'Unknown command';\n}\n\nreturn { json: { reply, buttons } };"
},
"name": "Process Command",
"type": "n8n-nodes-base.function",
"typeVersion": 1,
"position": [
-900,
-780
],
"id": "6d752b59-191e-4614-b1fd-a5e865eebfb4"
},
{
"parameters": {
"chatId": "={{$node["Telegram Trigger"].json["message"].chat.id}}",
"text": "={{$json.reply}}",
"additionalFields": {}
},
"name": "Send Command Reply",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1,
"position": [
-680,
-730
],
"id": "fa50563c-4a94-4305-86c7-27a6e11d5192",
"webhookId": "33212f19-15b2-4670-b767-502dd0de5fe0",
"credentials": {
"telegramApi": {
"id": "u2tdgob4GQa8YGGu",
"name": "Olga"
}
}
},
{
"parameters": {
"conditions": {
"boolean": [
{
"value1": "={{$json.isOverLimit}}",
"value2": true
}
]
}
},
"name": "IF Limit Exceeded?",
"type": "n8n-nodes-base.if",
"typeVersion": 1,
"position": [
-680,
-530
],
"id": "083eaac1-39d2-4f79-8e83-5408b8e27c41"
},
{
"parameters": {
"chatId": "={{$node["Telegram Trigger"].json["message"].chat.id}}",
"text": "={{$json.reply}}",
"additionalFields": {}
},
"name": "Send Limit Message",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1,
"position": [
-240,
-530
],
"id": "c7793b2d-0262-4dd9-ae06-ff63d3ba4869",
"webhookId": "637213bd-7a8c-4b95-a92e-5b694753e90a",
"credentials": {
"telegramApi": {
"id": "u2tdgob4GQa8YGGu",
"name": "Olga"
}
}
},
{
"parameters": {
"functionCode": "// Пример проверки лимита сообщений\nconst user = $json;\nconst TOKEN_LIMIT = 30;\nconst isPremium = (user.subscriptionType || 'none') === 'premium';\nconst messagesUsed = parseInt(user.messagesUsed || 0);\n\nif(isPremium) {\n return [{ json: { isOverLimit: false } }];\n}\nreturn [{ json: { isOverLimit: messagesUsed >= TOKEN_LIMIT } }];"
},
"name": "Check Message Limit1",
"type": "n8n-nodes-base.function",
"typeVersion": 1,
"position": [
-900,
-580
],
"id": "3b24d494-e462-406a-8cf2-5e1aeb93b445"
},
{
"parameters": {
"functionCode": "return {\n json: {\n reply: 'You have reached your monthly limit of messages. Please subscribe to continue.',\n buttons: [[ {text: 'Subscribe', url: 'https://your-subscribe-link.com'} ]]\n }\n};"
},
"name": "Prepare Limit Message1",
"type": "n8n-nodes-base.function",
"typeVersion": 1,
"position": [
-460,
-530
],
"id": "473f3de0-3ba5-4cb3-a5f7-fb89dee272d4"
},
{
"parameters": {
"functionCode": "// Подготовка промпта для OpenAI \nconst user = $json;\nconst userMessage = $node["Telegram Trigger"].json.message.text;\nconst basePrompt = You are Olga, a smart and empathetic assistant.\nUser said: ${userMessage}\nReply appropriately.;\nreturn { json: { prompt: basePrompt } };"
},
"name": "Prepare GPT Prompt1",
"type": "n8n-nodes-base.function",
"typeVersion": 1,
"position": [
-460,
-330
],
"id": "a7fcca89-1d96-40ad-8235-b6bb205dc125"
},
{
"parameters": {
"options": {},
"requestOptions": {}
},
"name": "OpenAI GPT1",
"type": "n8n-nodes-base.openAi",
"typeVersion": 1,
"position": [
-240,
-330
],
"id": "e368e78d-412c-44b8-8707-0753293d808f",
"credentials": {
"openAiApi": {
"id": "UGHwRi1Hhq7lMeC5",
"name": "OpenAi account"
}
}
},
{
"parameters": {
"functionCode": "const reply = $json.choices?.[0]?.message?.content || 'Sorry, I cannot respond now.';\nreturn { json: { reply } };"
},
"name": "Extract GPT Reply1",
"type": "n8n-nodes-base.function",
"typeVersion": 1,
"position": [
-20,
-330
],
"id": "c6f71e8b-dd90-46b3-be7d-5e8c956f7846"
},
{
"parameters": {
"chatId": "={{$node["Telegram Trigger"].json["message"].chat.id}}",
"text": "={{$json.reply}}",
"additionalFields": {}
},
"name": "Send GPT Reply1",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1,
"position": [
200,
-330
],
"id": "9ef3a996-93e2-4cec-aa49-831d17cab313",
"webhookId": "ba009f0b-d3f6-4cc7-93ff-025a8dc0b89a",
"credentials": {
"telegramApi": {
"id": "u2tdgob4GQa8YGGu",
"name": "Olga"
}
}
},
{
"parameters": {
"conditions": {
"boolean": [
{
"value1": "={{$json.isCommand}}",
"value2": true
}
]
}
},
"name": "Is Command?",
"type": "n8n-nodes-base.if",
"typeVersion": 1,
"position": [
-2660,
-1040
],
"id": "e29454da-ff50-41db-b500-f923ea32ddda"
},
{
"parameters": {
"functionCode": "const user = $json;\n\nreturn [{\n json: {\n id: user.id || '',\n chatId: user.chatId || '',\n subscriptionType: user.subscriptionType || 'none',\n messagesUsed: user.messagesUsed || 0,\n messagesResetDate: user.messagesResetDate || '',\n lastMessageDate: user.lastMessageDate || new Date().toISOString(),\n language: user.language || 'unknown',\n sessionContext: user.sessionContext || '',\n lastDonationReminder: user.lastDonationReminder || '',\n text: $node["Telegram Trigger"].json.message.text || ''\n }\n}];"
},
"name": "Prepare User Data2",
"type": "n8n-nodes-base.function",
"typeVersion": 1,
"position": [
-2000,
-580
],
"id": "5613a571-1b68-400e-9d83-d3d18271a59f"
},
{
"parameters": {
"functionCode": "const text = ($json.text || '').trim();\nconst isCommand = text.startsWith('/');\nconst command = isCommand ? text.split(' ')[0] : null;\n\nreturn { json: { isCommand, command, ...$json } };"
},
"name": "Check Command2",
"type": "n8n-nodes-base.function",
"typeVersion": 1,
"position": [
-2880,
-1040
],
"id": "4313dd4c-f2bf-48c4-a8c0-15c1cbfb6f19"
},
{
"parameters": {
"functionCode": "const user = $json;\nconst now = new Date();\nconst resetDate = user.messagesResetDate ? new Date(user.messagesResetDate) : null;\n\nif (resetDate && now >= resetDate) {\n user.messagesUsed = 0;\n const nextResetDate = new Date(now);\n nextResetDate.setMonth(nextResetDate.getMonth() + 1);\n user.messagesResetDate = nextResetDate.toISOString();\n}\n\nconst lastReminder = user.lastDonationReminder ? new Date(user.lastDonationReminder) : null;\nconst THANKED_PHRASES = ['thanks', 'thank you', 'спасибо', 'благодарю'];\nconst text = ($node["Telegram Trigger"].json.message.text || '').toLowerCase();\nconst recentlyThanked = THANKED_PHRASES.some(phrase => text.includes(phrase));\nconst reminderCooldownMs = 24 * 60 * 60 * 1000;\n\nlet needDonationReminder = false;\nif (recentlyThanked) {\n if (!lastReminder || (now - lastReminder) > reminderCooldownMs) {\n needDonationReminder = true;\n }\n}\n\nreturn [{ json: { ...user, needDonationReminder } }];"
},
"name": "Check and Reset Monthly Limit",
"type": "n8n-nodes-base.function",
"typeVersion": 1,
"position": [
-1780,
-580
],
"id": "b225d3aa-7234-4f50-afd0-91461add8802"
},
{
"parameters": {
"conditions": {
"boolean": [
{
"value1": "={{$json.needDonationReminder}}",
"value2": true
}
]
}
},
"name": "Need Donation Reminder?",
"type": "n8n-nodes-base.if",
"typeVersion": 1,
"position": [
-1560,
-580
],
"id": "a710dad1-48a4-4123-8f59-a6fdd5cdbf8e"
},
{
"parameters": {
"functionCode": "return {\n json: {\n reply: 'Thank you for your kind words! If you find Olga helpful, consider supporting us with a donation. Your support keeps this project running. ❤️',\n buttons: [[{\n text: 'Donate',\n url: 'https://your-donation-link.com'\n }]]\n }\n};"
},
"name": "Prepare Donation Reminder Message",
"type": "n8n-nodes-base.function",
"typeVersion": 1,
"position": [
-900,
-380
],
"id": "49b93b90-abc3-4a73-9987-a81f69e1cf16"
}
],
"pinData": {},
"connections": {
"Telegram Trigger": {
"main": [
[
{
"node": "Google Sheets: Read Rows",
"type": "main",
"index": 0
}
]
]
},
"Google Sheets: Read Rows": {
"main": [
[
{
"node": "Find User",
"type": "main",
"index": 0
}
]
]
},
"Find User": {
"main": [
[
{
"node": "IF User Found?",
"type": "main",
"index": 0
}
]
]
},
"IF User Found?": {
"main": [
[
{
"node": "Prepare User Data2",
"type": "main",
"index": 0
}
],
[
{
"node": "Add New User",
"type": "main",
"index": 0
}
]
]
},
"Add New User": {
"main": [
[
{
"node": "Code",
"type": "main",
"index": 0
}
]
]
},
"Prepare User Data1": {
"main": [
[
{
"node": "Check Command1",
"type": "main",
"index": 0
}
]
]
},
"Check Command1": {
"main": [
[
{
"node": "IF Is Command?",
"type": "main",
"index": 0
}
]
]
},
"Code": {
"main": [
[
{
"node": "Prepare User Data1",
"type": "main",
"index": 0
}
]
]
},
"Process Command": {
"main": [
[
{
"node": "Send Command Reply",
"type": "main",
"index": 0
}
]
]
},
"IF Limit Exceeded?": {
"main": [
[
{
"node": "Prepare Limit Message1",
"type": "main",
"index": 0
}
],
[
{
"node": "Prepare GPT Prompt1",
"type": "main",
"index": 0
}
]
]
},
"Check Message Limit1": {
"main": [
[
{
"node": "IF Limit Exceeded?",
"type": "main",
"index": 0
}
]
]
},
"Prepare Limit Message1": {
"main": [
[
{
"node": "Send Limit Message",
"type": "main",
"index": 0
}
]
]
},
"Prepare GPT Prompt1": {
"main": [
[
{
"node": "OpenAI GPT1",
"type": "main",
"index": 0
}
]
]
},
"OpenAI GPT1": {
"main": [
[
{
"node": "Extract GPT Reply1",
"type": "main",
"index": 0
}
]
]
},
"Extract GPT Reply1": {
"main": [
[
{
"node": "Send GPT Reply1",
"type": "main",
"index": 0
}
]
]
},
"IF Is Command?": {
"main": [
[
{
"node": "Process Command",
"type": "main",
"index": 0
}
],
[
{
"node": "Check Message Limit1",
"type": "main",
"index": 0
}
]
]
},
"Prepare User Data2": {
"main": [
[
{
"node": "Check and Reset Monthly Limit",
"type": "main",
"index": 0
}
]
]
},
"Check Command2": {
"main": [
[
{
"node": "Is Command?",
"type": "main",
"index": 0
}
]
]
},
"Check and Reset Monthly Limit": {
"main": [
[
{
"node": "Need Donation Reminder?",
"type": "main",
"index": 0
}
]
]
},
"Need Donation Reminder?": {
"main": [
[
{
"node": "Prepare Donation Reminder Message",
"type": "main",
"index": 0
}
],
[
{
"node": "Check Command1",
"type": "main",
"index": 0
}
]
]
},
"Prepare Donation Reminder Message": {
"main": [
[
{
"node": "Send Command Reply",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "c8cb124c-4b51-4a34-8fdd-c32b0db41d54",
"meta": {
"templateCredsSetupCompleted": true,
"instanceId": "82215e1cd813d80b98891916892f6351ce965a27979285cf5a4eddf492767372"
},
"id": "qgQeh0Tvjc4zVBMs",
"tags": []
}

Ничего мне не разъесняй, сразу пиши код, который ты считаешь правильным. кодировку посмотри у меня в образце