Skip to content

Alles für WordPress, Webentwicklung — und mehr

🤖 Viber-Chatbot in PHP: Strukturierte Nachrichten mit Tastaturmenüs senden

🤖 Viber-Chatbot in PHP: Strukturierte Nachrichten mit Tastaturmenüs senden

Der Nutzer drückt im Chat eine Taste und erhält kein bloßes Textfeld, sondern ein Raster aus Bildern, Links und farbigen Schaltflächen. Es wirkt wie eine native App. In Wirklichkeit ist es schlichtes JSON, das Ihr PHP-Skript über die Viber REST API zurücksendet.

Das Problem der meisten Tutorials: Sie lehren, auf Text mit Text zu antworten. Ein echter Business-Bot muss ein Tastaturmenü mit Link-Buttons, Bildern und Karussells anzeigen. Andernfalls versteht der Nutzer schlicht nicht, was der Bot leisten kann, und springt ab. Seit Februar 2024 hat Viber die Bot-Erstellung auf eine kommerzielle Basis gestellt (100 € pro Monat über offizielle Rakuten-Viber-Partner), und die Authentifizierung erfolgt nun über den HTTP-Header X-Viber-Auth-Token statt im Request-Body. Code-Schnipsel mit auth_token im JSON funktionieren nicht mehr.

Hier ist ein funktionierender Viber-Bot in PHP von Grund auf: vom Einrichten des Webhooks bis zum Versand eines strukturierten Tastaturmenüs mit Antwort- und URL-Buttons. Der Code ist aktuell für API-Version 7.3.

💡 Kurzüberblick:

  • Registrieren Sie einen kommerziellen Bot über einen Viber-Partner und beziehen Sie ein Authentifizierungs-Token
  • Konfigurieren Sie den Webhook via set_webhook mit dem X-Viber-Auth-Token-Header
  • Empfangen Sie Callback-Ereignisse von Viber: Webhook → subscribed → message
  • Bauen Sie ein Tastaturmenü (ein Button-Raster mit benutzerdefinierten Farben, Größen und Aktionen)
  • Senden Sie eine strukturierte Antwort: Text, Bilder, Links, Karussells via send_message

So funktioniert die Viber Bot API

Die Viber Bot API arbeitet nach einem REST-Modell: Ihr Server empfängt Callback-Anfragen auf dem Webhook und antwortet durch Aufruf von https://chatapi.viber.com/pa/send_message. Jede Anfrage wird mit einem Token im X-Viber-Auth-Token-Header authentifiziert.

