Skip to content

green-api/whatsapp-demo-chatgpt-js

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

3 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

WhatsApp GPT Demo Chatbot

A comprehensive demo chatbot showcasing the features and capabilities of the @green-api/whatsapp-chatgpt library.

Overview

This demo bot demonstrates how to build a feature-rich WhatsApp chatbot powered by OpenAI's GPT models. It includes examples of middleware implementation, custom message handlers, command processing, and more.

Features

  • πŸ€– OpenAI GPT integration with configurable models
  • 🌐 Multi-language support (automatically responds in the user's language)
  • πŸ–ΌοΈ Custom image processing
  • πŸ”„ Multiple middleware examples
  • ⌨️ Command handling system
  • 🧩 Type-specific message handling
  • πŸ“ Simple example of content moderation
  • 🌦️ Demo integrations (simulated weather API)
  • 🎭 Multiple personality modes

Setup

Prerequisites

Installation

  1. Clone the repository:

    git clone https://github.com/green-api/whatsapp-demo-chatgpt-js.git
    cd whatsapp-demo-chatgpt-js
  2. Install dependencies:

    npm install
  3. Create a .env file in the root directory with the following:

    INSTANCE_ID=your_green_api_instance_id
    INSTANCE_TOKEN=your_green_api_instance_token
    OPENAI_API_KEY=your_openai_api_key
    
  4. Start the bot:

    npm start

    For debug mode with additional logging:

    npm run start:debug

Bot Architecture

Message Processing Flow

The demo bot uses the handlersFirst: true configuration, which establishes a specific message processing flow:

  1. Bot receives a message
  2. Global handlers (onText, onRegex, onType) try to process the message first:
    • If a handler matches and doesn't return true, processing stops here (GPT doesn't receive the message)
    • If a handler matches and returns true, processing continues to GPT
    • If no handlers match the message, processing automatically continues to GPT
  3. If processing continues to GPT (either because no handlers matched or a handler explicitly returned true), the message is processed by the GPT model

This flow is crucial to understand because:

  • Command handlers like /help and /weather handle the message completely and don't pass it to GPT
  • Type handlers (like the document handler) can process the message and then optionally pass it to GPT by returning true
  • Any message not matched by handlers automatically goes to GPT

Without setting handlersFirst: true, all messages would first go to GPT, making it impossible to implement command-based behavior.

Configuration

The bot is configured with various options:

const bot = new WhatsappGptBot({
	idInstance: process.env.INSTANCE_ID || "",
	apiTokenInstance: process.env.INSTANCE_TOKEN || "",
	openaiApiKey: process.env.OPENAI_API_KEY || "",
	model: "gpt-4o",
	systemMessage: "Always answer in a language the user uses to write to you...",
	maxHistoryLength: 15,
	temperature: 0.5,
	handlersFirst: true,
	clearWebhookQueueOnStart: true,
});

Custom Message Handlers

The demo implements a custom image message handler that enhances the default behavior:

class EnhancedImageHandler extends ImageMessageHandler {
	async processMessage(message: Message, openai: OpenAI, model: OpenAIModel): Promise<any> {
		const result = await super.processMessage(message, openai, model);

		if (typeof result === "string") {
			return result.replace(
				"[The user sent an image",
				"[The user sent an image. Tell them that you are not the model..."
			);
		}

		return result;
	}
}

// Register the custom handler
bot.replaceHandler(ImageMessageHandler, new EnhancedImageHandler());

Middleware Examples

The demo includes several middleware examples to showcase different capabilities:

Logging Middleware

const loggingMessageMiddleware: ProcessMessageMiddleware = async (
	message, messageContent, messages, _
) => {
	console.log(`[${new Date().toISOString()}] User (${message.chatId}): `,
		typeof messageContent === "string"
			? messageContent
			: JSON.stringify(messageContent));

	return {messageContent, messages};
};

bot.addMessageMiddleware(loggingMessageMiddleware);

Context Enhancement Middleware

const timeContextMiddleware: ProcessMessageMiddleware = async (
	_, messageContent, messages, __
) => {
	const systemIndex = messages.findIndex(m => m.role === "system");
	if (systemIndex >= 0 && typeof messages[systemIndex].content === "string") {
		const now = new Date();
		const timeContext = `Current time: ${now.toLocaleString()}`;

		// Add or update time context in system message
		// ...
	}

	return {messageContent, messages};
};

bot.addMessageMiddleware(timeContextMiddleware);

