
🤖 Viber-chatbotti PHP:lla: jäsenneltyjen viestien lähettäminen näppäimistövalikoilla
Käyttäjä painaa chatissa nappia ja saa vastaukseksi paljaan tekstin sijaan ruudukon kuvia, linkkejä ja värikoodattuja näppäimiä. Se näyttää natiivilta sovellukselta. Todellisuudessa se on pelkkää JSONia, jonka PHP-skriptisi palauttaa Viberin REST API:n kautta.
Useimpien tutoriaalien ongelma: ne opettavat vastaamaan tekstiin tekstillä. Oikean bisnesbotin täytyy näyttää näppäimistövalikko, jossa on linkkipainikkeita, kuvia ja karuselleja. Muuten käyttäjä ei yksinkertaisesti ymmärrä, mitä botti osaa tehdä, ja poistuu. Helmikuusta 2024 lähtien Viber on asettanut bottien luonnin kaupalliselle pohjalle (100 € kuukaudessa virallisten Rakuten Viber -kumppaneiden kautta), ja autentikointi kulkee nyt HTTP-otsakkeessa X-Viber-Auth-Token eikä pyynnön rungossa. Koodinpätkät, joissa auth_token on JSONin sisällä, eivät enää toimi.
Tässä on toimiva Viber-botti PHP:llä alusta alkaen: webhookin asetuksesta jäsennellyn näppäimistövalikon lähettämiseen reply- ja open-url-painikkeilla. Koodi on ajan tasalla API-versiolle 7.3.
💡 Pikakatsaus:
- Rekisteröi kaupallinen botti Viber-kumppanin kautta ja hanki autentikointitoken
- Määritä webhook
set_webhook-kutsulla jaX-Viber-Auth-Token-otsakkeella - Vastaanota callback-tapahtumat Viberiltä: webhook → subscribed → message
- Rakenna näppäimistövalikko (painikeruudukko, jossa mukautetut värit, koot ja toiminnot)
- Lähetä jäsennelty vastaus: tekstiä, kuvia, linkkejä, karuselleja
send_message-kutsulla
Miten Viber Bot API toimii
Viber Bot API toimii REST-mallilla: palvelimesi vastaanottaa callback-pyyntöjä webhookiin ja vastaa kutsumalla osoitetta https://chatapi.viber.com/pa/send_message. Jokainen pyyntö autentikoidaan tokenilla X-Viber-Auth-Token-otsakkeessa.
Perussykli näyttää tältä:
- Rekisteröit botin Viber-kumppanin kautta ja saat tokenin "Edit Info" -paneelista.
- Määrität webhookin (palvelimesi URL, jossa on kelvollinen SSL; Let's Encrypt toimii, koska se on Viberin luotetulla Java-varmenne-listalla; itse allekirjoitettuja varmenteita ei hyväksytä).
- Viber lähettää POST-pyyntöjä tähän URLiin jokaisesta tapahtumasta: käyttäjä tilasi, lähetti viestin, painoi painiketta.
- PHP-skriptisi lukee saapuvan JSONin, jäsentää
event-kentän ja vastaa kutsumallasend_message-funktiota.
Ensimmäinen askel ymmärtämiseen on katsoa elävää bottia. Avaa Viber ja etsi minkä tahansa tunnetun brändin julkinen tili. Lähes jokaisella on chatbotti, jossa on valikko. Alla oleva kuvakaappaus näyttää tyypillisen julkisen tilin hakutuloksen.

Tilauksen jälkeen siirryt kahdenkeskiseen chattiin. Se näyttää suunnilleen tältä: avatar, tervetuloviesti ja painike keskustelun aloittamiseksi.

Napauta viestikuvaketta oikeassa yläkulmassa ja lähetä "Hei". Jos bottiin on määritetty näppäimistövalikko, näet vastauksen, jossa on painikeruudukko:

Tämä on jäsennelty viesti. Painiketyyppejä on kaksi: reply lähettää tekstiä takaisin botille (painamalla "Uutiset" tai "Artikkelit"), kun taas open-url avaa linkin selaimessa. Kirjoitetaan nyt koodi, joka tuottaa tämän.
Vaihe 1: Hanki token ja määritä webhook
Token sijaitsee Viberin hallintapaneelissa: Edit Info -osio → App Key -kenttä. Se on kirjainten ja numeroiden yhdistelmä, jonka liität jokaiseen API-pyyntöön.
Webhook asetetaan yhdellä POST-pyynnöllä osoitteeseen https://chatapi.viber.com/pa/set_webhook. Pyynnön runko on JSONia, joka sisältää käsittelijäsi URL:n ja listan tapahtumista, jotka tilaat. Otsake on X-Viber-Auth-Token ja tokenisi.
Webhookin asetusskripti (tallenna nimellä setup.php ja aja kerran):
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'); 10 curl_setopt($ch, CURLOPT_POST, 1); 11 curl_setopt($ch, CURLOPT_POSTFIELDS, $data); 12 curl_setopt($ch, CURLOPT_HTTPHEADER, [ 13 'Content-Type: application/json', 14 'X-Viber-Auth-Token: ' . $token, 15 ]); 16 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 17 18 $result = curl_exec($ch); 19 $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); 20 curl_close($ch); 21 22 echo "HTTP {$httpCode}: {$result}\n"; 23 24 if ($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 }
Mitä tässä tapahtuu: cURL lähettää POST-pyynnön set_webhook-osoitteeseen. Token on tiukasti otsakkeessa, ei rungossa. Viber palauttaa {"status":0} onnistuessaan ja lähettää välittömästi webhook-callbackin määritettyyn URLiin varmistaakseen sen tavoitettavuuden. Vastaaminen tähän callbackiin viestillä {"status":0,"status_message":"ok"} on pakollista (käsittelemme tämän seuraavassa vaiheessa).
Jos saat vastauksen invalidUrl, tarkista SSL-varmenteesi. Let's Encrypt toimii; itse allekirjoitettu ei. Palvelimellasi riittää, että ajat certbot --nginx -d your-domain.com ja määrität automaattisen uusinnan cronin kautta.
Vaihe 2: Vastaanota callback-tapahtumat Viberiltä
Kun käyttäjä on vuorovaikutuksessa botin kanssa, Viber lähettää POST-pyynnön JSON-muodossa webhookiisi. Sinun tehtäväsi on lukea event-kenttä ja reagoida.
Minimaalinen käsittelijä webhook.php, joka vastaa oikein kaikkiin tapahtumiin:
1 <?php 2 $request = file_get_contents("php://input"); 3 $input = json_decode($request, true); 4 5 if ($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 15 if ($input['event'] === 'subscribed') { 16 $sender_id = $input['sender']['id']; 17 sendWelcomeMessage($sender_id); 18 } 19 20 if ($input['event'] === 'conversation_started') { 21 $sender_id = $input['sender']['id']; 22 sendMainMenu($sender_id); 23 } 24 25 if ($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 }
Tapahtumien erittely:
webhooksaapuu kerran, kun webhook asetetaan. Sinun on palautettava{"status":0,"status_message":"ok"}ja lista tuetuista tapahtumista. Ilman tätä Viber ei vahvista URL-osoitetta eikä botti käynnisty.subscribedtarkoittaa, että käyttäjä on tilannut botin. Tämä on ihanteellinen hetki lähettää tervetulovalikko.conversation_startedtarkoittaa, että käyttäjä avasi keskustelun (ensimmäistä kertaa tai uudelleen). Sopii myös päävalikon näyttämiseen.messageon tärkein työtapahtuma.text-kenttä sisältää joko mielivaltaisen käyttäjän viestin tai painetun painikkeenActionBody-arvon (jos sen tyyppi onreply). Näin botti ymmärtää, mitä valittiin: "Uutiset", "Artikkelit" vai "Galleria".
match()-rakenne on käytettävissä PHP 8:sta alkaen. Jos käytössäsi on PHP 7.4, korvaa se switch-rakenteella.
Vaihe 3: Rakenna näppäimistövalikko
Näppäimistö liitetään mihin tahansa viestiin keyboard-kentän kautta send_message JSON-objektissa. Se on taulukko painikkeita, joille määritellään erikseen leveys (Columns, 1-6), korkeus (Rows, 1-2), taustaväri, teksti ja toiminto.
Funktio, joka kokoaa päävalikon seitsemästä reply-painikkeesta ja yhdestä linkkipainikkeesta:
1 <?php 2 3 function 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 }
Painikkeet, joissa Columns=2 ja Rows=2, ovat neliön muotoisia, kolme per rivi (2+2+2=6). Linkkipainike, jossa Columns=4, vie oman rivinsä. Ruudukko kootaan vasemmalta oikealle, ylhäältä alas. Rivin Columns-arvojen summa määrittää asettelun.
Painikkeiden parametrit:
Parametri | Arvot | Tarkoitus |
|---|---|---|
| 1-6 | Painikkeen leveys ehdollisina sarakkeina |
| 1-2 | Painikkeen korkeus riveinä |
|
|
|
| merkkijono |
|
| merkkijono | Painikkeen teksti, tukee HTML-tageja b, i ja fontin väriä |
| HEX | Painikkeen taustaväri |
| URL | Kuva painikkeen päällä, JPEG, valinnainen |
Vaihe 4: Lähetä data send_message-toiminnolla
Lähetysfunktio, jota kutsut tapahtumankäsittelijästä:
1 <?php 2 3 function 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 }
Keskeinen ero vanhoihin tutoriaaleihin: token on otsikkotiedossa, ei JSON-rungossa. Runko sisältää vain kentät receiver, type, text, keyboard ja valinnaisesti sender.name, sender.avatar, tracking_data. JSONin maksimikoko on 30 kt. Jos ylität sen, Viber hylkää viestin hiljaisesti; tarkista strlen(json_encode($data)) ennen lähetystä.
Vaihe 5: Kokoa sisältö painikkeille
Kun käyttäjä painaa reply-painiketta, sen ActionBody lähetetään webhookiin viestin tekstinä. Jäsennät sen match()-rakenteessa ja kutsut sopivaa funktiota. Tässä esimerkki uutislistasta kuvien kanssa:
1 <?php 2 3 function 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 }
Käyttäjän puolella tämä näyttää korttiruudukolta: kuva vasemmalla, otsikko oikealla. Minkä tahansa kohdan napauttaminen avaa linkin selaimeen.

