# Viber

- Tool: FlutterFlow
- Difficulty: Advanced
- Time required: 45 minutes
- Last updated: July 2026

## TL;DR

Connect FlutterFlow to Viber by routing messages through a Firebase Cloud Function proxy that holds your Viber Public Account auth token. The function registers a webhook with Viber's `/set_webhook` endpoint and forwards send requests to `/send_message`. You can only message users who have already subscribed to your bot — no cold outreach. The mandatory webhook step is required before any message will go through.

## Why Viber Requires a Server-Side Proxy

Viber's messaging API (`https://chatapi.viber.com/pa`) authenticates every request with an `X-Viber-Auth-Token` header — a secret token tied to your Public Account. Because FlutterFlow compiles to a Flutter client app running on the user's device, any credential you place in an API Call header is bundled inside the compiled app. Tools like APKTool can extract it in minutes. This means the auth token must live exclusively inside a server-side proxy such as a Firebase Cloud Function, never in FlutterFlow itself.

Beyond the security requirement, Viber has a mandatory prerequisite before it will accept any send request: you must call `/set_webhook` to register a public HTTPS endpoint where Viber can deliver inbound events (user messages, subscription events, delivery receipts). Since a FlutterFlow app has no server address, this webhook must be a Cloud Function URL. Only after the webhook is registered will Viber allow your bot to send messages — skipping this step is the number-one reason first-time builds fail silently.

Viber's free Public Account tier lets you create a bot and receive subscriber events at no cost. Business Messages (for verified brands with richer features) are priced per messaging session — check current rates in the Viber Partners portal. The subscriber-only constraint is critical: you can only message users who have already started a conversation with your bot (captured as a `conversation_started` or `subscribed` event). There is no way to cold-message arbitrary phone numbers.

## Before you start

- A Viber Public Account (Bot) created at partners.viber.com — free to register
- Firebase project with Cloud Functions enabled (Blaze pay-as-you-go plan required for outbound HTTP calls)
- Node.js knowledge at a basic level to deploy and edit the Cloud Function
- A FlutterFlow project with at least one screen and a data source (Firestore) to store subscriber IDs
- Basic understanding of Firestore collections for storing and reading subscriber data

## Step-by-step guide

### 1. Create a Viber Public Account and copy the auth token

Go to partners.viber.com and sign in with your Viber account. Click 'Create Bot Account' and fill in your bot's name, icon, description, and category. Once the account is created, navigate to 'Info & API' in the left sidebar. You will see your **Auth Token** — a long alphanumeric string specific to your Public Account. Copy this token and store it somewhere safe (a password manager or a notes file — you will paste it into your Cloud Function environment, never into FlutterFlow).

Also take note of the bot's **URI** (the unique identifier used in deep links). On the same page, make sure your bot's status is 'Active' — inactive bots cannot receive or send messages. If you plan to use Viber Business Messages for verified brand accounts, you'll need to apply through the partner portal separately, but for testing and most app use cases the standard Public Account/Bot tier is sufficient.

At this stage you do not have a webhook URL yet — that comes from the Cloud Function you'll deploy in the next step. Do not attempt to call `/set_webhook` until you have the Cloud Function URL in hand.

**Expected result:** You have a Viber Public Account/Bot with an active status and a copied auth token stored securely offline.

### 2. Deploy a Firebase Cloud Function as your Viber proxy and webhook

Your Cloud Function serves two purposes: it registers as the Viber webhook (so Viber can deliver events to it) and it proxies send requests from your FlutterFlow app to Viber. In the Firebase Console, open your project and navigate to Functions → Get started (or the Functions dashboard if already enabled). Make sure your project is on the Blaze plan — the free Spark plan blocks outbound network calls, which are required to reach `chatapi.viber.com`.

In your local Firebase project folder (or the inline editor for small functions), create the Cloud Function below. It exposes two routes: `POST /webhook` for receiving Viber events (subscribe, message, etc.) and `POST /send` for FlutterFlow to call when it wants to send a Viber message. Set the `VIBER_AUTH_TOKEN` as a Firebase environment config variable (`firebase functions:config:set viber.token="YOUR_TOKEN_HERE"`) so it is never hard-coded.

After deploying the function with `firebase deploy --only functions`, copy the HTTPS trigger URL (e.g. `https://us-central1-yourproject.cloudfunctions.net/viberBot`). You'll use both the `/webhook` and `/send` sub-paths from this base URL in the following steps.

