From 3e88b27021c868118eedfc53961940bf1a46a777 Mon Sep 17 00:00:00 2001 From: adriano Date: Fri, 9 Aug 2024 16:45:25 -0300 Subject: [PATCH] feat: add 24-hour window and service category for official WhatsApp conversations in Redis; implement method to send billing info to API for Grafana usage report --- backend/src/controllers/WhatsAppController.ts | 97 ++++++++++++++++++- backend/src/helpers/RedisClient.ts | 40 ++++++++ 2 files changed, 136 insertions(+), 1 deletion(-) diff --git a/backend/src/controllers/WhatsAppController.ts b/backend/src/controllers/WhatsAppController.ts index 0158748..b442e79 100644 --- a/backend/src/controllers/WhatsAppController.ts +++ b/backend/src/controllers/WhatsAppController.ts @@ -41,7 +41,10 @@ import { getSettingValue } from "../helpers/WhaticketSettings"; import ListWhatsAppsNumber from "../services/WhatsappService/ListWhatsAppsNumber"; import SettingTicket from "../models/SettingTicket"; import { Op } from "sequelize"; -import { del, get, set } from "../helpers/RedisClient"; +import { del, get, getKeysByPattern, set, setCBPWhatsappOfficial } from "../helpers/RedisClient"; + +import axios from "axios"; + interface WhatsappData { name: string; @@ -214,6 +217,48 @@ export const weebhook = async ( return res.sendStatus(500); } + if( + req?.body?.entry?.length > 0 && + req?.body?.entry[0]?.changes?.length > 0 && + req?.body?.entry[0]?.changes?.length > 0 && + req?.body?.entry[0]?.changes[0]?.value?.statuses?.length>0 && + req?.body?.entry[0]?.changes[0]?.value?.statuses[0]?.recipient_id && + req?.body?.entry[0]?.changes[0]?.value?.statuses[0]?.conversation?.origin?.type){ + + const company_phone = req?.body?.entry[0]?.changes[0]?.value?.metadata?.display_phone_number + const client_phone = req?.body?.entry[0]?.changes[0]?.value?.statuses[0]?.recipient_id + const conversation_type = req?.body?.entry[0]?.changes[0]?.value?.statuses[0].conversation.origin.type + const billable = req?.body?.entry[0]?.changes[0]?.value?.statuses[0].pricing.billable + const pricing_model = req?.body?.entry[0]?.changes[0]?.value?.statuses[0].pricing.pricing_model + const conversation_type_category = req?.body?.entry[0]?.changes[0]?.value?.statuses[0].pricing.category + const msg_id = req?.body?.entry[0]?.changes[0]?.value?.statuses[0].id + + const _contact_to_exist = await get({ + key: "whatsapp:*", + value: `${company_phone}` + }); + + if(_contact_to_exist){ + + const lst_services_cbp = await getKeysByPattern(company_phone, client_phone, conversation_type_category) + + if(lst_services_cbp && lst_services_cbp.length > 0){ + for(const item of lst_services_cbp){ + if(!item.split(':').includes(conversation_type_category)){ + await setCBP(msg_id, company_phone, client_phone, conversation_type_category, billable, pricing_model) + } + } + }else{ + await setCBP(msg_id, company_phone, client_phone, conversation_type_category, billable, pricing_model) + + } + + console.log('_contact_to_exist: ', _contact_to_exist) + } + + + } + // MESSAGE if (req.body.object) { if ( @@ -626,3 +671,53 @@ const checkWhatsAppData = ({ return { message: "urlApi is required!" }; } }; + +async function setCBP(msg_id: any, company_phone: any, client_phone: any, conversation_type_category: any, billable:string, pricing_model:string) { + const message = await Message.findByPk(msg_id) + + if (message) { + await setCBPWhatsappOfficial(company_phone, client_phone, conversation_type_category, msg_id, `${message.ticketId}`) + + await sendToAPIUsage(msg_id, + company_phone, + client_phone, + conversation_type_category, + `${message.ticketId}`, + billable, + pricing_model + ) + } +} + + + +async function sendToAPIUsage(msg_id: any, company_phone: any, client_phone: any, conversation_type_category: any, ticketId: any, billable:string, pricing_model:string) { + const data = JSON.stringify({ + "companyId": company_phone, + "provider": "meta", + "product": "whatsapp", + "type": conversation_type_category, + "msgId": msg_id, + "ticketId": `${ticketId}`, + "billable": billable, + "pricing_model": pricing_model + }); + + const config = { + method: 'post', + url: 'http://172.31.187.24:6008/api/v1/billing/usage-whatsapp', + headers: { + 'Authorization': 'Bearer 2ivck10D3o9qAZi0pkKudVDl9bdEVXY2s8gdxZ0jYgL1DZWTgDz6wDiIjlWgYmJtVOoqf0b42ZTLBRrfo8WoAaScRsujz3jQUNXdchSg0o43YilZGmVhheGJNAeIQRknHEll4nRJ7avcFgmDGoYbEey7TSC8EHS4Z3gzeufYYSfnKNDBwwzBURIQrTOxYFe3tBHsGOzwnuD2lU5tnEx7tr2XRO4zRNYeNY4lMBOFM0mRuyAe4kuqTrKXmJ8As200', + 'Content-Type': 'application/json' + }, + data: data + }; + + try { + const response = await axios(config); + console.log('Response from whatsapp api usage: ',JSON.stringify(response.data)); + } catch (error) { + console.log('Error on try register the whatsapp usage: ', error); + } + +} \ No newline at end of file diff --git a/backend/src/helpers/RedisClient.ts b/backend/src/helpers/RedisClient.ts index 2520588..19c828d 100644 --- a/backend/src/helpers/RedisClient.ts +++ b/backend/src/helpers/RedisClient.ts @@ -158,6 +158,46 @@ export async function findObject( return result; } +export async function setCBPWhatsappOfficial( + company_phone:string, + client_phone:string, + conversation_type:string, + msg_id: string, + ticketId?: string +) { + const key = `company_phone:${company_phone}:client_phone:${client_phone}:conversation_type:${conversation_type}`; + const result = await redis.hmset( + key, + "company_phone", + company_phone, + "client_phone", + client_phone, + "conversation_type", + conversation_type, + "msg_id", + msg_id, + "ticketId", + ticketId + ); + + await redis.expire(key, 86400); +} + + +export async function getKeysByPattern(company_phone:string, client_phone:string, conversation_type:string,) { + const pattern = `company_phone:${company_phone}:client_phone:${client_phone}:conversation_type:${conversation_type}*`; + const keys = []; + let cursor = "0"; + + do { + const result = await redis.scan(cursor, "MATCH", pattern, "COUNT", 100); + cursor = result[0]; + keys.push(...result[1]); + } while (cursor !== "0"); + + return keys; +} + export async function deleteObject( whatsappId: string, contactId: string,