Skip to main content

Build a WhatsApp & Messaging Bot

Learning Path

Level 4, Step 4.7 β€” Learning Path. Prerequisites: Using the API, any completed Build project.

Messaging platforms are where your customers already are. This project shows you how to connect your CiniterFlow AI agent to WhatsApp, Slack, and Microsoft Teams so users can chat with your agent directly from their favorite messaging app.

What You'll Build​

A messaging bot that:

  • Receives messages from WhatsApp, Slack, or Teams
  • Processes them through your CiniterFlow agent
  • Sends the AI response back to the user
  • Handles text, images, and other media
  • Maintains conversation context across messages

How It Works​

The pattern is the same for all messaging platforms:

User sends message on WhatsApp/Slack/Teams
β†’ Messaging platform sends a webhook to your middleware
β†’ Middleware calls CiniterFlow Prediction API
β†’ CiniterFlow processes the message and returns a response
β†’ Middleware sends the response back to the messaging platform
β†’ User sees the AI response

You need a small piece of middleware (a simple server) that sits between the messaging platform and CiniterFlow. This middleware translates messages between the platform's format and CiniterFlow's API format.

Part 1: Build Your CiniterFlow Agent First​

Before connecting to any messaging platform, build and test your agent in CiniterFlow:

  1. Create an Agentflow (or Chatflow) with your desired behavior
  2. Add your system prompt, tools, and knowledge bases
  3. Test thoroughly using the built-in chat panel
  4. Note your Flow ID (from the URL or the API button)
  5. Create an API Key for your flow (Settings β†’ API Keys)

Your agent's API endpoint will be:

POST https://flow.ciniter.com/api/v1/prediction/{your-flow-id}

Part 2: WhatsApp Integration​

Option A: Using the CiniterFlow API Directly​

The simplest approach β€” build a small webhook server that connects WhatsApp Business API to CiniterFlow.

Step 1: Set up WhatsApp Business API

  1. Create a Meta Business account at business.facebook.com
  2. Set up a WhatsApp Business App in the Meta Developer Portal
  3. Get your WhatsApp Business API token and phone number ID

Step 2: Create a Webhook Server

Here's a minimal Node.js server that bridges WhatsApp and CiniterFlow:

const express = require('express');
const app = express();
app.use(express.json());

const CINITERFLOW_API = 'https://flow.ciniter.com/api/v1/prediction/your-flow-id';
const CINITERFLOW_KEY = 'your-ciniterflow-api-key';
const WHATSAPP_TOKEN = 'your-whatsapp-token';
const PHONE_NUMBER_ID = 'your-phone-number-id';
const VERIFY_TOKEN = 'your-verify-token';

// Webhook verification (required by Meta)
app.get('/webhook', (req, res) => {
if (req.query['hub.verify_token'] === VERIFY_TOKEN) {
res.send(req.query['hub.challenge']);
} else {
res.sendStatus(403);
}
});

// Handle incoming messages
app.post('/webhook', async (req, res) => {
res.sendStatus(200); // Acknowledge immediately

const entry = req.body.entry?.[0];
const message = entry?.changes?.[0]?.value?.messages?.[0];
if (!message) return;

const userPhone = message.from;
const userText = message.text?.body || '';

try {
// Call CiniterFlow
const response = await fetch(CINITERFLOW_API, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${CINITERFLOW_KEY}`
},
body: JSON.stringify({
question: userText,
overrideConfig: { sessionId: userPhone }
})
});

const data = await response.json();
const aiReply = data.text || data.answer || 'Sorry, I could not process your request.';

// Send reply via WhatsApp
await fetch(`https://graph.facebook.com/v18.0/${PHONE_NUMBER_ID}/messages`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${WHATSAPP_TOKEN}`
},
body: JSON.stringify({
messaging_product: 'whatsapp',
to: userPhone,
text: { body: aiReply }
})
});
} catch (error) {
console.error('Error:', error);
}
});

app.listen(3000, () => console.log('Webhook server running on port 3000'));

Key detail: We use the user's phone number as the sessionId. This means CiniterFlow maintains separate conversation history for each WhatsApp user automatically.

Step 3: Deploy and Configure

  1. Deploy this server to any hosting platform (Vercel, Railway, Render, etc.)
  2. In the Meta Developer Portal, set your webhook URL to https://your-server.com/webhook
  3. Subscribe to the messages webhook event

Option B: Using a No-Code Integration Platform​

