A fun, extensible WhatsApp bot that plays games and call tools(acting as an agent) with you using AI intelligence! Built with TypeScript, Groq AI, and WhatsApp Web.js
APIS used : google sheet api for text storage(database), groq for AI intelligence, cloudinary for image storage
I built it to have fun with me and my friends. solves the "we have nothung to talk about " problem, "truth or dare, but none one has a questions or an interesting dare to ask", "ask questions and ill answer but no one wants to ask the questions", "nothing interesting to talk about" etc
✨ AI-Powered Responses - Uses Groq's language model to understand and respond intelligently
🎯 Tool-Based Architecture - Easily extensible system for adding new games and features
🖼️ Media Support - Send images and media from Cloudinary
💬 WhatsApp Integration - Runs directly through WhatsApp Web
🔄 Real-time Processing - Instant message handling with typing indicators
🎲 Multiple Games - Picture questions, truth or dare, and more!
- Node.js v20+
- npm or yarn
- A WhatsApp account (for scanning QR code)
# Clone the repository
git clone <repo-url>
cd weboredjs
# Install dependencies
npm install
# Create environment file
cp .env.example .env.local
# Start the bot
npm run devYou'll see a QR code in your terminal. Scan it with your WhatsApp phone to connect! 📱
weboredjs/
├── core/ # Core configurations
│ ├── client.ts # WhatsApp Web.js client setup
│ ├── qroqClient.ts # Groq API client
│ ├── cloudinary.ts # Cloudinary configuration
│ └── firebase.ts # Firebase setup (optional)
│
├── Helpers/ # Helper utilities
│ ├── qroq.ts # AI completion logic
│ ├── cloudinary.ts # Image fetching from Cloudinary
│ ├── whatsapp.ts # WhatsApp message helpers
│ └── firebase.ts # Firebase helpers (optional)
│
├── Handlers/ # Message handlers
│ └── tools.ts # Tool execution handler
│
├── utils/ # Utilities
│ └── tool_registry.ts # All available tools/games defined here
│
├── services/ # Services
│ └── boot.ts # Bot initialization
│
├── main.js # Entry point
└── package.json # Dependencies
User Message (WhatsApp)
↓
main.js receives message
↓
completion() → Groq AI (uses toolRegistry)
↓
AI decides which tool to use
↓
tool_handler() executes the tool
↓
Response sent back to WhatsApp
- User: "Send me a picture question"
- Bot: Calls
picture_questionstool - Cloudinary: Fetches random image
- Bot: Sends image with caption to WhatsApp
- User: Describes the image, bot responds
# Groq API
GROQ_API_KEY=your_groq_api_key
# Cloudinary (for images)
CLOUDINARY_PROJECT_NAME=your_project_name
CLOUDINARY_KEY=your_api_key
CLOUDINARY_SECRET=your_api_secret
# Firebase (optional)
FIREBASE_API_KEY=your_firebase_key
FIREBASE_PROJECT_ID=your_project_id
FIREBASE_STORAGE_BUCKET=your_bucket.appspot.com
FIREBASE_APP_ID=your_app_idEdit Helpers/qroq.ts and change the model field:
const response = await groq.chat.completions.create({
// ... other options ...
model: "openai/gpt-oss-20b", // Change this
// ... other options ...
});Available models:
openai/gpt-oss-20b(default - fast & free)claude-3-5-sonnet-20241022llama-3.1-70b-versatile- And many more via Groq's API
- Open
utils/tool_registry.ts - Add your tool to the
toolRegistryobject:
your_game_name: {
function: async (args: any) => {
// Your game logic here
client.sendMessage("[email protected]", "Let's play!");
},
description: "Description of what your game does",
parameters: {
type: "object",
properties: {
hint: { type: "string", description: "Optional hint" },
},
required: [],
},
}- The AI automatically knows about your tool and will call it when appropriate!
send_whatsapp_message- Send text responsespicture_questions- Send random images from Cloudinary for guessing gamestruth_or_dare- sends truth or darepick a number- pick a number and you get a qustion/task to do. always suprising
This bot integrates with Cloudinary for image handling:
- Upload images programmatically
- Fetch random images for games
- Organize by tags for categorization
Example:
import { getRandomImage } from "./Helpers/cloudinary.js";
const imageUrl = await getRandomImage();
// Use imageUrl in your gameShow "typing..." state to users for better UX:
import { sendTypingWithDelay } from "./Helpers/whatsapp.js";
await sendTypingWithDelay(msg, 2000); // Show typing for 2 secondsSend images with captions:
import { sendMedia } from "./Helpers/whatsapp.js";
await sendMedia("[email protected]", imageUrl, {
caption: "Check out this picture!",
});- Conversation History - Remember user context across messages
- use redis for conversation history and find a better way to store it, rather than object of array. and use an engine that resets the conversation etc
- Truth or Dare Game - Full multiplayer game implementation
- Random - add a function that makes sure the AI doesnt repeat the same question or dare to the user, not the AI but random function doesn't unless maybe the user requests for it.... so have about 1000+ questions and dares to avoid repetition, or store asked questions in db and avoid repeating.
- Custom AI Models - Support for Claude, GPT-4, Gemini Pro
- Local LLM Support - Run models locally with llama.cpp
- Database Integration - Persistent user data and game stats
- Multi-User Support - Handle multiple user conversations
- Fix status@broadcast issue
- unify tool handler and response handler into one mega handler
const conversationHistory: { [key: string]: any[] } = {};
export const completion = async (msg: WAWebJS.Message) => {
const userId = msg.from;
// Initialize history for new users
if (!conversationHistory[userId]) {
conversationHistory[userId] = [];
}
// Add user message
conversationHistory[userId].push({
role: "user",
content: msg.body,
});
// Use full conversation history
const response = await groq.chat.completions.create({
messages: [
{ role: "system", content: "You are a game bot..." },
...conversationHistory[userId],
],
// ... rest of config
});
return response;
};-
Picture Questions 🖼️
- Bot sends random image from Cloudinary
- User describes what they see
- Great for GK and visual recognition!
-
Text-based Games 💬
- Truth or Dare (in development)
- Riddles, trivia, and more
{
[toolName: string]: {
function: (args: any) => Promise<void>
description: string
parameters: {
type: "object"
properties: { [key: string]: any }
required: string[]
}
}
}| Function | Location | Purpose |
|---|---|---|
sendMessage() |
Helpers/whatsapp.ts |
Send text message |
sendMedia() |
Helpers/whatsapp.ts |
Send image with caption |
sendTypingWithDelay() |
Helpers/whatsapp.ts |
Show typing indicator |
getRandomImage() |
Helpers/cloudinary.ts |
Fetch random image |
uploadImage() |
Helpers/cloudinary.ts |
Upload image to Cloudinary |
- Never commit
.env.localto git - Regenerate API keys if exposed
- Use
.gitignoreto exclude sensitive files - Keep credentials secure - use environment variables only
npm install dotenv- Check your internet connection
- Rescan the QR code
- Clear
.wwebjs_auth/and.wwebjs_cache/folders
- Verify
CLOUDINARY_PROJECT_NAMEis correct - Upload test images via Cloudinary dashboard
- Check that images have proper file extensions
- Check system prompt in
Helpers/qroq.ts - Verify tool descriptions are clear
- Ensure tool registry has required fields
Want to use Claude or GPT-4? Change the provider:
// Instead of Groq, use OpenAI compatible endpoint
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
baseURL: process.env.API_BASE_URL,
});Run models locally with llama.cpp:
# Install ollama or llama.cpp
# Then update your AI client to use local endpointHave an awesome game idea or feature?
- Fork the repo
- Create a new branch
- Add your changes
- Submit a pull request DOCS: https://github.com/pedroslopez/whatsapp-web.js/blob/main/example.js#L359
ISC - See LICENSE file for details
Have fun building cool tools and games! If you create something awesome, feel free to share it back with the community. Happy coding! 🚀
Made with ❤️ for WhatsApp game lovers