Nodejs:如何使用whatsapp api云发送多条消息?

问题描述 投票:0回答:1

我有一个问题,当我通过 api webhook 向 Whatsapp 发送多条消息时,它会陷入循环,即使我正在验证为每条发送的消息返回 200 状态

我有一个循环来一条一条地发送消息,我将这些消息存储在一个对象数组中,其中发送到 Whatsapp 的每种类型的消息都在其中。我什至每发送一条消息都会有2秒的延迟,但是它陷入了一个循环,对于我发送的每一条响应,它都不停地响应,直到我重新启动服务器

我不知道还能尝试什么,我什至有一个过滤器来尝试避免在一定时间内收到的消息,以避免重复接收它们,但什么也没有。甚至在Supabase中创建一个DB来调用已经发送的消息并验证它做了多少以避免重复消息

我请求你的帮助,因为我不知道现在还能尝试什么,我提前感谢任何类型的帮助,请帮助

async function sendMessagesToWhatsApp(messages: any[]): Promise<void> {
    for (const msg of messages) {
        try {
            await SendMessageWhatsApp(msg);
            await delay(2000); // Wait 2 seconds between messages
        } catch (error) {
            await registerEvents(msg, 500, "Server Error Internal", String(error));
        }
    }
}

export const receiveMessage = async (req: Request, res: Response, next: NextFunction) => {

    let entry = req.body.entry[0];
    let changes = entry.changes[0];
    let value = changes.value;

    try {

        // First we record the log
        await registerEvents(req.body, 200, "Get Webhook Whatsapp Api Cloud", null);

        const messageReceived = req.body;

        if (!messageReceived) {
            // No message received but a status 200 is returned to avoid errors
            console.log('evaluating when nothing is received in the body');
            res.sendStatus(200)
        }


        let messageObject = value?.messages ?? undefined;
        const changesResult = messageReceived.entry[0].changes[0].value;

        if (changesResult?.statuses !== undefined) {

            const messageStatus = messageReceived.entry[0].changes[0].value.statuses[0].status;

            if (messageStatus === "sent") {
                res.sendStatus(200);
            }

            if (messageStatus === "delivered") {
                res.sendStatus(200);
            }

            if (messageStatus === "read") {
                res.sendStatus(200);
            }

            if (messageStatus === "failed") {
                await registerEvents(messageReceived, 500, "Webhook Events", "Message Failed");
                res.sendStatus(200);
            }

        } else {

            if (messageObject !== undefined) {

                messageObject = messageObject.filter((message) => message.timestamp > (Date.now() - 1000 * 60 * 60 * 0.2) / 1000);

                if (messageObject.length > 0) {
                    const messages: Message = messageObject[0];
                    const from = messageObject[0]?.from;

                    // Type message
                    let typeMessage = messages?.type;

                    // validate the type of messaging
                    if (typeMessage === "text") {
                        sendStatusMessage("Typing...", from);
                        const messagesToSend = await textProcess(messages, from);
                        if (Array.isArray(messagesToSend)) {
                            sendMessagesToWhatsApp(messagesToSend)
                                .then(() => {
                                    console.log("Messages sent successfully.");
                                    res.sendStatus(200);
                                })
                                .catch(error => {
                                    console.error("Error sending messages:", error);
                                    res.sendStatus(200);
                                });
                        } else {
                            SendMessageWhatsApp(messagesToSend);
                            res.sendStatus(200);
                        }
                    }

                    if (typeMessage === "audio") {
                        console.log('is audio');
                        const data = await audioProcess(messages, from);
                        SendMessageWhatsApp(data);
                        res.sendStatus(200);
                    }

                    if (typeMessage === "button") {
                        const data = await buttonProcess(messages, from);
                        SendMessageWhatsApp(data);
                        res.sendStatus(200);
                    }

                    if (typeMessage === "interactive") {
                        const data = await interactiveProcess(messages, from);
                        SendMessageWhatsApp(data);
                        res.sendStatus(200);
                    }
                } else {
                    // when resubmitted they still contain the timestamp from when they were initially sent
                    console.log('The message was filtered by the sending time');
                    res.sendStatus(200);
                }

            } else {
                res.sendStatus(200);
            }
        }


    } catch (error) {

        console.log(error);

        await registerEvents(req.body, 500, "Error Webhook Whatsapp Api Cloud", error)
        // Evitar lopp webhook
        console.log('An internal server error occurred but 200 should always be sent');
        res.sendStatus(200);
    }

}

async function textProcess(messages: Message, from: string) {

    let message = messages.text.body;
    const answer = await askOpenAI(message);

    const answertoLowerCase = answer.toLocaleLowerCase();

    if (answertoLowerCase.includes("app")) {

        const ifAnswerIsMarkdown = isMarkdownFormat(answer);

        if (ifAnswerIsMarkdown) {
            const formattedContent = parseMarkdown(answer);
            const messages_ = buildDataToWhatsapp(formattedContent, from);

            console.log('lenght msj', messages_.length);

            // for await (const msg of messages_) {
            //     SendMessageWhatsApp(msg);
            //     await delay(2000); // Espera un tiempo entre cada mensaje
            // }
            return messages_

        } else {
            console.log('no need to format the text because it is not markdown');
            const dataToSend = {
                "messaging_product": "whatsapp",
                "recipient_type": "individual",
                "to": from,
                "type": "text",
                "text": {
                    "preview_url": false,
                    "body": answer
                }
            }
            // SendMessageWhatsApp(dataToSend);
            return dataToSend
        }
    } else {
        const dataToSend = {
            "messaging_product": "whatsapp",
            "recipient_type": "individual",
            "to": from,
            "type": "text",
            "text": {
                "preview_url": false,
                "body": answer
            }
        }
        return dataToSend
    }
}
node.js webhooks whatsapp whatsapi whatsapp-cloud-api
1个回答
0
投票

嗯..代码中有多个地方正在执行 res.sendStatus(200) 。发送响应后,在同一周期内尝试发送另一个响应将导致错误。如果您没有看到这些错误,则可能您没有进入多个分支,但需要注意这一点。 确保当您通过 SendMessageWhatsApp 发送消息时,不会导致再次调用 receiveMessage。

UPD 考虑通过将唯一标识符与每条消息关联来实现幂等处理。在处理消息之后和发回任何响应之前,将此 ID 存储在您的数据库中。对于每条传入消息,请检查该 ID 是否已存在于您的数据库中。如果是,则不处理该消息,仅发回 200 状态。

© www.soinside.com 2019 - 2024. All rights reserved.