Galleria, artikkelilista tai kyselyt kootaan täsmälleen samalla tavalla; vain $buttons-taulukon sisältö ja viestin teksti vaihtuvat. Jos sisältöä on paljon ja JSON lähestyy 30 kt:n rajaa, jaa se sivuille "Seuraava"-painikkeen avulla.
Jos haluat mieluummin työskennellä valmiin PHP-kirjaston kuin raa'an API:n kanssa, tutustu Bogdaanin viber-bot-php -kirjastoon. Se hoitaa allekirjoituksen validoinnin, tapahtumien reitityksen ja JSONin muodostamisen puolestasi.
Yhteenveto: koko käyttöönottopolku
- Hanki token Viber Admin Panelista: Edit Info -osio → App Key.
- Julkaise käsittelijä palvelimelle, jossa on HTTPS. Let's Encrypt toimii; itse allekirjoitettu varmenne ei. Viber validoi varmenteet luotettujen Java Root CA -varmenteiden listaa vasten.
- Aseta webhook POST-pyynnöllä osoitteeseen
https://chatapi.viber.com/pa/set_webhookbodynä{"url":"https://your-domain/webhook.php","event_types":[...]}ja otsakkeellaX-Viber-Auth-Token. - Tarkista vastaus:
{"status":0}tarkoittaa onnistumista. Viber lähettää hetiwebhook-kutsun URL-osoitteeseesi. Varmista, että skripti palauttaa{"status":0,"status_message":"ok"}. - Lähetä ensimmäinen valikko:
conversation_started-tapahtumassa kutsugetMainMenu()ja välitä tulossendToViber()-funktiolle.
⁉️🤔 Usein kysytyt kysymykset
Voinko käyttää itse allekirjoitettua SSL-varmennetta webhookille?
Et. Viber validoi varmenteen luotettujen Java-juurivarmenteiden listaa vasten. Itse allekirjoitettu varmenne aiheuttaa
invalidUrl-virheen webhookia asetettaessa. Let's Encrypt on tällä listalla ja on ilmainen. Palvelimellasi ajacertbot --nginx -d your-domain.com, lisää automaattinen uusinta croniin, ja Viber hyväksyy varmenteen ongelmitta.
Mikä on ero reply- ja open-url-toimintotyypin välillä?
replylähettääActionBody-kentän takaisin webhookille viestitekstinä. PHP-skripti näkee sen muuttujassa$input['message']['text']ja reitittää senmatch()-funktion kautta. Käytä tätä botin sisäiseen navigointiin.open-urlavaa linkin ulkoisessa selaimessa eikä laukaise webhookia. Käytännössä valikot yhdistävät molempia tyyppejä: viisi tai kuusi reply-painiketta osioille ja yksi leveä open-url-painike verkkosivulle siirtymiseen.
Mitä viestityyppejä Viber Bot API tukee?
Viber Bot API tukee yhdeksää
type-arvoasend_message-kutsussa:text(pelkkä teksti),picture(JPEG-kuva),video(videotiedosto),file(mikä tahansa tiedosto enintään 50 Mt),location(maantieteellinen piste),contact(yhteystietokortti),sticker(tarra),rich_media(korttikaruselli) jaurl(linkin esikatselu). Ajantasainen lista pakollisine kenttineen löytyy Viber Developers Hubin dokumentaatiosta. Yleisin skenaario ontext+keyboardvalikoille japicturekuvien lähettämiseen. Karusellit sopivat erinomaisesti verkkokauppojen julkisivuihin ja tuoteluetteloihin, mutta vaativat enemmän koodia.
Mitä teen, jos käyttäjä ei näe näppäimistöä?
Yleisiä syitä on kolme. Ensimmäinen: näppäimistön sisältävä JSON ylitti 30 kt, ja Viber hylkää tällaiset viestit äänettömästi. Tarkista
strlen(json_encode($data))ennen lähetystä. Toinen: vastausset_webhook-kutsuun ei sisältänyt"status":0-arvoa, webhookia ei asetettu, eikä botti vastaanota viestejä. Kolmas: käytät vanhaa formaattia, jossaauth_tokenon JSON-bodyssä. API 7.0:sta lähtien tämä ohitetaan; tarvitsetX-Viber-Auth-Token-otsakkeen. Vianetsintää varten ota käyttöön Viber API -vastauksen lokitus: se palauttaa luettavaa JSONia virhekoodeineen invalidAuthToken, badData tai missingData.
Voinko vaihtaa näppäimistön lähetyksen jälkeen?
Kyllä. Jokaisen uuden viestin mukana voit lähettää eri näppäimistön. Viber-sovellus näyttää aina viimeisimmän vastaanotetun. Tämän avulla voit rakentaa monitasoisia valikoita: päävalikko → osion alavalikko → tietty sisältö. Jokaisella tasolla on omat painikkeensa, ja käyttäjä liikkuu niiden välillä painamalla reply-näppäimiä.
Paljonko Viber-botin käynnistäminen maksaa vuonna 2026?
Helmikuun 5. päivästä 2024 alkaen uuden botin luominen maksaa 100 € kuukaudessa virallisten Rakuten Viber -kumppaneiden kautta. Ennen tätä päivämäärää luodut botit jatkavat vanhoilla ehdoilla. Kustannus sisältää oman tilin hallintapaneelilla, analytiikan ja pääsyn kaikkiin viestityyppeihin, mukaan lukien rich_media ja Viber Pay. API:n tekninen osa on identtinen kaupallisille ja vanhoille ilmaisboteille.
Botti on valmis: mitä seuraavaksi
Näppäimistövalikko on vasta sisäänkäynti. Kun perusmekaniikka toimii, lisää sisältökaruselleja rich_media-tyypillä, maksuja Viber Payn kautta ja käyttäjäsegmentointia sen perusteella, mitä painikkeita he painavat useimmin. Jokainen uusi taso ei muuta perustaa: luet edelleen event-kenttää ja lähetät edelleen send_message-kutsun X-Viber-Auth-Token-otsakkeella.
Jos tarvitset toimivan koodin live-esimerkin, katso viber-bot-php-repositorio GitHubissa. Se kattaa kaikki tapahtumat, pyyntöjen allekirjoittamisen ja kuvallisen näppäimistön rakentamisen. Ja visuaalista aloitusta varten tässä on puolen tunnin opastusvideo Viber-botin luomisesta alusta alkaen:
Tärkeintä on muistaa: Viber Bot API on aluksi yksinkertainen, mutta vaativa yksityiskohtien suhteen. Oikea todennusotsake, luotettu SSL, validi JSON alle 30 kt ja selkeä ActionBody-reititys riittävät pitämään botin toiminnassa ilman virheitä. Ota yllä olevat koodinpätkät, korvaa omalla tokenillasi ja domainillasi ja käynnistä ensimmäinen valikkosi tänään.



