choco-bot
Version:
Whatsapp-bot
303 lines (255 loc) • 9.29 kB
JavaScript
const qrcode = require('qrcode-terminal');
const { Client, LocalAuth } = require('whatsapp-web.js');
const axios = require('axios');
const fs = require('fs');
const { Configuration, OpenAI } = require('openai');
const { exec } = require('child_process');
const { randomInt } = require('crypto'); // Added to generate random intervals
const client = new Client({
authStrategy: new LocalAuth()
});
const openai = new OpenAI({
apiKey: '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',
});
// Map to store the chat status for each chat
let chatStatus = {};
// Array to store the phone numbers of users with sudo privileges
const sudoUsers = ['19152168522@c.us']; // Replace 'your_phone_number' with your WhatsApp phone number
// Load chat status from JSON file
if (fs.existsSync('chatStatus.json')) {
const fileContent = fs.readFileSync('chatStatus.json');
if (fileContent) {
chatStatus = JSON.parse(fileContent);
}
}
client.on('qr', qr => {
qrcode.generate(qr, { small: true });
});
client.on('ready', () => {
console.log('Client is ready!');
});
client.on('message', async (msg) => {
const isFromBot = (msg.author === client.info.wid.user);
const chat = await msg.getChat();
const chatId = chat.id._serialized;
const senderId = msg.from._serialized;
const message = msg.body.trim();
const isFromAdmin = (senderId === '19152168522@c.us');
// Function to check if the sender is in the sudo array
const isSudoUser = sudoUsers.some(sudoUser => senderId === sudoUser);
// Function to check if the message starts with a specific command
const hasCommandPrefix = (command) => message.startsWith(command) || msg.fromMe;
// Function to generate a random interval
function getRandomInterval() {
return randomInt(2000, 5000); // Random interval between 2 to 4 seconds
}
// Function to get the sender's information
async function getMyNumberInfo(msg) {
const contact = await client.getContactById(msg.from);
const myNumberInfo = `Your phone number: ${msg.from}\nYour name: ${contact.name}`;
return myNumberInfo;
}
// Handle .mynumber command
if (hasCommandPrefix('.mynumber')) {
const myNumberInfo = await getMyNumberInfo(msg);
await msg.reply(myNumberInfo);
return;
}
if (!chatStatus[senderId]) {
chatStatus[senderId] = true;
await msg.reply('Welcome to the chat bot! Here are some commands you can use:\n- /start: Start the bot\n- /stop: Stop the bot\n- !everyone: Mention everyone\n- !meme: Get a random wholesome meme\n- !d: Delete a message (admin command)');
saveChatStatus();
return;
}
// Start or stop the bot for the current chat
if (hasCommandPrefix('/start')) {
chatStatus[chatId] = true;
await msg.reply('AI bot launched for this chat.');
saveChatStatus();
return;
}
if (hasCommandPrefix('/stop')) {
chatStatus[chatId] = false;
await msg.reply('AI bot stopped for this chat.');
saveChatStatus();
return;
}
// Check if the bot is active for the current chat
const isActive = chatStatus[chatId];
if (!isActive) return;
// Mention everyone
if (hasCommandPrefix('!everyone')) {
let text = '';
let mentions = [];
for (let participant of chat.participants) {
const contact = await client.getContactById(participant.id._serialized);
mentions.push(contact);
text += `@${participant.id.user} `;
}
await chat.sendMessage(text, { mentions });
return;
}
// Respond with a meme
if (hasCommandPrefix('!meme')) {
try {
const response = await axios.get('https://meme-api.com/gimme/wholesomememes/1');
const meme = response.data.memes[0];
await msg.reply(meme.url, undefined, { caption: meme.title });
} catch (error) {
console.error('Error fetching meme:', error);
await msg.reply('Failed to fetch a meme. Please try again later.');
}
return;
}
// Delete a message (admin command)
if (hasCommandPrefix('!d')) {
if (chat.isAdmin()) {
const quotedMsg = msg.quotedMsg;
if (!quotedMsg) {
await msg.reply('Reply to a message to delete it.');
return;
}
try {
await quotedMsg.delete();
} catch (error) {
console.error('Error deleting message:', error);
await msg.reply('Failed to delete the message. Please try again later.');
}
} else {
await msg.reply('This command is only for admins.');
}
return;
}
// Check bot status
if (hasCommandPrefix('.status')) {
const botStatus = chatStatus[chatId] ? 'Online' : 'Offline';
await msg.reply(`Bot status: ${botStatus}`);
return;
}
if (hasCommandPrefix('.ssudo')) {
const numberToAdd = message.split(' ')[1];
if (!sudoUsers.includes(numberToAdd)) {
sudoUsers.push(numberToAdd);
await msg.reply(`Added ${numberToAdd} to the sudo list.`);
} else {
await msg.reply(`The number ${numberToAdd} is already in the sudo list.`);
}
return;
}
if (hasCommandPrefix('.rsudo')) {
const numberToRemove = message.split(' ')[1];
const index = sudoUsers.indexOf(numberToRemove);
if (index !== -1) {
sudoUsers.splice(index, 1);
await msg.reply(`Removed ${numberToRemove} from the sudo list.`);
} else {
await msg.reply(`The number ${numberToRemove} is not found in the sudo list.`);
}
return;
}
if (hasCommandPrefix('.gsudo')) {
await msg.reply(`Sudo Users: ${sudoUsers.join(', ')}`);
return;
}
if (hasCommandPrefix('.edit')) {
handleFileEdit(msg);
return;
}
if (hasCommandPrefix('.share')) {
const content = message.slice(7); // Remove the ".share" prefix
const participants = chat.participants.filter(p => p.id.user !== senderId);
for (const participant of participants) {
const contact = await client.getContactById(participant.id._serialized);
const privateChat = await contact.getChat();
// Send the message with a random interval
setTimeout(async () => {
await privateChat.sendMessage(content);
}, getRandomInterval());
}
return;
}
// Handle conversation with AI
const previousMessages = await getPreviousMessages(msg.from);
const userMessage = { role: 'user', content: msg.body };
previousMessages.push(userMessage);
const aiResponse = await getAIResponse(previousMessages);
if (typeof aiResponse === 'string') {
// Send AI response as a text message
await msg.reply(aiResponse);
} else {
// Handle unexpected AI response
await msg.reply('AI response format is not supported. Please try again later.');
}
const aiReply = { role: 'assistant', content: aiResponse };
previousMessages.push(aiReply);
await saveMessage(msg.from, previousMessages);
});
async function handleFileEdit(msg) {
const editCommand = msg.body.trim().slice('.edit'.length).trim();
const [filename, content] = editCommand.split(' ');
if (!filename || !content) {
await msg.reply('Invalid command format. Usage: .edit <filename> <content>');
return;
}
const filePath = `${filename}`;
fs.writeFile(filePath, content, 'utf8', (err) => {
if (err) {
console.error('Error editing file:', err);
msg.reply(`Failed to edit the file ${filename}. Please try again later.`);
} else {
msg.reply(`File ${filename} has been updated successfully.`);
}
});
}
client.initialize();
// Function to append the current message to the JSON file
const saveMessage = async (number, messages) => {
const filePath = `${number}.json`;
try {
fs.writeFileSync(filePath, JSON.stringify(messages));
} catch (error) {
console.error('Error saving messages:', error);
}
};
// Function to retrieve previous messages from the JSON file
const getPreviousMessages = async (number) => {
const filePath = `${number}.json`;
try {
if (fs.existsSync(filePath)) {
const fileContent = fs.readFileSync(filePath);
const data = JSON.parse(fileContent);
return data;
}
} catch (error) {
console.error('Error retrieving previous messages:', error);
}
return [];
};
// Function to send messages to the AI and get a response
const getAIResponse = async (messages) => {
try {
const response = await openai.createChatCompletion({
model: 'gpt-3.5-turbo-16k',
messages: messages,
temperature: 0.5,
max_tokens: 1024,
top_p: 1,
frequency_penalty: 0,
presence_penalty: 0
});
const { choices } = response.data;
const reply = choices[0].message.content;
return reply;
} catch (error) {
console.error('Error getting AI response:', error);
return 'Failed to retrieve a response. Please try again later.';
}
};
// Function to save the chat status to the JSON file
const saveChatStatus = () => {
try {
fs.writeFileSync('chatStatus.json', JSON.stringify(chatStatus));
} catch (error) {
console.error('Error saving chat status:', error);
}
};