/*
* Starter Project for WhatsApp Echo Bot Tutorial
*
* Remix this as the starting point for following the WhatsApp Echo Bot tutorial
*
*/
"use strict";
// Access token for your app -
// (copy token from DevX getting started page
// and save it as environment variable into the .env file)
const token = process.env.WHATSAPP_TOKEN;
const { system_prompt } = require('./prompts');
// Imports dependencies and set up http server
const request = require("request"),
express = require("express"),
body_parser = require("body-parser"),
axios = require("axios").default,
app = express().use(body_parser.json()), // creates express http server
FormData = require("form-data"),
fs = require("fs").promises;
// Sets server port and logs message on success
app.listen(process.env.PORT || 1337, () => console.log("webhook is listening"));
async function WriteTempFile(tempPath, contenido) {
try {
await fs.writeFile(tempPath, contenido);
console.log("Archivo guardado con éxito");
} catch (error) {
console.error("Error al guardar archivo: ", error);
}
}
##Endpoint utilizado para recibir los mensajes generados por la conversacion
// Accepts POST requests at /webhook endpoint
app.post("/webhook", async (req, res) => {
try {
let body = req.body;
//console.log(JSON.stringify(req.body, null, 2));
let response_core_ai = null;
let response_whatsapp = null;
let msg_body = null;
let media_id = null;
let response_url_audio = null;
let phone_number_id = null;
let from = null;
let conversation_id = null;
##Conversation text, no se usa para imagenes o audio
if (req.body.object) {
if (
req.body.entry &&
req.body.entry[0].changes &&
req.body.entry[0].changes[0] &&
req.body.entry[0].changes[0].value.messages &&
req.body.entry[0].changes[0].value.messages[0]
) {
phone_number_id =
req.body.entry[0].changes[0].value.metadata.phone_number_id;
from = req.body.entry[0].changes[0].value.messages[0].from;
//console.log(req.body.entry[0].changes[0].value.messages[0].text.body);
// get conversation_id for previous conversation
conversation_id = await axios({
method: "GET",
url:
"https://exp-api-dev.hunty.cloud/core-ai/get_last_conversation_id?" +
"user_id=" +
from,
headers: { "Content-Type": "application/json" },
}).catch((error) => {
console.error(error);
throw new Error("Error en la promesa de respuesta del API Core AI.");
});
console.log("conversation_id=" + conversation_id.data);
conversation_id = conversation_id.data;
//
if (req.body.entry[0].changes[0].value.messages[0].type === "text") {
msg_body = req.body.entry[0].changes[0].value.messages[0].text.body;
console.log(msg_body);
//let conversation_id = "0";
if (msg_body.includes("RESET CHAT")) {
conversation_id = Number(conversation_id) + 1
if (conversation_id === 1) {conversation_id = 2};
msg_body = msg_body.replace("RESET CHAT: ", "");
};
response_core_ai = await axios({
method: "POST",
url:
"https://exp-api-dev.hunty.cloud/core-ai/base_conversation?prompt=" +
msg_body +
"&conversation_id=" +
conversation_id +
"&user_id=" +
from +
"&system_prompt=" +
system_prompt +
"&model_name=" +
"gpt-4",
headers: { "Content-Type": "application/json" },
}).catch((error) => {
console.error(error);
throw new Error(
"Error en la promesa de respuesta del API Core AI."
);
});
if (response_core_ai.status && response_core_ai.status === 200) {
console.log(response_core_ai.data.response);
//if (from === "5493492507816") {
// from = "54349215507816";
//}
let data_send = {
messaging_product: "whatsapp",
type: "text",
to: from,
recipient_type: "individual",
text: { body: response_core_ai.data.response },
};
//console.log(data_send);
response_whatsapp = axios({
method: "POST",
url:
"https://graph.facebook.com/v16.0/" +
"103749432565035" +
"/messages",
data: data_send,
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + token,
},
}).catch((error) => {
console.error(error);
throw new Error(
"Error en la promesa de respuesta del API de WhatsApp."
);
});
} else {
res.sendStatus(424);
}
## Audio conversation, no se usa para texto
} else if (
req.body.entry[0].changes[0].value.messages[0].type === "audio"
) {
console.log("Comienza el audio test");
media_id = req.body.entry[0].changes[0].value.messages[0].audio.id;
response_url_audio = await axios({
method: "GET",
url: "https://graph.facebook.com/v16.0/" + media_id,
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + token,
},
}).catch((error) => {
console.error(error);
throw new Error(
"Error en la promesa de respuesta del API de WhatsApp para descargar url de archivo de audio."
);
});
console.log(response_url_audio);
let url = String(response_url_audio.data.url);
console.log(url);
let response_audio = await axios({
method: "GET",
url: url,
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + token,
},
}).catch((error) => {
console.error(error);
throw new Error(
"Error al usar la URL proporcionada por whatsapp api."
);
});
console.log(response_audio);
let audio_file = response_audio.data;
let form_data = new FormData();
let response_core_ai = null;
form_data.append(
"audio_file",
audio_file,
from + "_" + media_id + "_audio.ogg"
);
response_core_ai = await axios({
method: "POST",
url:
"https://exp-api-dev.hunty.cloud/core-ai/conversation/process_audio?" +
"user_id=" +
from +
"&conversation_id=3&language=es",
data: form_data,
headers: {
accept: "application/json",
},
}).catch((error) => {
console.error(error);
throw new Error("Error al enviar la solicitud POST.");
});
console.log(response_core_ai);
if (response_core_ai.status && response_core_ai.status === 200) {
let response_audio_assistant = await axios({
method: "GET",
url: response_url_audio.url,
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + token,
},
}).catch((error) => {
console.error(error);
throw new Error(
"Error al usar la URL proporcionada por whatsapp api."
);
});
console.log(response_audio_assistant);
let audio_file_assistant = response_audio_assistant.data;
let form_data_assistant_response = new FormData();
if (from === "5493492507816") {
from = "54349215507816";
}
let fs = require("fs");
let path = require("path");
// Generar un nombre de archivo único y temporal
let uniqueFileName = `${Date.now()}-${Math.round(
Math.random() * 1e9
)}.wav`;
// Ruta donde se guardará el archivo temporal
let tempPath = path.join(__dirname, "temp", uniqueFileName);
// Escribir datos en el archivo temporal
WriteTempFile();
fs.writeFile(tempPath, audio_file_assistant, (err) => {
if (err) throw err;
});
let response_media_id_whatsapp = null;
let form_data_whatsapp_audio_media = new FormData();
form_data_whatsapp_audio_media.append(
"file",
fs.createReadStream(tempPath)
);
form_data_whatsapp_audio_media.append("type", "image/jpeg");
form_data_whatsapp_audio_media.append(
"messaging_product",
"whatsapp"
);
response_media_id_whatsapp = await axios({
method: "POST",
url: "https://graph.facebook.com/v16.0/" + media_id + "/media",
data: form_data_whatsapp_audio_media,
headers: {
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + token,
...form_data_whatsapp_audio_media.getHeaders(),
},
},
}).catch((error) => {
console.error(error);
});
console.log(response_media_id_whatsapp);
let data_send = {
messaging_product: "whatsapp",
type: "audio",
to: from,
recipient_type: "individual",
audio: { id: response_media_id_whatsapp.id },
};
response_whatsapp = await axios({
method: "POST",
url:
"https://graph.facebook.com/v16.0/" +
"103749432565035" +
"/messages",
data: data_send,
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + token,
},
}).catch((error) => {
console.error(error);
throw new Error(
"Error en la promesa de respuesta del API de WhatsApp."
);
});
console.log(response_whatsapp);
} else {
res.sendStatus(424);
}
}
res.sendStatus(200);
} else {
res.sendStatus(404);
}
} else {
res.sendStatus(404);
}
} catch (error) {
console.error(error);
res.status(500).send("Internal Server Error");
}
});
## Este endpoint es usado para verificar la conexion del webhook desde Facebook API no se utiliza para otra cosa.
## Accepts GET requests at the /webhook endpoint. You need this URL to setup webhook initially.
## info on verification request payload: https://developers.facebook.com/docs/graph-api/webhooks/getting-started#verification-requests
app.get("/webhook", (req, res) => {
/**
* UPDATE YOUR VERIFY TOKEN
*This will be the Verify Token value when you set up webhook
**/
const verify_token = process.env.VERIFY_TOKEN;
// Parse params from the webhook verification request
let mode = req.query["hub.mode"];
let token = req.query["hub.verify_token"];
let challenge = req.query["hub.challenge"];
// Check if a token and mode were sent
if (mode && token) {
// Check the mode and token sent are correct
if (mode === "subscribe" && token === verify_token) {
// Respond with 200 OK and challenge token from the request
console.log("WEBHOOK_VERIFIED");
res.status(200).send(challenge);
} else {
// Responds with '403 Forbidden' if verify tokens do not match
res.sendStatus(403);
}
}
});
2023-04-24 05:36:20.491761: I tensorflow/core/platform/cpu_feature_guard.cc:193] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX2 AVX512F AVX512_VNNI FMA
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
2023-04-24 05:36:20.596101: I tensorflow/core/util/util.cc:169] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.
2023-04-24 05:36:20.600470: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory
2023-04-24 05:36:20.600486: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.
2023-04-24 05:36:20.624086: E tensorflow/stream_executor/cuda/cuda_blas.cc:2981] Unable to register cuBLAS factory: Attempting to register factory for plugin cuBLAS when one has already been registered
2023-04-24 05:36:21.132174: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer.so.7'; dlerror: libnvinfer.so.7: cannot open shared object file: No such file or directory
2023-04-24 05:36:21.132229: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer_plugin.so.7'; dlerror: libnvinfer_plugin.so.7: cannot open shared object file: No such file or directory
2023-04-24 05:36:21.132236: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Cannot dlopen some TensorRT libraries. If you would like to use Nvidia GPU with TensorRT, please make sure the missing libraries mentioned above are installed properly.
/root/venv/lib/python3.9/site-packages/pinecone/index.py:4: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
from tqdm.autonotebook import tqdm