Hi community,
I’m trying to implement a webhook callback for the Meta (WhatsApp Business) API directly within a Coda pack. Currently, I have a working solution on Glitch that uses an Express server to receive incoming WhatsApp messages and automatically save them to a table in Coda.
Here’s how the flow works on Glitch:
- Meta sends a POST request to the server’s endpoint whenever a new WhatsApp message is received.
- The server verifies the message, extracts the text, and sends it to a table in Coda via Coda’s API.
- The server responds with a
200 OK
status code to confirm the webhook reception.
My goal is to replicate this flow within a Coda pack, eliminating the need for an external server like Glitch. Specifically, the pack should:
- Configure a webhook with Meta’s API to receive messages.
- Extract relevant data from the message (sender, text, timestamp, etc.).
- Automatically sync the data into a Coda table.
Here’s the current code I’m using in Glitch:
import express from "express";
import axios from "axios";
const app = express();
app.use(express.json());
const { WEBHOOK_VERIFY_TOKEN, GRAPH_API_TOKEN, CODA_API_TOKEN, CODA_DOC_ID, PORT } = process.env;
// POST route to handle incoming WhatsApp messages
app.post("/webhook", async (req, res) => {
console.log("Incoming webhook message:", JSON.stringify(req.body, null, 2));
const message = req.body.entry?.[0]?.changes?.[0]?.value?.messages?.[0];
// Verify that the message type is "text"
if (message?.type === "text") {
const messageBody = message.text.body; // Extract the message text
try {
// Send the message to the Coda table
await axios({
method: "POST",
url: `https://coda.io/apis/v1/docs/${CODA_DOC_ID}/tables/Registro_Mensajes/rows`,
headers: {
Authorization: `Bearer ${CODA_API_TOKEN}`,
"Content-Type": "application/json",
},
data: {
rows: [
{
cells: [
{
column: "Mensajes",
value: messageBody,
},
],
},
],
},
});
console.log("Message saved to Coda:", messageBody);
} catch (error) {
console.error("Error saving the message to Coda:", error.response?.data || error.message);
}
}
// Respond to WhatsApp with a 200 status code to confirm the webhook
res.sendStatus(200);
});
// GET route for initial webhook verification
app.get("/webhook", (req, res) => {
const mode = req.query["hub.mode"];
const token = req.query["hub.verify_token"];
const challenge = req.query["hub.challenge"];
if (mode === "subscribe" && token === WEBHOOK_VERIFY_TOKEN) {
res.status(200).send(challenge);
console.log("Webhook verified successfully!");
} else {
res.sendStatus(403);
}
});
// Start the server on the specified port
app.listen(PORT || 3000, () => {
console.log(`Server is listening on port: ${PORT || 3000}`);
});
Variable Breakdown:
- WEBHOOK_VERIFY_TOKEN: A token used to verify that the webhook request comes from Meta. It is compared with the value sent by Meta during the webhook setup.
- GRAPH_API_TOKEN: The access token for Meta’s API that authorizes requests to WhatsApp endpoints.
- CODA_API_TOKEN: The access token for Coda’s API to allow writing data to a specific table.
- CODA_DOC_ID: The ID of the Coda document containing the tables where the messages are stored.
- PORT: The port on which the Express server runs. Defaults to port 3000 if not defined.
Questions for the Community:
- Is it possible to replicate this flow directly in a Coda pack?
- How can I set up the pack to receive webhook callbacks, process them, and sync the data into a Coda table?
- Are there any examples of webhook setups in a Coda pack that I can use as a reference?
Any guidance or suggestions would be greatly appreciated. Thanks in advance!