```
// functions/index.js
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const axios = require('axios');

admin.initializeApp();
const db = admin.firestore();

const VIBER_TOKEN = functions.config().viber.token;
const VIBER_BASE = 'https://chatapi.viber.com/pa';
const headers = { 'X-Viber-Auth-Token': VIBER_TOKEN };

// Webhook: receives Viber events (subscribe, conversation_started, message)
exports.viberWebhook = functions.https.onRequest(async (req, res) => {
  const event = req.body;
  const type = event.event;

  if (type === 'subscribed' || type === 'conversation_started') {
    const sender = event.sender || event.user;
    if (sender && sender.id) {
      await db.collection('viber_subscribers').doc(sender.id).set({
        id: sender.id,
        name: sender.name || '',
        subscribedAt: admin.firestore.FieldValue.serverTimestamp()
      }, { merge: true });
    }
  }

  res.status(200).send('ok');
});

// Send: FlutterFlow calls this to send a Viber message
exports.viberSend = functions.https.onRequest(async (req, res) => {
  const { receiver, text, senderName } = req.body;
  if (!receiver || !text) {
    return res.status(400).json({ error: 'receiver and text required' });
  }
  try {
    const payload = {
      receiver,
      type: 'text',
      text,
      sender: { name: senderName || 'YourBot' }
    };
    const response = await axios.post(`${VIBER_BASE}/send_message`, payload, { headers });
    return res.status(200).json(response.data);
  } catch (err) {
    return res.status(500).json({ error: err.message });
  }
});
```

**Expected result:** Firebase Console shows two functions deployed: `viberWebhook` and `viberSend`, each with a green checkmark and an HTTPS trigger URL.

### 3. Register your webhook with Viber's /set_webhook endpoint

Viber requires you to call `POST https://chatapi.viber.com/pa/set_webhook` before it will allow your bot to send any messages. This registration tells Viber where to deliver inbound events (subscriptions, messages, delivery receipts) and validates that your server is reachable. Without this step, Viber returns a status code indicating the webhook is not configured and will refuse message sends.

You only need to call `/set_webhook` once (or again if your function URL changes). The easiest way to do this is through a one-time HTTP request. Open a browser-based REST client (such as Hoppscotch at hoppscotch.io) or use the Firebase Functions logs to trigger it. Send a `POST` request to `https://chatapi.viber.com/pa/set_webhook` with the header `X-Viber-Auth-Token: YOUR_TOKEN` and the JSON body shown below, replacing the URL with your actual Cloud Function webhook URL.

A successful response looks like `{"status":0,"status_message":"ok","event_types":[...]}`. If you see status 1 or 3, double-check that your auth token is correct and your function URL is publicly reachable over HTTPS. The `event_types` array tells Viber which events to forward — include `subscribed`, `conversation_started`, `message`, and `delivered` at minimum so your function can capture subscriber IDs.

```
// One-time registration request (run from Hoppscotch or Postman — not from FlutterFlow)
// POST https://chatapi.viber.com/pa/set_webhook
// Header: X-Viber-Auth-Token: YOUR_VIBER_AUTH_TOKEN
{
  "url": "https://us-central1-yourproject.cloudfunctions.net/viberWebhook",
  "event_types": [
    "subscribed",
    "conversation_started",
    "message",
    "delivered",
    "failed",
    "seen"
  ],
  "send_name": true,
  "send_photo": false
}
```

**Expected result:** The `/set_webhook` response returns `{"status":0,"status_message":"ok"}` and Firestore shows a `viber_subscribers` collection after a test subscription.

### 4. Create the API Call in FlutterFlow pointing at your send proxy

Now that your Cloud Function is live and Viber is registered, configure FlutterFlow to call the send proxy. In the FlutterFlow editor, click **API Calls** in the left navigation panel. Click **+ Add** → **Create API Group**. Name the group `ViberProxy` and set the base URL to your Cloud Function's base URL (e.g. `https://us-central1-yourproject.cloudfunctions.net`).

