const generateId = require('../../utils/generateId.util'); const { domain } = require('../../config').server; const whatsappEvents = require('../emitter'); const { callWebhook } = require('../webhook'); const { addConnection, updateConnection, addCurrentConnection, resetConnection } = require('../../services/connections.service'); const { objectMapper } = require('../../utils/commons.util'); const { sessionService } = require('..'); const logger = console; const connectionEventNames = ['connection:connect', 'connection:open', 'connection:close']; const messageEventNames = ['message:received', 'message:updated']; const eventTypeMapped = { 'message:received': 'wai.message.received', 'message:updated': 'wai.message.updated', }; const timeField = { sent: 'sendTime', delivered: 'deliverTime', read: 'readTime' }; const directionField = { 'message:received': 'inbound', 'message:updated': 'outbound' }; const webhookBodyBuilder = (messageData, messageType) => { const message = { id: `evt_${generateId().replace(/-/g, '')}`, type: eventTypeMapped[messageType], apiVersion: 'v2', webhooksource: 'wai', createTime: new Date(new Date().getTime() + 8 * 60 * 60 * 1000).toISOString(), // GMT +8 waiMessage: { ...messageData, ...(messageData.updateTime ? { [timeField[messageData.status]]: messageData.updateTime } : {}), wamid: messageData.id, direction: directionField[messageType], externalId: '-1', // todo: }, }; return message; }; const setupConnectionHandler = () => { // connectionEventNames.forEach(eventName => { logger.info(`Setting up event ${'connection:connect'}`); whatsappEvents.on('connection:connect', async connectionData => { try { // find Or create await addCurrentConnection({ ...objectMapper(connectionData, { phone: [{ key: 'wa_id' }, { key: 'sesson_id' }], channelId: 'channel_id', createTimestamp: 'createtime' }), service_type: 'baileys', status: 'connecting', }); } catch (error) { logger.error({ connectionData, error }, 'error add connection'); } }); logger.info(`Setting up event ${'connection:open'}`); whatsappEvents.on('connection:open', async connectionData => { logger.info(`event ${'connection:open'}`, connectionData); try { await updateConnection( { ...objectMapper(connectionData, { whatsAppNo: [{ key: 'wa_id' }, { key: 'sesson_id' }], channelId: 'channel_id' }), service_type: 'baileys', }, { connect_domain: domain }, ); } catch (error) { logger.error({ connectionData, error }, 'error add connection'); } }); logger.info(`Setting up event ${'connection:close'}`); whatsappEvents.on('connection:close', async connectionData => { try { sessionService.removeSession(connectionData.sesson_id); await updateConnection({ ...objectMapper(connectionData, { whatsAppNo: [{ key: 'wa_id' }, { key: 'sesson_id' }], channelId: 'channel_id' }), service_type: 'baileys', }); // todo: 通知前端: 重新扫码 } catch (error) { logger.error({ connectionData, error }, 'error add connection'); } }); // }); }; const setupMessageHandler = () => { messageEventNames.forEach(eventName => { logger.info(`Setting up event ${eventName}`); whatsappEvents.on(eventName, async messageData => { try { const x = webhookBodyBuilder(messageData, eventName); await callWebhook(x); } catch (error) { logger.error({ messageData, error }, 'error call webhook'); } }); }); }; function setupWhatsappHandler() { setupConnectionHandler(); setupMessageHandler(); } /** * 登出: 当前服务的所有连接 */ async function resetCurrentConnection() { await resetConnection(); } module.exports = { setupWhatsappHandler, resetCurrentConnection };