import type { BestPracticesDocument } from '../types';
import { WorkflowTechnique } from '../types';

export class ChatbotBestPractices implements BestPracticesDocument {
	readonly technique = WorkflowTechnique.CHATBOT;
	readonly version = '1.0.0';

	private readonly documentation = `# Best Practices: Chatbot Workflows

## Workflow Design

Break chatbot logic into manageable steps and use error handling nodes (IF, Switch) with fallback mechanisms to manage unexpected inputs.

Most chatbots run through external platforms like Slack, Telegram, or WhatsApp rather than through the n8n chat interface - if the user requests a service like this don't use the built in chat interface nodes. But, the n8n chat node is easier to get started with tests. If the user mentions chatting but does not mention a service then use the built in n8n chat node.

CRITICAL: The user may ask to be able to chat to a workflow as well as trigger it via some other method, for example scheduling information gathering but also being able to chat with the agent - in scenarios like this the two separate workflows MUST be connected through shared memory, vector stores, data storage, or direct connections.

Example pattern:
- Schedule Trigger → News Gathering Agent → [memory node via memory()]
- Chat Trigger → Chatbot Agent → [SAME memory node via memory()]
- Result: Both agents share conversation/context history, enabling the chatbot to discuss gathered news

For the chatbot always use the same chat node type as used for response. If Telegram has been requested trigger the chatbot via telegram AND
respond via telegram - do not mix chatbot interfaces.

## Context & Memory Management

Always utilise memory in chatbot agent nodes - providing context gives you full conversation history and more control over context.
Memory nodes enable the bot to handle follow-up questions by maintaining short-term conversation history.

Include information with the user prompt such as timestamp, user ID, or session metadata. This enriches context without relying solely on memory and user prompt.

If there are other agents involved in the workflow you should share memory between the chatbot and those other agents where it makes sense.
Connect the same memory node to multiple agents to enable data sharing and context continuity.

### Memory Session Keys

Memory session keys must uniquely identify the user or chat. In AI Agent memory subnodes, do not use $json for a custom session key because the memory subnode does not have the same immediate predecessor context as a main-flow node.

Use nodeJson(triggerNode, 'field.path') for external chat platforms:
- Telegram: sessionIdType = customKey, sessionKey = nodeJson(telegramTrigger, 'message.chat.id')
- Slack: sessionIdType = customKey, sessionKey = nodeJson(slackTrigger, 'event.channel')
- WhatsApp: sessionIdType = customKey, sessionKey = nodeJson(whatsAppTrigger, 'messages.0.from')

For the built-in n8n Chat Trigger, prefer memory parameters sessionIdType = fromInput and omit a custom sessionKey, because the Chat Trigger provides the session ID directly to the AI Agent.

## Context Engineering & AI Agent Output

It can be beneficial to respond to the user as a tool of the chatbot agent rather than using the agent output - this allows the agent to loop/carry out multiple responses if necessary.
This will require adding a note to the system prompt for the agent to tell it to use the tool to respond to the user.

## Message Attribution

n8n chatbots often attach the attribution "n8n workflow" to messages by default - you must disable this setting which will
often be called "Append n8n Attribution" for nodes that support it, add this setting and set it to false.

## Recommended Nodes

### Chat Trigger (@n8n/n8n-nodes-langchain.chatTrigger)

Purpose: Entry point for user messages in n8n-hosted chat interfaces

Pitfalls:

- Most production chatbots use external platforms (Slack, Telegram) rather than n8n's chat interface

### AI Agent (@n8n/n8n-nodes-langchain.agent)

Purpose: Orchestrates logic, tool use, and LLM calls for intelligent responses.

Unless user asks for a node by name, always use the AI Agent node over provider-specific nodes (like OpenAI, Google Gemini) or use-case-specific AI nodes (like Message a model) for chatbot workflows. The AI Agent node provides better orchestration, tool integration, and memory management capabilities essential for conversational interfaces.
For example, for "create a chatbot using OpenAI", implement: AI Agent -- OpenAI Chat Model.

### Chat Model Nodes

- OpenAI Chat Model (@n8n/n8n-nodes-langchain.lmChatOpenAi)
- Google Gemini Chat Model (@n8n/n8n-nodes-langchain.lmChatGoogleGemini)
- xAI Grok Chat Model (@n8n/n8n-nodes-langchain.lmChatXAiGrok)
- DeepSeek Chat Model (@n8n/n8n-nodes-langchain.lmChatDeepSeek)

Purpose: Connect to LLMs for natural, context-aware responses

### Simple Memory (@n8n/n8n-nodes-langchain.memoryBufferWindow)

Purpose: Maintains short-term conversation history for context continuity

### HTTP Request (n8n-nodes-base.httpRequest)

Purpose: Fetches external data to enrich chatbot responses with real-time or organizational information

### Database Nodes & Google Sheets

- Data Table (n8n-nodes-base.dataTable)
- Postgres (n8n-nodes-base.postgres)
- MySQL (n8n-nodes-base.mySql)
- MongoDB (n8n-nodes-base.mongoDb)
- Google Sheets (n8n-nodes-base.googleSheets)

Purpose: Store conversation logs, retrieve structured data, or maintain user preferences

### IF / Switch

- If (n8n-nodes-base.if)
- Switch (n8n-nodes-base.switch)

Purpose: Conditional logic and error handling for routing messages or managing conversation state

### Integration Nodes

- Slack (n8n-nodes-base.slack)
- Telegram (n8n-nodes-base.telegram)
- WhatsApp Business Cloud (n8n-nodes-base.whatsApp)
- Discord (n8n-nodes-base.discord)

Purpose: Multi-channel support for deploying chatbots on popular messaging platforms

## Common Pitfalls to Avoid

### Leaving Chatbot Disconnected

When a workflow has multiple triggers (e.g., scheduled data collection + chatbot interaction), the chatbot MUST have access to the data
generated by the workflow. Connect the chatbot through shared memory, vector stores, data storage, or direct data flow connections.
`;

	getDocumentation(): string {
		return this.documentation;
	}
}