If you don't want to write code, use a platform like Zapier, Make, or Pipedream to connect WhatsApp to CiniterFlow's API. The flow is:

  1. Trigger: New WhatsApp message received
  2. Action: Send HTTP POST to CiniterFlow Prediction API
  3. Action: Send the response back via WhatsApp API

Part 3: Slack Integration​

CiniterFlow has a built-in Slack tool, but for a full bot experience, you'll want a Slack App.

Step 1: Create a Slack App

  1. Go to api.slack.com/apps
  2. Click "Create New App" β†’ "From scratch"
  3. Enable Event Subscriptions and subscribe to message.im (direct messages)
  4. Add Bot Token Scopes: chat:write, im:history, im:read
  5. Install the app to your workspace

Step 2: Create a Webhook Handler

const express = require('express');
const app = express();
app.use(express.json());

const CINITERFLOW_API = 'https://flow.ciniter.com/api/v1/prediction/your-flow-id';
const CINITERFLOW_KEY = 'your-ciniterflow-api-key';
const SLACK_TOKEN = 'xoxb-your-slack-bot-token';

app.post('/slack/events', async (req, res) => {
// Handle Slack URL verification
if (req.body.type === 'url_verification') {
return res.json({ challenge: req.body.challenge });
}

res.sendStatus(200);

const event = req.body.event;
if (!event || event.type !== 'message' || event.bot_id) return;

const userId = event.user;
const channel = event.channel;
const userText = event.text;

try {
// Call CiniterFlow
const response = await fetch(CINITERFLOW_API, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${CINITERFLOW_KEY}`
},
body: JSON.stringify({
question: userText,
overrideConfig: { sessionId: `slack-${userId}` }
})
});

const data = await response.json();
const aiReply = data.text || data.answer || 'Sorry, something went wrong.';

// Send reply to Slack
await fetch('https://slack.com/api/chat.postMessage', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${SLACK_TOKEN}`
},
body: JSON.stringify({
channel: channel,
text: aiReply
})
});
} catch (error) {
console.error('Error:', error);
}
});

app.listen(3000);

Using the Built-in Slack Tool​

For simpler use cases where the agent needs to send messages to Slack (rather than respond to them), use the built-in Slack tool:

  1. In your Agent node, add the Slack tool
  2. Configure it with your Slack credentials
  3. The agent can now post messages to Slack channels as part of its workflow

Part 4: Microsoft Teams Integration​

CiniterFlow has a built-in Microsoft Teams tool for sending messages. For a full bot:

  1. Register a bot in the Azure Bot Framework
  2. Create a webhook handler similar to the Slack example
  3. Use the Bot Framework SDK to handle incoming messages
  4. Call CiniterFlow's Prediction API and return the response

The built-in Teams tool works great for scenarios where your agent needs to notify a Teams channel (e.g., "New support ticket received" or "Research report completed").

Handling Images and Files​

For WhatsApp and Slack, users often send images. Here's how to forward them to CiniterFlow:

// After receiving an image message from WhatsApp
const imageUrl = message.image?.link || await getMediaUrl(message.image?.id);

const response = await fetch(CINITERFLOW_API, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${CINITERFLOW_KEY}`
},
body: JSON.stringify({
question: message.image?.caption || 'What is in this image?',
uploads: [{
data: imageUrl,
type: 'url',
name: 'image.jpg',
mime: 'image/jpeg'
}],
overrideConfig: { sessionId: userPhone }
})
});

Tips for Production Messaging Bots​

  1. Always use sessionId β€” map it to the user's phone number or Slack user ID so conversations persist
  2. Handle rate limits β€” messaging platforms have sending limits. Queue responses if needed
  3. Add typing indicators β€” send a "typing" status while waiting for CiniterFlow to respond
  4. Set response timeouts β€” if CiniterFlow takes too long, send a "Still thinking..." message
  5. Log conversations β€” store messages for debugging and quality improvement
  6. Handle errors gracefully β€” if the API fails, send a friendly error message instead of silence
  7. Test with real users β€” messaging UX is different from web chat. Test the full experience

Taking It Further​

  • Add quick reply buttons for common actions
  • Build a menu system for structured navigation
  • Implement handoff to human when the AI can't help
  • Add proactive messaging β€” the agent reaches out based on triggers (e.g., order shipped, appointment reminder)
  • Create multi-language support β€” detect the user's language and respond accordingly