You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
261 lines
8.1 KiB
TypeScript
261 lines
8.1 KiB
TypeScript
import express from 'express';
|
|
import axios from 'axios';
|
|
import dotenv from 'dotenv';
|
|
|
|
// Load environment variables
|
|
dotenv.config();
|
|
|
|
const API_URL = process.env.API_URL;
|
|
const INSTANCE_NAME = process.env.INSTANCE_NAME;
|
|
const API_KEY = process.env.API_KEY;
|
|
const WEBHOOK_URL = process.env.WEBHOOK_URL;
|
|
const COMMUNITY_ID = process.env.COMMUNITY_ID;
|
|
|
|
if (!API_URL || !INSTANCE_NAME || !API_KEY || !WEBHOOK_URL || !COMMUNITY_ID) {
|
|
throw new Error('Required environment variables are not defined.');
|
|
}
|
|
|
|
// Store community and group information
|
|
const linkedGroups: Set<string> = new Set();
|
|
|
|
// Create an Express app
|
|
const app = express();
|
|
app.use(express.json());
|
|
|
|
// Fetch all groups and identify the community and linked groups
|
|
async function fetchGroups() {
|
|
try {
|
|
const response = await axios.get(`${API_URL}/group/fetchAllGroups/${INSTANCE_NAME}?getParticipants=false`, {
|
|
headers: {
|
|
apikey: API_KEY,
|
|
},
|
|
});
|
|
|
|
console.log('API Response:', response.data); // Log the full response
|
|
|
|
// Check if the response is an array of groups
|
|
if (Array.isArray(response.data)) {
|
|
for (const group of response.data) {
|
|
if (group.id === COMMUNITY_ID) {
|
|
// This is the community
|
|
console.log(`Community ID: ${COMMUNITY_ID}`);
|
|
} else if (group.linkedParent === COMMUNITY_ID) {
|
|
// This is a group linked to the community
|
|
linkedGroups.add(group.id);
|
|
console.log(`Linked Group ID: ${group.id}`);
|
|
}
|
|
}
|
|
} else {
|
|
console.error('Unexpected response format:', response.data);
|
|
}
|
|
} catch (error) {
|
|
console.error('Error fetching groups:', error.response ? error.response.data : error.message);
|
|
}
|
|
}
|
|
|
|
// Add the bot to a new group
|
|
async function addBotToGroup(groupId: string) {
|
|
try {
|
|
await axios.post(`${API_URL}/group/invite`, {
|
|
groupId,
|
|
participants: ['your-bot-phone-number'], // Replace with your bot's phone number
|
|
}, {
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
apikey: API_KEY,
|
|
},
|
|
});
|
|
console.log(`Bot added to group: ${groupId}`);
|
|
} catch (error) {
|
|
console.error('Error adding bot to group:', error);
|
|
}
|
|
}
|
|
|
|
// Webhook endpoint
|
|
|
|
app.post('/webhook', (req, res) => {
|
|
const event = req.body;
|
|
console.log('Received event:', JSON.stringify(event, null, 2)); // Log the full event
|
|
|
|
// Handle the event
|
|
if (event.event === 'messages.upsert') {
|
|
const messageData = event.data;
|
|
|
|
// Ignore messages sent by the bot itself
|
|
// if (messageData.key.fromMe) {
|
|
// console.log('Ignoring message sent by the bot itself');
|
|
// return res.status(200).send('OK');
|
|
// }
|
|
|
|
// Handle the message
|
|
handleMessage(messageData);
|
|
} else if (event.event === 'group_create' && event.data.parentGroupId === COMMUNITY_ID) {
|
|
// A new group was created in the community
|
|
const groupId = event.data.groupId;
|
|
linkedGroups.add(groupId);
|
|
addBotToGroup(groupId);
|
|
}
|
|
|
|
res.status(200).send('OK');
|
|
});
|
|
|
|
// Handle incoming messages
|
|
function handleMessage(messageData: any) {
|
|
// console.log('Incoming message data:', JSON.stringify(messageData, null, 2)); // Log the full message data
|
|
|
|
const body = messageData.message?.conversation;
|
|
const sender = messageData.key.remoteJid;
|
|
const groupId = messageData.key.remoteJid; // Group ID for community messages
|
|
|
|
// Check if the message is from a group linked to the community
|
|
if (groupId && linkedGroups.has(groupId) && body) {
|
|
// Parse the command
|
|
if (body.startsWith('/tarea')) {
|
|
// Remove the "/tarea" prefix and trim any extra spaces
|
|
const command = body.replace('/tarea', '').trim();
|
|
|
|
// Split the remaining command into action and arguments
|
|
const [action, ...args] = command.split(' ');
|
|
console.log('Parsed action:', action); // Log the action
|
|
console.log('Parsed args:', args); // Log the arguments
|
|
|
|
const description = args.join(' ');
|
|
console.log('Description:', description); // Log the description
|
|
|
|
// Extract assigned user (if any)
|
|
const assignedUserMatch = description.match(/@\w+/);
|
|
const assignedUser = assignedUserMatch ? assignedUserMatch[0] : null;
|
|
|
|
// Extract due date (if any)
|
|
const dueDateMatch = description.match(/\d{4}-\d{2}-\d{2}/);
|
|
const dueDate = dueDateMatch ? dueDateMatch[0] : null;
|
|
|
|
// Remove the assigned user and due date from the description
|
|
const cleanDescription = description
|
|
.replace(/@\w+/g, '') // Remove assigned user
|
|
.replace(/\d{4}-\d{2}-\d{2}/g, '') // Remove due date
|
|
.trim(); // Remove extra spaces
|
|
|
|
if (action === 'nueva') {
|
|
// If no user is assigned, default to the sender
|
|
const finalAssignedUser = assignedUser || `@${sender.split('@')[0]}`;
|
|
createTask(sender, cleanDescription, finalAssignedUser, dueDate);
|
|
} else if (action === 'asignar') {
|
|
const taskId = args[0];
|
|
if (assignedUser) {
|
|
assignTask(sender, taskId, assignedUser);
|
|
} else {
|
|
sendMessage(sender, 'Debes mencionar a un usuario para asignar la tarea. Ejemplo: /tarea asignar 1 @usuario');
|
|
}
|
|
} else if (action === 'completar') {
|
|
const taskId = args[0];
|
|
completeTask(sender, taskId);
|
|
} else {
|
|
sendMessage(sender, 'Acción no reconocida. Usa /tarea nueva, /tarea asignar, o /tarea completar.');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// Create a new task
|
|
function createTask(sender: string, description: string, assignedUser?: string, dueDate?: string) {
|
|
const task = {
|
|
id: tasks.length + 1,
|
|
description,
|
|
assignedTo: assignedUser || null,
|
|
dueDate: dueDate || null,
|
|
completed: false,
|
|
};
|
|
tasks.push(task);
|
|
sendMessage(sender, `Tarea creada: ${task.id} - ${task.description}${assignedUser ? ` asignada a ${assignedUser}` : ''}${dueDate ? ` para el ${dueDate}` : ''}`);
|
|
}
|
|
|
|
// Assign a task
|
|
function assignTask(sender: string, taskId: string, assignedUser: string) {
|
|
const task = tasks.find((t) => t.id === parseInt(taskId));
|
|
if (task) {
|
|
task.assignedTo = assignedUser;
|
|
sendMessage(sender, `Tarea ${taskId} asignada a ${assignedUser}`);
|
|
} else {
|
|
sendMessage(sender, `Tarea ${taskId} no encontrada`);
|
|
}
|
|
}
|
|
|
|
// Mark a task as completed
|
|
function completeTask(sender: string, taskId: string) {
|
|
const task = tasks.find((t) => t.id === parseInt(taskId));
|
|
if (task) {
|
|
task.completed = true;
|
|
sendMessage(sender, `Tarea ${taskId} marcada como completada`);
|
|
} else {
|
|
sendMessage(sender, `Tarea ${taskId} no encontrada`);
|
|
}
|
|
}
|
|
|
|
// Send a message
|
|
async function sendMessage(phone: string, message: string) {
|
|
try {
|
|
await axios.post(`${API_URL}/message/sendText/${INSTANCE_NAME}`, {
|
|
number: phone,
|
|
text: message,
|
|
}, {
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
apikey: API_KEY,
|
|
},
|
|
});
|
|
} catch (error) {
|
|
console.error('Error sending message:', error);
|
|
}
|
|
}
|
|
|
|
// In-memory task storage
|
|
const tasks: any[] = [];
|
|
|
|
// Start the webhook server
|
|
const PORT = 3000;
|
|
app.listen(PORT, () => {
|
|
console.log(`Webhook server running on port ${PORT}`);
|
|
});
|
|
|
|
// Configure the webhook in Evolution API
|
|
async function configureWebhook() {
|
|
try {
|
|
const response = await axios.post(
|
|
`${API_URL}/webhook/set/${INSTANCE_NAME}`,
|
|
{
|
|
webhook: {
|
|
url: WEBHOOK_URL, // Use the environment variable
|
|
enabled: true,
|
|
webhook_by_events: true,
|
|
webhook_base64: true,
|
|
events: [
|
|
'MESSAGES_UPSERT', // New or updated messages
|
|
'GROUPS_UPSERT', // New or updated groups
|
|
'GROUP_PARTICIPANTS_UPDATE', // Group participant changes
|
|
'GROUP_UPDATE', // Group metadata changes (optional)
|
|
],
|
|
},
|
|
},
|
|
{
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
apikey: API_KEY,
|
|
},
|
|
}
|
|
);
|
|
console.log('Webhook configured successfully:', response.data);
|
|
} catch (error) {
|
|
console.error('Error configuring webhook:', error.response ? error.response.data : error.message);
|
|
}
|
|
}
|
|
|
|
// Fetch groups and configure the webhook when the bot starts
|
|
async function startBot() {
|
|
await fetchGroups();
|
|
await configureWebhook();
|
|
}
|
|
|
|
startBot();
|