Der grundlegende Zyklus sieht so aus:

  • Sie registrieren einen Bot über einen Viber-Partner und erhalten ein Token im Bereich „Edit Info".
  • Sie konfigurieren einen Webhook (die URL Ihres Servers mit gültigem SSL; Let's Encrypt funktioniert, da es in Vipers Liste vertrauenswürdiger Java-Zertifikate enthalten ist; selbstsignierte Zertifikate werden nicht akzeptiert).
  • Viber sendet bei jedem Ereignis POST-Anfragen an diese URL: Ein Nutzer hat abonniert, eine Nachricht gesendet, eine Taste gedrückt.
  • Ihr PHP-Skript liest das eingehende JSON, parst das Feld event und antwortet durch Aufruf von send_message.

Der erste Schritt zum Verständnis ist ein Blick auf einen Live-Bot. Öffnen Sie Viber und suchen Sie nach dem öffentlichen Konto einer beliebigen bekannten Marke. Fast jedes hat einen Chatbot mit einem Menü. Der Screenshot unten zeigt ein typisches Suchergebnis für ein öffentliches Konto.

Suche nach einem öffentlichen Konto in Viber

Nach dem Abonnieren gelangen Sie in einen Eins-zu-eins-Chat. Das sieht ungefähr so aus: ein Avatar, eine Willkommensnachricht und eine Schaltfläche zum Starten der Konversation.

Viber-Chatbildschirm eines öffentlichen Chats nach dem Abonnieren

Tippen Sie auf das Nachrichtensymbol oben rechts und senden Sie „Hallo". Wenn der Bot mit einem Tastaturmenü konfiguriert ist, sehen Sie eine Antwort mit einem Button-Raster:

Tastaturmenü mit Schaltflächen in einem Viber-Chat

Das ist eine strukturierte Nachricht. Es gibt zwei Button-Typen: reply sendet Text an den Bot zurück (beim Drücken von „News" oder „Artikel"), während open-url einen Link im Browser öffnet. Schreiben wir nun den Code, der dies erzeugt.

Schritt 1: Token beziehen und Webhook konfigurieren

Das Token befindet sich im Viber-Admin-Panel: Bereich „Edit Info" → Feld „App Key". Es ist eine Zeichenfolge aus Buchstaben und Ziffern, die Sie in jede API-Anfrage einbinden.

Der Webhook wird mit einer einzigen POST-Anfrage an https://chatapi.viber.com/pa/set_webhook gesetzt. Der Request-Body ist JSON mit der URL Ihres Handlers und einer Liste der Ereignisse, die Sie abonnieren. Der Header ist X-Viber-Auth-Token mit Ihrem Token.

Skript für die Webhook-Einrichtung (speichern Sie es als setup.php und führen Sie es einmal aus):

1<?php
2$token = 'ВАШ_X_VIBER_AUTH_TOKEN';
3
4$data = json_encode([
5 'url' => 'https://your-domain.com/webhook.php',
6 'event_types' => ['message', 'subscribed', 'conversation_started'],
7]);
8
9$ch = curl_init('https://chatapi.viber.com/pa/set_webhook');
10curl_setopt($ch, CURLOPT_POST, 1);
11curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
12curl_setopt($ch, CURLOPT_HTTPHEADER, [
13 'Content-Type: application/json',
14 'X-Viber-Auth-Token: ' . $token,
15]);
16curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
17
18$result = curl_exec($ch);
19$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
20curl_close($ch);
21
22echo "HTTP {$httpCode}: {$result}\n";
23
24if ($httpCode === 200) {
25 $response = json_decode($result, true);
26 if (($response['status'] ?? -1) === 0) {
27 echo "Вебхук установлен успешно.\n";
28 } else {
29 echo "Ошибка Viber: " . ($response['status_message'] ?? 'неизвестная') . "\n";
30 }
31}

Was hier passiert: cURL sendet einen POST an set_webhook. Das Token steht strikt im Header, nicht im Body. Viber gibt bei Erfolg {"status":0} zurück und sendet umgehend einen webhook-Callback an die angegebene URL, um deren Verfügbarkeit zu prüfen. Die Antwort mit {"status":0,"status_message":"ok"} auf diesen Callback ist zwingend erforderlich (das behandeln wir im nächsten Schritt).

Wenn Sie invalidUrl erhalten, prüfen Sie Ihr SSL-Zertifikat. Let's Encrypt funktioniert; selbstsignierte nicht. Auf Ihrem Server genügt es, certbot --nginx -d your-domain.com auszuführen und die automatische Verlängerung via Cron einzurichten.

Schritt 2: Callback-Ereignisse von Viber empfangen

Wenn ein Nutzer mit dem Bot interagiert, sendet Viber eine POST-Anfrage mit JSON an Ihren Webhook. Ihre Aufgabe ist es, das Feld event zu lesen und zu reagieren.

Ein minimaler Handler webhook.php, der korrekt auf alle Ereignisse antwortet:

1<?php
2$request = file_get_contents("php://input");
3$input = json_decode($request, true);
4
5if ($input['event'] === 'webhook') {
6 $response = [
7 'status' => 0,
8 'status_message' => 'ok',
9 'event_types' => ['delivered', 'seen', 'message', 'subscribed', 'conversation_started'],
10 ];
11 echo json_encode($response);
12 exit;
13}
14
15if ($input['event'] === 'subscribed') {
16 $sender_id = $input['sender']['id'];
17 sendWelcomeMessage($sender_id);
18}
19
20if ($input['event'] === 'conversation_started') {
21 $sender_id = $input['sender']['id'];
22 sendMainMenu($sender_id);
23}
24
25if ($input['event'] === 'message') {
26 $type = $input['message']['type'];
27 $text = $input['message']['text'];
28 $sender_id = $input['sender']['id'];
29 $sender_name = $input['sender']['name'];
30
31 $data = match ($text) {
32 'News' => getNewsList($sender_id),
33 'Articles' => getArticleList($sender_id),
34 'Gallery' => getGalleryList($sender_id),
35 default => getMainMenu($sender_id),
36 };
37
38 sendToViber($data);
39}

Ereignisaufschlüsselung:

  • webhook trifft einmalig ein, wenn der Webhook gesetzt wird. Sie müssen {"status":0,"status_message":"ok"} mit einer Liste der unterstützten Ereignisse zurückgeben. Ohne dies bestätigt Viber die URL nicht und der Bot startet nicht.
  • subscribed bedeutet, dass ein Nutzer den Bot abonniert hat. Dies ist der ideale Zeitpunkt, um ein Willkommensmenü zu senden.
  • conversation_started bedeutet, dass ein Nutzer den Chat geöffnet hat (erstmalig oder erneut). Ebenfalls geeignet, um das Hauptmenü anzuzeigen.
  • message ist das zentrale Arbeitsereignis. Das Feld text enthält entweder eine beliebige Nutzernachricht oder den ActionBody einer gedrückten Schaltfläche (sofern deren Typ reply ist). Darüber versteht der Bot, was ausgewählt wurde: „News", „Artikel" oder „Galerie".

Das Konstrukt match() steht ab PHP 8 zur Verfügung. Falls Sie PHP 7.4 einsetzen, ersetzen Sie es durch switch.

Schritt 3: Das Tastaturmenü aufbauen

Eine Tastatur wird jeder Nachricht über das Feld keyboard im JSON-Objekt send_message angehängt. Es handelt sich um ein Array von Schaltflächen mit separaten Einstellungen für Breite (Columns, 1-6), Höhe (Rows, 1-2), Hintergrundfarbe, Text und Aktion.

Eine Funktion, die ein Hauptmenü aus sieben Reply-Buttons und einem Link-Button zusammensetzt:

1<?php
2
3function getMainMenu(string $user_id): array
4{
5 $buttons = [];
6
7 $addReplyButton = function (string $label, string $actionBody, int $cols = 2, int $rows = 2) use (&$buttons) {
8 $buttons[] = [
9 'Columns' => $cols,
10 'Rows' => $rows,
11 'Text' => $label,
12 'TextSize' => 'regular',
13 'TextVAlign' => 'bottom',
14 'TextHAlign' => 'center',
15 'TextOpacity' => 100,
16 'ActionType' => 'reply',
17 'ActionBody' => $actionBody,
18 'BgColor' => '#FFFFFF',
19 ];
20 };
21
22 $addReplyButton('NEWS', 'News');
23 $addReplyButton('ARTICLES', 'Articles');
24 $addReplyButton('INTERVIEWS', 'Interviews');
25 $addReplyButton('GALLERY', 'Gallery');
26 $addReplyButton('POLL', 'Poll');
27 $addReplyButton('PLAYER OF THE MONTH','POTM');
28 $addReplyButton('QUOTE OF THE DAY', 'Quote');
29
30 $buttons[] = [
31 'Columns' => 4,
32 'Rows' => 2,
33 'Text' => 'VISIT OUR WEBSITE',
34 'TextSize' => 'regular',
35 'TextVAlign' => 'bottom',
36 'TextHAlign' => 'center',
37 'TextOpacity' => 100,
38 'ActionType' => 'open-url',
39 'ActionBody' => 'https://your-site.com',
40 'BgColor' => '#FFFFFF',
41 ];
42
43 return [
44 'receiver' => $user_id,
45 'type' => 'text',
46 'text' => 'Please select one of the options below:',
47 'keyboard' => [
48 'Type' => 'keyboard',
49 'BgColor' => '#FFFFFF',
50 'Buttons' => $buttons,
51 ],
52 ];
53}

Schaltflächen mit Columns=2 und Rows=2 sind quadratisch, drei pro Zeile (2+2+2=6). Der Link-Button mit Columns=4 belegt eine eigene Zeile. Das Raster wird von links nach rechts und von oben nach unten aufgebaut. Die Summe der Columns in einer Zeile bestimmt das Layout.

Parameter der Schaltflächen:

Parameter

Werte

Zweck

Columns

1-6

Schaltflächenbreite in bedingten Spalten

Rows

1-2

Schaltflächenhöhe in Zeilen

ActionType

reply oder open-url

reply sendet Text an den Bot zurück, open-url öffnet den Browser

ActionBody

Zeichenkette

Bei reply der Text, den der Bot zurückerhält; bei open-url die URL

Text

Zeichenkette

Beschriftung der Schaltfläche, unterstützt HTML-Tags b, i und Schriftfarbe

BgColor

HEX

Hintergrundfarbe der Schaltfläche

Image

URL

Bild oberhalb der Schaltfläche, JPEG, optional

Schritt 4: Daten per send_message versenden

Eine Sender-Funktion, die Sie aus dem Event-Handler aufrufen:

1<?php
2
3function sendToViber(array $data): void
4{
5 $token = 'ВАШ_X_VIBER_AUTH_TOKEN';
6
7 $ch = curl_init('https://chatapi.viber.com/pa/send_message');
8 curl_setopt($ch, CURLOPT_POST, 1);
9 curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
10 curl_setopt($ch, CURLOPT_HTTPHEADER, [
11 'Content-Type: application/json',
12 'X-Viber-Auth-Token: ' . $token,
13 ]);
14 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
15
16 $result = curl_exec($ch);
17 $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
18 curl_close($ch);
19
20 if ($httpCode !== 200) {
21 error_log("Viber API error: HTTP {$httpCode} - {$result}");
22 }
23}

Der wesentliche Unterschied zu älteren Tutorials: Der Token steht im Header, nicht im JSON-Body. Der Body enthält nur die Felder receiver, type, text, keyboard und optional sender.name, sender.avatar, tracking_data. Die maximale JSON-Größe beträgt 30 KB. Wenn Sie diese überschreiten, verwirft Viber die Nachricht stillschweigend; prüfen Sie strlen(json_encode($data)) vor dem Senden.

Schritt 5: Inhalte für Schaltflächen zusammenstellen

Wenn ein Nutzer eine Reply-Schaltfläche drückt, wird deren ActionBody als Nachrichtentext an den Webhook gesendet. Sie parsen diesen in match() und rufen die entsprechende Funktion auf. Hier ein Beispiel für eine Nachrichtenliste mit Bildern:

1<?php
2
3function getNewsList(string $user_id): array
4{
5 $newsItems = [
6 [
7 'title' => 'Your Article Title',
8 'link' => 'https://your-site.com/article-1',
9 'image' => 'https://your-site.com/images/article-1.jpg',
10 ],
11 [
12 'title' => 'Another Article',
13 'link' => 'https://your-site.com/article-2',
14 'image' => 'https://your-site.com/images/article-2.jpg',
15 ],
16 ];
17
18 $buttons = [];
19 foreach ($newsItems as $item) {
20 $buttons[] = [
21 'Columns' => 2,
22 'Rows' => 2,
23 'ActionType' => 'open-url',
24 'ActionBody' => $item['link'],
25 'BgColor' => '#FFFFFF',
26 'Image' => $item['image'],
27 ];
28 $buttons[] = [
29 'Columns' => 4,
30 'Rows' => 2,
31 'Text' => $item['title'],
32 'TextSize' => 'regular',
33 'TextHAlign' => 'left',
34 'TextVAlign' => 'top',
35 'ActionType' => 'open-url',
36 'ActionBody' => $item['link'],
37 'BgColor' => '#F5F5F5',
38 ];
39 }
40
41 return [
42 'receiver' => $user_id,
43 'type' => 'text',
44 'text' => 'Here are the latest updates:',
45 'keyboard' => [
46 'Type' => 'keyboard',
47 'BgColor' => '#DDDDDD',
48 'Buttons' => $buttons,
49 ],
50 ];
51}

Auf Nutzerseite sieht dies wie ein Raster aus Karten aus: Bild links, Titel rechts. Ein Tippen auf einen beliebigen Bereich öffnet den Link im Browser.

Rich Message mit Bildern und Links in Viber

Eine Galerie, Artikelliste oder Umfragen werden exakt auf dieselbe Weise zusammengestellt; lediglich der Inhalt des Arrays $buttons und der Nachrichtentext ändern sich. Falls viel Inhalt vorhanden ist und das JSON sich 30 KB nähert, teilen Sie es mit einem „Weiter"-Button in Seiten auf.

Wenn Sie lieber mit einer fertigen PHP-Bibliothek arbeiten möchten statt mit der rohen API, sehen Sie sich viber-bot-php von Bogdaan an. Diese übernimmt für Sie die Signaturvalidierung, das Event-Routing und die JSON-Generierung.

Zusammenfassung: vollständige Startsequenz

  • Token beschaffen im Viber Admin Panel: Bereich „Info bearbeiten" → App Key.
  • Handler bereitstellen auf einem Server mit HTTPS. Let's Encrypt funktioniert; ein selbstsigniertes Zertifikat nicht. Viber validiert Zertifikate gegen die vertrauenswürdige Java Root CA-Liste.
  • Webhook setzen mit einer POST-Anfrage an https://chatapi.viber.com/pa/set_webhook mit Body {"url":"https://your-domain/webhook.php","event_types":[...]} und Header X-Viber-Auth-Token.
  • Antwort prüfen: {"status":0} bedeutet Erfolg. Viber sendet sofort einen webhook-Callback an Ihre URL. Stellen Sie sicher, dass das Skript {"status":0,"status_message":"ok"} zurückgibt.
  • Erstes Menü senden: beim Event conversation_started getMainMenu() aufrufen und das Ergebnis an sendToViber() übergeben.

⁉️🤔 Häufig gestellte Fragen

Kann ich ein selbstsigniertes SSL-Zertifikat für den Webhook verwenden?

Nein. Viber validiert das Zertifikat gegen die Liste der vertrauenswürdigen Java-Root-Zertifizierungsstellen. Ein selbstsigniertes Zertifikat verursacht beim Setzen des Webhooks einen invalidUrl-Fehler. Let's Encrypt ist in dieser Liste enthalten und kostenlos. Führen Sie auf Ihrem Server certbot --nginx -d your-domain.com aus, hinterlegen Sie die automatische Verlängerung im Cron, und Viber akzeptiert das Zertifikat problemlos.

Was ist der Unterschied zwischen reply und open-url beim ActionType?

reply sendet ActionBody als Nachrichtentext an den Webhook zurück. Das PHP-Skript sieht ihn in $input['message']['text'] und leitet ihn über match() weiter. Verwenden Sie dies für die Navigation innerhalb des Bots. open-url öffnet einen Link in einem externen Browser und löst keinen Webhook aus. In der Praxis kombinieren Menüs beide Typen: fünf oder sechs Reply-Buttons für Bereiche und einen breiten Open-URL-Button für den Sprung zur Website.

Welche Nachrichtentypen unterstützt die Viber Bot API?

Die Viber Bot API unterstützt neun type-Werte in send_message: text (reiner Text), picture (JPEG-Bild), video (Videodatei), file (beliebige Datei bis 50 MB), location (Geopunkt), contact (Kontaktkarte), sticker (Sticker), rich_media (Kartenkarussell) und url (Linkvorschau). Die aktuelle Liste mit den erforderlichen Feldern finden Sie in der Dokumentation des Viber Developers Hub. Das häufigste Szenario ist text + keyboard für Menüs und picture für den Bildversand. Karussells eignen sich hervorragend für Shops und Kataloge, erfordern aber mehr Code.

Was tun, wenn der Nutzer die Tastatur nicht sieht?

Es gibt drei häufige Ursachen. Erstens: Das JSON mit der Tastatur hat 30 KB überschritten, und Viber verwirft solche Nachrichten stillschweigend. Prüfen Sie strlen(json_encode($data)) vor dem Senden. Zweitens: Die Antwort auf set_webhook enthielt kein "status":0, der Webhook wurde nicht gesetzt, und der Bot empfängt keine Nachrichten. Drittens: Sie verwenden das alte Format mit auth_token im JSON-Body. Seit API 7.0 wird dies ignoriert; Sie benötigen den X-Viber-Auth-Token-Header. Aktivieren Sie zum Debuggen das Logging der Viber-API-Antwort: Sie liefert lesbares JSON mit Fehlercodes wie invalidAuthToken, badData oder missingData.

Kann ich die Tastatur nach dem Senden ändern?

Ja. Mit jeder neuen Nachricht können Sie eine andere Tastatur senden. Der Viber-Client zeigt immer die zuletzt empfangene an. So lassen sich mehrstufige Menüs aufbauen: Hauptmenü → Bereichs-Untermenü → spezifischer Inhalt. Jede Ebene hat ihren eigenen Satz an Schaltflächen, und der Nutzer bewegt sich durch Drücken der Reply-Tasten zwischen ihnen.

Was kostet der Start eines Viber-Bots im Jahr 2026?

Seit dem 5. Februar 2024 kostet die Erstellung eines neuen Bots 100 € pro Monat über offizielle Rakuten-Viber-Partner. Bots, die vor diesem Datum erstellt wurden, laufen zu den alten Konditionen weiter. Die Kosten umfassen einen dedizierten Account mit Admin-Panel, Analysefunktionen und Zugriff auf alle Nachrichtentypen einschließlich rich_media und Viber Pay. Der technische Teil der API ist für kommerzielle und ältere kostenlose Bots identisch.

Der Bot ist bereit: was nun kommt

Ein Tastaturmenü ist nur ein Einstiegspunkt. Sobald die grundlegende Mechanik funktioniert, ergänzen Sie Inhaltskarussells über rich_media, Zahlungen über Viber Pay und eine Nutzersegmentierung danach, welche Schaltflächen am häufigsten gedrückt werden. Jede neue Ebene ändert nichts am Fundament: Sie lesen weiterhin event und senden weiterhin send_message mit dem X-Viber-Auth-Token-Header.

Wenn Sie ein funktionierendes Codebeispiel benötigen, sehen Sie sich das viber-bot-php-Repository auf GitHub an. Es deckt alle Events, die Anfragensignierung und den Aufbau einer Tastatur mit Bildern ab. Und für einen visuellen Einstieg hier ein halbstündiges Tutorial zur Erstellung eines Viber-Bots von Grund auf:

Das Wichtigste, was Sie sich merken sollten: Die Viber Bot API ist am Anfang einfach, aber anspruchsvoll bei den Details. Ein korrekter Authentifizierungs-Header, vertrauenswürdiges SSL, gültiges JSON unter 30 KB und ein klares ActionBody-Routing genügen, damit der Bot störungsfrei läuft. Nehmen Sie die obigen Codeausschnitte, setzen Sie Ihren Token und Ihre Domain ein und starten Sie noch heute Ihr erstes Menü.