Inside the group, click **+ Add API Call**. Name it `SendViberMessage`. Set the method to `POST` and the endpoint to `/viberSend` (or whatever your function export is named — match exactly what Firebase assigned). Switch to the **Variables** tab and add three variables: `receiver` (String), `text` (String), and `senderName` (String, with a default value matching your bot's display name). These variables become `{{ receiver }}`, `{{ text }}`, and `{{ senderName }}` in the request body.

In the **Body** section, select **JSON** as the content type and write the body: `{"receiver":"{{receiver}}","text":"{{text}}","senderName":"{{senderName}}"}`. Switch to **Response & Test** and paste a sample success response from Viber (`{"status":0,"status_message":"ok"}`). Click **Generate JSON Paths** — FlutterFlow will parse the response and let you reference `$.status` and `$.status_message` in your UI to confirm success. Finally, click **Test** with a real subscriber ID from your Firestore `viber_subscribers` collection to confirm the pipeline end-to-end.

```
// FlutterFlow API Call configuration (JSON representation)
{
  "group_name": "ViberProxy",
  "base_url": "https://us-central1-yourproject.cloudfunctions.net",
  "calls": [
    {
      "name": "SendViberMessage",
      "method": "POST",
      "endpoint": "/viberSend",
      "headers": {},
      "body_type": "JSON",
      "body": {
        "receiver": "{{receiver}}",
        "text": "{{text}}",
        "senderName": "{{senderName}}"
      },
      "variables": [
        { "name": "receiver", "type": "String" },
        { "name": "text", "type": "String" },
        { "name": "senderName", "type": "String", "default": "YourBot" }
      ]
    }
  ]
}
```

**Expected result:** The API Call test returns `{"status":0,"status_message":"ok"}` and the Viber message appears on the test subscriber's phone.

### 5. Build the send screen and wire up the action in FlutterFlow

With the API Call configured, build a simple send screen in your FlutterFlow app. Add a **Screen** (or use an existing one) and place a `TextField` for the message text and a `Button` labeled 'Send Viber Message'. You'll also need a way to supply the receiver ID — typically by reading it from the logged-in user's Firestore document, where you stored it when they subscribed to your bot.

Select the Button, open its **Actions** panel on the right, and click **+ Add Action**. Choose **Backend/API Call** → **ViberProxy → SendViberMessage**. In the variable bindings:
- `receiver`: bind to the Firestore field holding the current user's Viber subscriber ID (e.g., from a Document Variable or App State).
- `text`: bind to the `TextField`'s current value.
- `senderName`: leave as the default constant (your bot name).

Add a second chained action: **Show Snack Bar** with a conditional message — if the API call response `$.status` equals `0`, show 'Message sent!' otherwise show 'Send failed — try again.' This gives users clear feedback without exposing internal error details.

For apps that need to send to multiple subscribers (broadcast), loop through the Firestore `viber_subscribers` collection and call `SendViberMessage` for each document. Keep in mind that Viber rate limits apply — if you're sending to many subscribers at once, implement a short delay between calls or fan out from the Cloud Function itself rather than from the app.

**Expected result:** Tapping the button on a device sends a Viber message to the test subscriber and the Snack Bar shows 'Message sent!' — the full end-to-end pipeline is working.

## Best practices

- Never place the `X-Viber-Auth-Token` in a FlutterFlow API Call header — it ships in the app bundle. Always proxy through a Firebase Cloud Function.
- Call `/set_webhook` immediately after deploying your Cloud Function and before testing any sends. Without a registered webhook, Viber blocks all outbound messaging from your bot.
- Store every subscriber's Viber ID in Firestore when you receive a `conversation_started` or `subscribed` event — it's the only way to send them messages later.
- Always include a non-empty `sender.name` in your message payload. A missing or blank sender name causes a status 2 error on every send.
- Add a confirmation dialog in your FlutterFlow app before sending bulk messages — Viber rate limits apply and repeated sends can flag your bot as spam.
- Handle unsubscribe events in your Cloud Function webhook handler: when Viber sends an `unsubscribed` event, delete the subscriber's Firestore document to avoid sending to users who have opted out.
- Test on a real device with the Viber app installed. The Viber message delivery experience cannot be simulated in FlutterFlow's web preview or Run mode.
- For rich messages (carousels, buttons, images), use Viber's `keyboard` and `rich_media` message types — but test thoroughly as rendering varies across Viber client versions.

## Use cases

### E-commerce order status bot

An online store app lets customers check out and then opt in to receive Viber order updates. When an order ships, the app triggers a Cloud Function that sends a Viber message to the customer's subscriber ID with the tracking number and estimated delivery date.

Prompt example:

```
Build a feature where after a user places an order, a button lets them subscribe to Viber updates, and the order confirmation screen triggers a Viber message with the order ID and status.
```

### Appointment reminder service

A booking app stores patient or client appointments. Fifteen minutes before each appointment, a scheduled Cloud Function fires, looks up the Viber subscriber ID linked to the booking, and sends a reminder message — reducing no-shows without any manual effort.

Prompt example:

```
Create an appointment reminder that sends a Viber message to subscribed users 15 minutes before their scheduled slot, including the appointment time and location.
```

### Community event announcements

A community or club app lets members subscribe to the group's Viber bot. An admin screen in the FlutterFlow app lets the organizer type a message and tap Send — the app calls a Cloud Function that fans out the message to all stored subscriber IDs.

Prompt example:

```
Add an admin broadcast screen where the organizer writes a message and sends it to all Viber subscribers at once, with a confirmation dialog before sending.
```

## Troubleshooting

### API returns {"status":1,"status_message":"invalidAuthToken"} or 401

Cause: The `X-Viber-Auth-Token` in the Cloud Function request headers is wrong, expired, or the bot account has been disabled.

Solution: In the Firebase Console, go to Functions → Configuration and verify the `viber.token` environment variable matches the token in your Viber Admin Panel (partners.viber.com → Info & API). Re-deploy the function after updating the config with `firebase functions:config:set viber.token="NEW_TOKEN"` and `firebase deploy --only functions`.

### API returns {"status":7,"status_message":"notSubscribed"} when sending a message

Cause: The `receiver` ID you're passing belongs to a user who has not subscribed to (or has blocked) your Viber Public Account. You cannot message users who haven't started a conversation with your bot.

Solution: Check your Firestore `viber_subscribers` collection and confirm the subscriber document exists and was written from the `/subscribed` or `/conversation_started` webhook event. If the document is missing, the webhook registration may have failed or the user needs to open the bot again on Viber to re-trigger the event.

### Messages are not being sent and the /set_webhook call returns {"status":1}

Cause: The webhook URL is unreachable, uses HTTP instead of HTTPS, or the auth token is incorrect. Viber validates reachability when you call `/set_webhook`.

Solution: Confirm your Firebase Cloud Function URL starts with `https://` (not `http://`) and is publicly accessible. In the Firebase Console, navigate to Functions, find `viberWebhook`, and open the URL in a browser — it should respond (even with a 405 for GET requests). Check Firebase logs for any cold-start errors that might indicate a deployment problem. Re-deploy and call `/set_webhook` again.

### Send fails with {"status":2,"status_message":"invalidReceiverOrSender"} or sender name error

Cause: The `sender.name` field is missing or empty in the message payload. Viber requires a non-empty sender name on every message.

Solution: In your Cloud Function's `viberSend` handler, ensure `senderName` is never an empty string before building the payload. Add a fallback: `sender: { name: senderName || 'MyBot' }`. Also confirm the `receiver` field contains the user's raw Viber subscriber ID string (not a phone number — Viber bot messaging uses internal IDs, not phone numbers).

```
const payload = {
  receiver,
  type: 'text',
  text,
  sender: { name: senderName || 'MyBot' }  // fallback prevents empty-name error
};
```

## Frequently asked questions

### Can I send a Viber message to any phone number from FlutterFlow?

No. Viber's Bot/Public Account API only lets you message users who have already started a conversation with your bot (captured as `conversation_started` or `subscribed` events). There is no API endpoint for sending to arbitrary phone numbers. If you need to reach users before they've interacted with your bot, consider Viber Business Messages (which requires partner registration and approval) or a different channel like SMS via Twilio or Sinch.

### Why does my FlutterFlow app need a Cloud Function just to send a Viber message?

FlutterFlow compiles to a Flutter client app that runs on the user's device. Any API key or token you add to an API Call header gets bundled into the compiled app, where it can be extracted with freely available tools. The Viber `X-Viber-Auth-Token` grants full control over your bot, so it must stay on a server. A Firebase Cloud Function acts as that server — your app calls the function, the function calls Viber with the token it holds securely in environment config.

### Do I need to call /set_webhook every time I redeploy my Cloud Function?

Only if your function URL changes. Firebase Cloud Functions keep the same HTTPS URL as long as the function name stays the same. If you rename the function or move to a different project/region, you'll get a new URL and must call `/set_webhook` again with the new URL. It's good practice to re-verify the webhook after any major redeployment by checking the Viber admin panel or calling `/get_account_info`.

### Can I receive Viber messages (inbound) in my FlutterFlow app?

Not directly — FlutterFlow apps have no server address and cannot receive HTTP webhooks. The pattern is: Viber delivers inbound messages to your Cloud Function webhook, which writes them to a Firestore collection. Your FlutterFlow app then uses a Firestore real-time query to display those messages, updating instantly as new documents arrive. This gives users an in-app inbox without the app needing to receive webhooks itself.

### Is RapidDev able to help set up the Cloud Function and Viber integration?

Yes — if the proxy setup or webhook configuration feels overwhelming, RapidDev's team handles FlutterFlow integrations like this every week. Book a free scoping call at rapidevelopers.com/contact to discuss your use case.

---

Source: https://www.rapidevelopers.com/flutterflow-integrations/viber
© RapidDev — https://www.rapidevelopers.com/flutterflow-integrations/viber