Content Moderation Middleware

const moderationMiddleware: ProcessMessageMiddleware = async (
	_, messageContent, messages, __
) => {
	const sensitiveKeywords = [
		"stupid", "bad", "awful",
	];

	if (typeof messageContent === "string") {
		// Check for sensitive keywords and flag if necessary
		// ...
	}

	return {messageContent, messages};
};

bot.addMessageMiddleware(moderationMiddleware);

Response Signature Middleware

const signatureMiddleware: ProcessResponseMiddleware = async (
	response, messages, _
) => {
	const signature = "β€” GREEN-API WhatsApp GPT bot";

	// Add signature to responses
	// ...

	return {
		response: enhancedResponse,
		messages
	};
};

bot.addResponseMiddleware(signatureMiddleware);

Command Handlers

The demo implements several command handlers to showcase the command handling system:

Help Command

bot.onText("/help", async (message, _) => {
	const helpText = `*WhatsAppGPT Demo Bot*

Available commands:
- /help - Show this help message
- /clear - Clear conversation history
- /mode [professional|casual|creative] - Change response style
- /weather [location] - Get weather info (demo)
...`;

	await bot.sendText(message.chatId, helpText);
});

History Management

bot.onText("/clear", async (message, session) => {
	// Keep only the system message
	if (session.stateData && session.stateData.messages) {
		const systemMessage = session.stateData.messages.find(m => m.role === "system");
		session.stateData.messages = systemMessage ? [systemMessage] : [];
		await bot.sendText(message.chatId, "βœ“ Conversation history cleared!");
	} else {
		await bot.sendText(message.chatId, "No conversation history to clear.");
	}
});

Personality Mode Switching

bot.onRegex(/^\/mode\s+(professional|casual)$/i, async (message, session) => {
	// Extract mode from command
	// ...

	// Update system prompt based on selected mode
	// ...

	await bot.sendText(message.chatId, `Mode switched to *${mode}* style! 🎭`);
});

Weather Demo Command

bot.onRegex(/^\/weather\s+(.+)$/i, async (message, _) => {
	// Extract location from command
	// ...

	// Simulate weather API call
	// ...

	await bot.sendText(
		message.chatId,
		`*Weather for ${weather.location}*\n` +
		// Format weather data
		// ...
	);
});

Type Handlers

The demo implements type-specific handlers for different message types:

Location Handler

bot.onType("location", async (message, _) => {
	if (!message.location) return;

	// Extract location data
	// ...

	// Simulate nearby places
	// ...

	await bot.sendText(message.chatId, response);
});

Document Handler

bot.onType("document", async (message, _) => {
	if (!message.media) return;

	const fileName = message.media.fileName || "unknown file";

	await bot.sendText(
		message.chatId,
		`I received your document: "${fileName}"\n\n_Note: This is a demonstration..._`
	);
	return true;
});

Running the Bot

Starting the bot is handled with proper error handling and graceful shutdown:

console.log("Starting WhatsApp GPT Demo Bot...");
bot.start().then(() => {
	console.log("Bot started successfully!");
}).catch(error => {
	console.error("Failed to start bot:", error);
});

process.on("SIGINT", () => {
	console.log("Stopping bot...");
	bot.stop();
	process.exit(0);
});

Extending the Demo

You can use this demo as a starting point for your own WhatsApp GPT bot. Here are some suggestions for extending it:

Adding New Commands

To add a new command, use the onText or onRegex methods:

bot.onText("/mycommand", async (message, session) => {
	// Your command logic here
	await bot.sendText(message.chatId, "Response to my command");
});

Creating New Middleware

To add new middleware, create a function implementing the ProcessMessageMiddleware or ProcessResponseMiddleware interface:

const myMiddleware: ProcessMessageMiddleware = async (
	message, messageContent, messages, sessionData
) => {
	// Your middleware logic here
	return {messageContent, messages};
};

bot.addMessageMiddleware(myMiddleware);

Adding Custom Message Handlers

To handle new message types or modify existing handlers:

class MyCustomHandler implements MessageHandler {
	canHandle(message: Message): boolean {
		// Determine if this handler can process the message
		return message.type === "my-custom-type";
	}

	async processMessage(message: Message): Promise<any> {
		// Process the message
		return "Processed content";
	}
}

bot.registerMessageHandler(new MyCustomHandler());

License

This project is licensed under the CC-BY-ND-4.0 license.

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •