andre/bionic

Bionic is a simple chat bot development library in PHP

v2.1.9 2024-03-19 08:29 UTC

README

Bionic is a simple chat bot development library in PHP.

It is driven by a very simple but powerful event dispatching library Événement and Guzzle a PHP HTTP client that makes it easy to send HTTP requests

Platform support

  • Facebook Messenger
  • WhatsApp
  • Instagram
  • Telegram
  • Viber

Facebook Messenger and Instagram

What is covered

  • Create a FB Page
  • Create a FB app
  • Create a webhook
  • Connect the Facebook app to the Facebook page
  • Setup Bionic

Installation

Create a FB page

First login to Facebook and create a Facebook page. Choose the settings that fits best your bot, but for testing it is not important.

Create a FB Messenger app

Go to the developer's app page. Click "Add a New App" and fill the basic app fields.

On the "Product Setup" page choose Messenger and click "Get Started".

Now you need to create a token to give your app access to your Facebook page. Select the created page, grant permissions and copy the generated token. You need that one later.

Create a webhook for the Facebook app for either Messenger or Instagram

Your application needs to have a webhook. This means a public URL that Facebook can communicate with. Every time a user sends a message inside the FB chat, FB will send it to this URL which is the entry point to your application.

Connect the Facebook app to your application

Now that you got the URL you need to setup the webhook. Go back to you Facebook app settings and click Setup Webhooks inside the Webhooks part.

Fill in the public URL, check the subscription fields you want to with and click Verify and Save.

Note: You need to write your own webhook verification logic in your application.

Setup Bionic

The recommended way to install Bionic is through composer.

Just create a composer.json file for your project and require it:

composer require andre/bionic

Now you can add the autoloader, and you will have access to the library:

<?php
require 'vendor/autoload.php';

Usage

Creating a Bionic instance

<?php
use Andre\Bionic\Bionic;

$bionic = Bionic::initialize();

Registering event listeners

Syntax

<?php
$bionic->listen($event_name, $event_listener);

With an anonymous function

<?php
$bionic->listen($event_name, function($required_parameters_depending_on_event_name){});

With a defined function

<?php
function function_name($required_parameters_depending_on_event_name){}

$bionic->listen($event_name, 'function_name');

With a class method

<?php
class BotController{
    public function function_name($required_parameters_depending_on_event_name){}
}

$controller = new BotController();
$bionic->listen($event_name, [$controller, 'function_name']);

With a static class method

<?php
class BotController{
    public static function function_name($required_parameters_depending_on_event_name){}
}

$bionic->listen($event_name, [BotController::class, 'function_name']);

Usage with messenger and Instagram

<?php
use Andre\Bionic\Bionic;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Nlp;
use Andre\Bionic\Plugins\Messenger\Messages\Message\QuickReply;
use Andre\Bionic\Plugins\Messenger\Messages\Message\ReplyTo;
use Andre\Bionic\Plugins\Messenger\Messages\Referral;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Text;
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Sender;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Recipient;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Attachments\Image;
use Andre\Bionic\Plugins\Messenger\Messages\Message;

/* validate verify token needed for setting up web hook */
if (isset($_GET['hub_verify_token'])) {
    if ($_GET['hub_verify_token'] === 'your verify token') {
        echo $_GET['hub_challenge'];
        return;
    } else {
        echo 'Invalid Verify Token';
        return;
    }
}

$data = json_decode(file_get_contents('php://input'), true);

$config = [
    'page_access_token' => 'your page access token',
    // 'graph_api_version' => 'v9.0' optional and defaults to v9.0
];

// This applies for only instagram and messenger where you need to specify the object type as the events prefix
$object_type = "page"; // page or instagram

$bionic = Bionic::initialize()
    ->setPlugin(Plugin::create($config))
    ->setEventPrefix($object_type);

// register your event listeners before calling the 'receive' method on the bionic instance
// $bionic->listen($event_name, $event_listener);
$bionic->listen('message.attachments.image', function (Plugin $plugin, Sender $sender, Recipient $recipient, Message $message, Image $image, $channel){
    // $plugin - current plugin being used i.e. MessengerPlugin
    // $sender - sender of the message i.e. Messenger user
    // $recipient - recipient of the message i.e. Your facebook page
    // $message - current message object
    // $image - Image attachment that was sent
    // $channel - event delivery channel, messaging or standby
   
    // this sends the attachment as a message back to the sender
    $plugin->sendAttachment($image, $sender);
})->listen('message.text', function (Plugin $plugin, Sender $sender, Recipient $recipient, Message $message, Text $text, QuickReply $quickReply = null, ReplyTo $replyTo = null, Referral $referral = null, Nlp $nlp = null, $channel) {
      $text->getText();
      if ($quickReply)
          $quickReply->getPayload();
  
      if ($nlp)
          $nlp->getEntities();
  
      $plugin->sendText($text, [], $sender);
})->listen('exceptions', function (Exception $exception) {
      
});

$bionic->receive($data);
return http_response_code(200);

Basic example

<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Sender;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Recipient;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Attachments\Image;
use Andre\Bionic\Plugins\Messenger\Messages\Message;

$bionic->listen('message.attachments.image', function (Plugin $plugin, Sender $sender, Recipient $recipient, Message $message, Image $image, $channel){  
    // this sends back the attachment as a message back to the sender
    $plugin->sendAttachment($image, $sender);
});

Available events provided for messenger and Instagram

Some events do not apply for Instagram, consult documentation

  • entry
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;

$bionic->listen('entry', function (Plugin $plugin, $entryItems){
    
     /**
     * @var \Andre\Bionic\Plugins\Messenger\Messages\EntryItem $entryItem
     * @var \Andre\Bionic\Plugins\Messenger\Messages\MessagingItem $messagingItem
     */
     
     // $entryItems is an array of Andre\Bionic\Plugins\Messenger\Messages\EntryItem::class
     foreach ($entryItems as $entryItem){
         foreach ($entryItem->getMessagingItems() as $messagingItem){
             $messagingItem->getMessage();
             $messagingItem->getPostback();
             $messagingItem->getAccountLinking();
             $messagingItem->getReferral();
             $messagingItem->getRead();
             $messagingItem->getDelivery();
             $messagingItem->getOptin();
             $messagingItem->getSender();
             $messagingItem->getRecipient();
             $messagingItem->getTimestamp();
             $messagingItem->getCheckoutUpdate();
             $messagingItem->getAppRoles();
             $messagingItem->getPassThreadControl();
             $messagingItem->getTakeThreadControl();
             $messagingItem->getPreCheckout();
             $messagingItem->getPayment();
         }
     }
});
  • entry.item
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\EntryItem;

$bionic->listen('entry.item', function (Plugin $plugin, EntryItem $entryItem){
    /**
     * @var \Andre\Bionic\Plugins\Messenger\Messages\EntryItem $entryItem
     * @var \Andre\Bionic\Plugins\Messenger\Messages\MessagingItem $messagingItem
     */
    foreach ($entryItem->getMessagingItems() as $messagingItem){
         $messagingItem->getMessage();
         $messagingItem->getPostback();
         $messagingItem->getAccountLinking();
         $messagingItem->getReferral();
         $messagingItem->getRead();
         $messagingItem->getDelivery();
         $messagingItem->getOptin();
         $messagingItem->getSender();
         $messagingItem->getRecipient();
         $messagingItem->getTimestamp();
         $messagingItem->getCheckoutUpdate();
         $messagingItem->getAppRoles();
         $messagingItem->getPassThreadControl();
         $messagingItem->getTakeThreadControl();
         $messagingItem->getPreCheckout();
         $messagingItem->getPayment();
    }
});
  • messaging
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;

$bionic->listen('messaging', function (Plugin $plugin, $messagingItems){
    /**
     * @var \Andre\Bionic\Plugins\Messenger\Messages\MessagingItem $messagingItem
     */
    
     // $messagingItems is an array of Andre\Bionic\Plugins\Messenger\Messages\MessagingItem::class
     foreach ($messagingItems as $messagingItem){
          $messagingItem->getMessage();
          $messagingItem->getPostback();
          $messagingItem->getAccountLinking();
          $messagingItem->getReferral();
          $messagingItem->getRead();
          $messagingItem->getDelivery();
          $messagingItem->getOptin();
          $messagingItem->getSender();
          $messagingItem->getRecipient();
          $messagingItem->getTimestamp();
          $messagingItem->getCheckoutUpdate();
          $messagingItem->getAppRoles();
          $messagingItem->getPassThreadControl();
          $messagingItem->getTakeThreadControl();
          $messagingItem->getPreCheckout();
          $messagingItem->getPayment();
     }
});
  • standby
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;

$bionic->listen('standby', function (Plugin $plugin, $standbyItems){
    /**
     * @var \Andre\Bionic\Plugins\Messenger\Messages\StandbyItem $standbyItem
     */
    
     // $messagingItems is an array of Andre\Bionic\Plugins\Messenger\Messages\$standbyItems::class
     foreach ($standbyItems as $standbyItem){
          $standbyItem->getMessage();
          $standbyItem->getRead();
          $standbyItem->getDelivery();
     }
});
  • messaging.item
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\MessagingItem;

$bionic->listen('messaging.item', function (Plugin $plugin, MessagingItem $messagingItem){
    /**
     * @var \Andre\Bionic\Plugins\Messenger\Messages\MessagingItem $messagingItem
     */
    
    $messagingItem->getMessage();
    $messagingItem->getPostback();
    $messagingItem->getAccountLinking();
    $messagingItem->getReferral();
    $messagingItem->getRead();
    $messagingItem->getDelivery();
    $messagingItem->getOptin();
    $messagingItem->getSender();
    $messagingItem->getRecipient();
    $messagingItem->getTimestamp();
    $messagingItem->getCheckoutUpdate();
    $messagingItem->getAppRoles();
    $messagingItem->getPassThreadControl();
    $messagingItem->getTakeThreadControl();
    $messagingItem->getPreCheckout();
    $messagingItem->getPayment();
});
  • standby.item
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\StandbyItem;

$bionic->listen('standby.item', function (Plugin $plugin, StandbyItem $standbyItem){
    $standbyItem->getMessage();
    $standbyItem->getRead();
    $standbyItem->getDelivery();
});
  • message
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Sender;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Recipient;
use Andre\Bionic\Plugins\Messenger\Messages\Message;

$bionic->listen('message', function (Plugin $plugin, Sender $sender, Recipient $recipient, Message $message, $channel){
    // $message - represents message sent to your page
    $message->getText();
    $message->getNlp();
    $message->getQuickReply();
    $message->getAppId();
    $message->getAttachmentItems();
    $message->getMetadata();
    $message->getMid();
    $message->getSeq();
    $message->isEcho(); // false
});
  • message.echo
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Sender;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Recipient;
use Andre\Bionic\Plugins\Messenger\Messages\Message;

$bionic->listen('message.echo', function (Plugin $plugin, Sender $sender, Recipient $recipient, Message $message){
    // $message - represents message sent by your page
    $message->getText();
    $message->getQuickReply();
    $message->getAppId();
    $message->getAttachmentItems();
    $message->getMetadata();
    $message->getMid();
    $message->getSeq();
    $message->isEcho(); // true
});
  • message.text
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Sender;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Recipient;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Text;
use Andre\Bionic\Plugins\Messenger\Messages\Message\QuickReply;
use Andre\Bionic\Plugins\Messenger\Messages\Message\ReplyTo;
use Andre\Bionic\Plugins\Messenger\Messages\Referral;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Nlp;
use Andre\Bionic\Plugins\Messenger\Messages\Message;

$bionic->listen('message.text', function (Plugin $plugin, Sender $sender, Recipient $recipient, Message $message, Text $text, QuickReply $quickReply = null, ReplyTo $replyTo = null, Referral $referral = null, Nlp $nlp = null, $channel){
    $text->getText();
    if ($quickReply)
        $quickReply->getPayload();
    
    if ($nlp)
        $nlp->getEntities();
    
    $plugin->sendPlainText($text->getText(), [], $sender);
    $plugin->sendText($text, [], $sender);
});
  • message.attachments
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Sender;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Recipient;
use Andre\Bionic\Plugins\Messenger\Messages\Message;

$bionic->listen('message.attachments', function (Plugin $plugin, Sender $sender, Recipient $recipient, Message $message, $messageAttachments, $channel){
    // $messageAttachments - an array of attachments e.g. Image, Audio, Location, Video, Fallback
    foreach ($messageAttachments as $attachment){
        $attachment->getType();
        $plugin->sendAttachment($attachment, $sender);
    }
});
  • message.attachments.image
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Sender;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Recipient;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Attachments\Image;
use Andre\Bionic\Plugins\Messenger\Messages\Message;

$bionic->listen('message.attachments.image', function (Plugin $plugin, Sender $sender, Recipient $recipient, Message $message, Image $image, $channel){
    $image->getPayload()->getUrl();
    $plugin->sendAttachment($image, $sender);
});
  • message.attachments.audio
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Sender;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Recipient;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Attachments\Audio;
use Andre\Bionic\Plugins\Messenger\Messages\Message;

$bionic->listen('message.attachments.audio', function (Plugin $plugin, Sender $sender, Recipient $recipient, Message $message, Audio $audio, $channel){
    $audio->getPayload()->getUrl();
    
    // Sending audio is only supported on messenger
    $plugin->sendAttachment($audio, $sender);
});
  • message.attachments.video
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Sender;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Recipient;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Attachments\Video;
use Andre\Bionic\Plugins\Messenger\Messages\Message;

$bionic->listen('message.attachments.video', function (Plugin $plugin, Sender $sender, Recipient $recipient, Message $message, Video $video, $channel){
    $video->getPayload()->getUrl();
    
    // Sending videos is only supported on messenger
    $plugin->sendAttachment($video, $sender);
});
  • message.attachments.location
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Sender;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Recipient;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Attachments\Location;
use Andre\Bionic\Plugins\Messenger\Messages\Message;

$bionic->listen('message.attachments.location', function (Plugin $plugin, Sender $sender, Recipient $recipient, Message $message, Location $location, $channel){
    $coordinates = $location->getPayload()->getCoordinates();
    $coordinates->getLat();
    $coordinates->getLong();
});
  • message.attachments.file
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Sender;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Recipient;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Attachments\File;
use Andre\Bionic\Plugins\Messenger\Messages\Message;

$bionic->listen('message.attachments.file', function (Plugin $plugin, Sender $sender, Recipient $recipient, Message $message, File $file, $channel){
    $file->getPayload()->getUrl();
    $plugin->sendAttachment($file, $sender);
});
  • message.attachments.fallback
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Sender;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Recipient;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Attachments\Fallback;
use Andre\Bionic\Plugins\Messenger\Messages\Message;

$bionic->listen('message.attachments.fallback', function (Plugin $plugin, Sender $sender, Recipient $recipient, Message $message, Fallback $fallback, $channel){
    $fallback->getTitle();
    $fallback->getURL();
});
  • postback
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Sender;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Recipient;
use Andre\Bionic\Plugins\Messenger\Messages\PostBack;

$bionic->listen('postback', function (Plugin $plugin, Sender $sender, Recipient $recipient, PostBack $postBack){
    $postBack->getPayload();
});
  • referral
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Sender;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Recipient;
use Andre\Bionic\Plugins\Messenger\Messages\Referral;

$bionic->listen('referral', function (Plugin $plugin, Sender $sender, Recipient $recipient, Referral $referral){
    $referral->getType();
    $referral->getSource();
});
  • optin
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Sender;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Recipient;
use Andre\Bionic\Plugins\Messenger\Messages\Optin;

$bionic->listen('optin', function (Plugin $plugin, Sender $sender = null, Recipient $recipient, Optin $optin){
    $optin->getRef();
    
    // if using Checkbox Plugin and set user_ref
    if ($optin->getUserRef()){
        $response = $plugin->sendPlainText("Hello, thank you for opting in.", [], Recipient::create(['user_ref' => $optin->getUserRef()]));
        $response->getBody()->getContents(); // information about the response
    }
});
  • account_linking
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Sender;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Recipient;
use Andre\Bionic\Plugins\Messenger\Messages\AccountLinking;

$bionic->listen('account_linking', function (Plugin $plugin, Sender $sender, Recipient $recipient, AccountLinking $accountLinking){
    $status = $accountLinking->getStatus();
    if ($status == 'linked')
        $accountLinking->getAuthorizationCode();
});
  • delivery
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Sender;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Recipient;
use Andre\Bionic\Plugins\Messenger\Messages\Delivery;

$bionic->listen('delivery', function (Plugin $plugin, Sender $sender, Recipient $recipient, Delivery $delivery, $channel){
    $delivery->getMids();
    $delivery->getSeq();
    $delivery->getWatermark();
});
  • read
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Sender;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Recipient;
use Andre\Bionic\Plugins\Messenger\Messages\Read;

$bionic->listen('read', function (Plugin $plugin, Sender $sender, Recipient $recipient, Read $read, $channel){
    $read->getSeq();
    $read->getWatermark();
});
  • policy_enforcement
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Recipient;
use Andre\Bionic\Plugins\Messenger\Messages\PolicyEnforcement;

$bionic->listen('policy_enforcement', function (Plugin $plugin, Recipient $recipient, PolicyEnforcement $policyEnforcement){
    $action = $policyEnforcement->getAction();
    if ($action == 'block')
        $policyEnforcement->getReason();
});
  • payment
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Sender;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Recipient;
use Andre\Bionic\Plugins\Messenger\Messages\Payment\Payment;

$bionic->listen('payment', function (Plugin $plugin, Sender $sender, Recipient $recipient, Payment $payment){
    $payment->getShippingOptionId();
    $payment->getPaymentCredential();
    $payment->getRequestedUserInfo();
    $payment->getAmount();
});
  • checkout_update
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Sender;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Recipient;
use Andre\Bionic\Plugins\Messenger\Messages\Payment\CheckoutUpdate;

$bionic->listen('checkout_update', function (Plugin $plugin, Sender $sender, Recipient $recipient, CheckoutUpdate $checkoutUpdate){
    $checkoutUpdate->getPayload();
    $checkoutUpdate->getShippingAddress();
});
  • pre_checkout
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Sender;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Recipient;
use Andre\Bionic\Plugins\Messenger\Messages\Payment\PreCheckout;

$bionic->listen('pre_checkout', function (Plugin $plugin, Sender $sender, Recipient $recipient, PreCheckout $preCheckout){
    $preCheckout->getPayload();
    $preCheckout->getRequestedUserInfo();
    $preCheckout->getAmount();
});
  • pass_thread_control
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Sender;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Recipient;
use Andre\Bionic\Plugins\Messenger\Messages\PassThreadControl;

$bionic->listen('pass_thread_control', function (Plugin $plugin, Sender $sender, Recipient $recipient, PassThreadControl $passThreadControl){
    $passThreadControl->getNewOwnerAppId();
    $passThreadControl->getMetadata();
});
  • take_thread_control
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Sender;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Recipient;
use Andre\Bionic\Plugins\Messenger\Messages\TakeThreadControl;

$bionic->listen('take_thread_control', function (Plugin $plugin, Sender $sender, Recipient $recipient, TakeThreadControl $takeThreadControl){
    $takeThreadControl->getPreviousOwnerAppId();
    $takeThreadControl->getMetadata();
});
  • app_roles
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Recipient;
use Andre\Bionic\Plugins\Messenger\Messages\AppRoles;

$bionic->listen('app_roles', function (Plugin $plugin, Recipient $recipient, AppRoles $appRoles){
    $appRoles->getAppId();
    $appRoles->getAppRoles();
});

Supported Buttons

NOTE: Explore class files for a better understanding of provided methods

  • UrlButton
<?php
use Andre\Bionic\Plugins\Messenger\Messages\Message\Buttons\UrlButton;
$url_button = UrlButton::create();
  • PostBackButton
<?php
use Andre\Bionic\Plugins\Messenger\Messages\Message\Buttons\PostBackButton;
$post_back_button = PostBackButton::create();
  • ShareButton
<?php
use Andre\Bionic\Plugins\Messenger\Messages\Message\Buttons\ShareButton;
$share_button = ShareButton::create();
  • CallButton
<?php
use Andre\Bionic\Plugins\Messenger\Messages\Message\Buttons\CallButton;
$call_button = CallButton::create();
  • LoginButton
<?php
use Andre\Bionic\Plugins\Messenger\Messages\Message\Buttons\LoginButton;
$login_button = LoginButton::create();
  • LogoutButton
<?php
use Andre\Bionic\Plugins\Messenger\Messages\Message\Buttons\LogoutButton;
$logout_button = LogoutButton::create();
  • BuyButton
<?php
use Andre\Bionic\Plugins\Messenger\Messages\Message\Buttons\BuyButton;
$buy_button = BuyButton::create();

Sending Messages

  • Text and quick replies
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Sender;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Recipient;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Text;
use Andre\Bionic\Plugins\Messenger\Messages\Message\QuickReply;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Nlp;
use Andre\Bionic\Plugins\Messenger\Messages\Message;

$bionic->listen('message.text', function (Plugin $plugin, Sender $sender, Recipient $recipient, Message $message, Text $text, QuickReply $quickReply = null, Nlp $nlp = null, $channel){
    // sending text
    $plugin->sendText($text, [], $sender);
    
    // with quick reply
    $quick_replies = [
        QuickReply::create()->setContentType('text')->setTitle('Yes')->setPayload('yes'),
        QuickReply::create()->setContentType('text')->setTitle('No')->setPayload('no')
    ];
    $plugin->sendText($text, $quick_replies, $sender);
});
  • Sender action
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Sender;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Recipient;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Text;
use Andre\Bionic\Plugins\Messenger\Messages\Message\QuickReply;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Nlp;
use Andre\Bionic\Plugins\Messenger\Messages\Message;

$bionic->listen('message.text', function (Plugin $plugin, Sender $sender, Recipient $recipient, Message $message, Text $text, QuickReply $quickReply = null, Nlp $nlp = null, $channel){
    $plugin->sendAction($sender); // default mark_seen
    $plugin->sendAction($sender, 'typing_on');
    $plugin->sendAction($sender, 'typing_off');
});

Attachments

  • Image
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Sender;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Recipient;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Attachments\Image;
use Andre\Bionic\Plugins\Messenger\Messages\Message;

$bionic->listen('message.attachments.image', function (Plugin $plugin, Sender $sender, Recipient $recipient, Message $message, Image $image, $channel){
    $plugin->sendAttachment($image, $sender);
});
  • Audio
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Sender;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Recipient;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Attachments\Audio;
use Andre\Bionic\Plugins\Messenger\Messages\Message;

$bionic->listen('message.attachments.audio', function (Plugin $plugin, Sender $sender, Recipient $recipient, Message $message, Audio $audio, $channel){
    $plugin->sendAttachment($audio, $sender);
});
  • Video
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Sender;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Recipient;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Attachments\Video;
use Andre\Bionic\Plugins\Messenger\Messages\Message;

$bionic->listen('message.attachments.video', function (Plugin $plugin, Sender $sender, Recipient $recipient, Message $message, Video $video, $channel){
    $plugin->sendAttachment($video, $sender);
});

Supported Templates

  • Generic Template
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Sender;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Recipient;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Attachments\Image;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Attachments\Templates\GenericTemplate;
use Andre\Bionic\Plugins\Messenger\Messages\Payload\GenericTemplatePayload;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Attachments\Templates\TemplateElement;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Buttons\UrlButton;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Buttons\PostBackButton;
use Andre\Bionic\Plugins\Messenger\Messages\Message;

$bionic->listen('message.attachments.image', function (Plugin $plugin, Sender $sender, Recipient $recipient, Message $message, Image $image, $channel){
    // actions
    $url_button = UrlButton::create(['url' => 'http://localhost']);
    $post_back_button = PostBackButton::create(['title' => 'Payload Button', 'payload' => 'payload_button']);
    
    // template element
    $template_element = TemplateElement::create()
        ->setImageUrl($image->getPayload()->getUrl())
        ->setTitle("Generic Template")
        ->setSubtitle("Am a generic template")
        ->setDefaultAction($url_button)
        ->setButtons([
            $url_button->setTitle("Url Button"),
            $post_back_button
        ]);
    
    // template payload
    $template_payload = GenericTemplatePayload::create()
        ->setElements([$template_element]);
    
    // generic template
    $generic_template = GenericTemplate::create()
        ->setPayload($template_payload);
    
    $plugin->sendAttachment($generic_template, $sender);
});
  • List Template
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Sender;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Recipient;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Attachments\Image;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Attachments\Templates\ListTemplate;
use Andre\Bionic\Plugins\Messenger\Messages\Payload\ListTemplatePayload;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Attachments\Templates\TemplateElement;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Buttons\UrlButton;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Buttons\PostBackButton;
use Andre\Bionic\Plugins\Messenger\Messages\Message;

$bionic->listen('message.attachments.image', function (Plugin $plugin, Sender $sender, Recipient $recipient, Message $message, Image $image, $channel){
    // actions
    $url_button = UrlButton::create(['url' => 'http://localhost']);
    $post_back_button = PostBackButton::create(['title' => 'View', 'payload' => 'payload_button']);
    
    // template element
    $template_element = TemplateElement::create()
        ->setImageUrl($image->getPayload()->getUrl())
        ->setTitle("List Template")
        ->setSubtitle("Am a generic template")
        ->setDefaultAction($url_button)
        ->setButtons([$post_back_button]); // maximum of one button
    
    // template payload
    $template_payload = ListTemplatePayload::create()
        ->setElements([$template_element, $template_element, $template_element]);
    
    // list template
    $list_template = ListTemplate::create()
        ->setPayload($template_payload);
    
    $plugin->sendAttachment($list_template, $sender);
});
  • Button Template
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Sender;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Recipient;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Attachments\Templates\ButtonTemplate;
use Andre\Bionic\Plugins\Messenger\Messages\Payload\ButtonTemplatePayload;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Buttons\UrlButton;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Buttons\PostBackButton;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Text;
use Andre\Bionic\Plugins\Messenger\Messages\Message\QuickReply;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Nlp;
use Andre\Bionic\Plugins\Messenger\Messages\Message;

$bionic->listen('message.text', function (Plugin $plugin, Sender $sender, Recipient $recipient, Message $message, Text $text, QuickReply $quickReply = null, Nlp $nlp = null, $channel){
    // actions
    $url_button = UrlButton::create(['url' => 'http://localhost', 'title' => 'Button']);
    $post_back_button = PostBackButton::create(['title' => 'PostBack', 'payload' => 'payload_button']);
    
    // template payload
    $template_payload = ButtonTemplatePayload::create()
        ->setText($text->getText())
        ->setButtons([$url_button, $post_back_button]);
    
    // button template
    $button_template = ButtonTemplate::create()
        ->setPayload($template_payload);
    
    $plugin->sendAttachment($button_template, $sender);
});
  • Receipt Template
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Sender;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Recipient;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Text;
use Andre\Bionic\Plugins\Messenger\Messages\Message\QuickReply;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Nlp;
use Andre\Bionic\Plugins\Messenger\Messages\Payment\ShippingAddress;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Attachments\Templates\Receipt\ReceiptSummary;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Attachments\Templates\TemplateElement;
use Andre\Bionic\Plugins\Messenger\Messages\Payload\ReceiptTemplatePayload;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Attachments\Templates\Receipt\ReceiptAdjustment;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Attachments\Templates\Receipt\ReceiptTemplate;
use Andre\Bionic\Plugins\Messenger\Messages\Message;

$bionic->listen('message.text', function (Plugin $plugin, Sender $sender, Recipient $recipient, Message $message, Text $text, QuickReply $quickReply = null, Nlp $nlp = null, $channel){

    $address = ShippingAddress::create()
        ->setStreet1('1 Hacker Way')
        ->setCity("Menlo Park")
        ->setPostalCode("94025")
        ->setState("CA")
        ->setCountry("US");

    $summary = ReceiptSummary::create()
        ->setSubtotal(75.00)
        ->setShippingCost(4.95)
        ->setTotalTax(6.19)
        ->setTotalCost(56.14);
    
    $element_1 = TemplateElement::create([
        "title" => "Classic White T-Shirt",
        "subtitle" => "100% Soft and Luxurious Cotton",
        "quantity" => 2,
        "price" => 50,
        "currency" => "USD",
        "image_url" => "http://petersapparel.parseapp.com/img/whiteshirt.png"
        ]);
    
    $element_2 = TemplateElement::create()
        ->setTitle("Classic Gray T-Shirt")
        ->setSubtitle("100% Soft and Luxurious Cotton")
        ->setQuantity(1)->setPrice(25)
        ->setCurrency("USD")
        ->setImageUrl("http://petersapparel.parseapp.com/img/grayshirt.png");
    
    $payload = ReceiptTemplatePayload::create()
        ->setRecipientName("Stephane Crozatier")
        ->setOrderNumber("12345678902")
        ->setCurrency("USD")
        ->setPaymentMethod("Visa 2345")
        ->setOrderUrl("http://petersapparel.parseapp.com/order?order_id=123456")
        ->setTimestamp("1428444852")
        ->setAddress($address)
        ->setSummary($summary)
        ->setElements([$element_1, $element_2])
        ->setAdjustments([
            ReceiptAdjustment::create(["name" => "New Customer Discount", "amount" => 20]),
            ReceiptAdjustment::create(["name" => "$10 Off Coupon", "amount" => 10])
        ]);
    
    $receipt = ReceiptTemplate::create()->setPayload($payload);
    
    $plugin->sendAttachment($receipt, $sender);
});

Others

  • Open Graph Template
  • Media Template

Accessing a user profile information

<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Sender;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Recipient;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Text;
use Andre\Bionic\Plugins\Messenger\Messages\Message\QuickReply;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Nlp;
use Andre\Bionic\Plugins\Messenger\Messages\Message;

$bionic->listen('message.text', function (Plugin $plugin, Sender $sender, Recipient $recipient, Message $message, Text $text, QuickReply $quickReply = null, Nlp $nlp = null, $channel){
    $profile = $plugin->getUserProfile($sender); // returns an instance of Andre\Bionic\Plugins\Messenger\UserProfile::class
    $profile->getFirstName();
    $profile->getId();
    $profile->getLastName();
    $profile->getProfilePic();
    $plugin->sendPlainText('Hi, ' . $profile->getFirstName() . ' ' . $profile->getLastName(), [], $sender);
});

Messenger Profile

  • Setting the Get Started Button Postback
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\BotProfile\GetStarted;
$config = [
    'page_access_token' => 'your page access token'
];

$plugin = Plugin::create($config);
$plugin->setGetStarted(GetStarted::create(["payload" => "get_started"]));
  • Setting the Greeting Text
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\BotProfile\GreetingText;
$config = [
    'page_access_token' => 'your page access token'
];

$plugin = Plugin::create($config);

$greeting_default = GreetingText::create(["locale" => "default", "text" => "Hello!"]);
$greeting_en_US = GreetingText::create(["locale" => "en_US", "text" => "Timeless apparel for the masses"]);

$plugin->setGreetingText([$greeting_default, $greeting_en_US]);
  • Whitelisting domains
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
$config = [
    'page_access_token' => 'your page access token'
];

$plugin = Plugin::create($config);
$plugin->whitelistDomains(['http://example.com', 'http://app.example.com']);
  • Persistent menu
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\BotProfile\PersistentMenu;
use Andre\Bionic\Plugins\Messenger\BotProfile\PersistentMenuItem;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Buttons\PostBackButton;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Buttons\UrlButton;
$config = [
    'page_access_token' => 'your page access token'
];

$plugin = Plugin::create($config);

$menu_item = PersistentMenuItem::create(["title" => "My Account", "type" => "nested"]);
$post_back_1 = PostBackButton::create(["title" => "Pay Bill", "payload" => "PAYBILL_PAYLOAD"]);
$post_back_2 = PostBackButton::create(["title" => "History", "payload" => "HISTORY_PAYLOAD"]);
$post_back_3 = PostBackButton::create(["title" => "Contact Info", "payload" => "CONTACT_INFO_PAYLOAD"]);

$menu_item->setCallToActions([$post_back_1, $post_back_2, $post_back_3]);
$url_button = UrlButton::create(["title" => "Contact Info", "url" => "http://example.com"]);

$persistent_menu_default = PersistentMenu::create(['locale' => 'default', 'composer_input_disabled' => false]);
$persistent_menu_default->setCallToActions([$menu_item, $url_button]);

$persistent_menu_zh_CN = PersistentMenu::create(['locale' => 'zh_CN', 'composer_input_disabled' => false]);
$persistent_menu_zh_CN->setCallToActions([$post_back_1]);

$plugin->setPersistentMenu([$persistent_menu_default, $persistent_menu_zh_CN]);
  • Deleting Messenger Profile Properties
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;

$config = [
    'page_access_token' => 'your page access token'
];

$plugin = Plugin::create($config);
$plugin->deleteProperties(['persistent_menu', 'get_started', 'greeting', 'whitelisted_domains']);
  • Setting public key for Tokenized Payments
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;

$config = [
    'page_access_token' => 'your page access token'
];

$plugin = Plugin::create($config);
$plugin->setPublicKey("<YOUR_PUBLIC_KEY>");
  • Setting Payment Privacy Policy URL
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;

$config = [
    'page_access_token' => 'your page access token'
];

$plugin = Plugin::create($config);
$plugin->setPrivacyUrl("<YOUR_PRIVACY_URL>");

Handover Protocol

  • Passing Thread Control
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Sender;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Recipient;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Text;
use Andre\Bionic\Plugins\Messenger\Messages\Message\QuickReply;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Nlp;
use Andre\Bionic\Plugins\Messenger\Messages\Message;

$bionic->listen('message.text', function (Plugin $plugin, Sender $sender, Recipient $recipient, Message $message, Text $text, QuickReply $quickReply = null, Nlp $nlp = null, $channel){
    $plugin->passThreadControl($sender, '123456789', 'String to pass to secondary receiver app');
});
  • Taking Thread Control
<?php
use Andre\Bionic\Plugins\Messenger\MessengerPlugin as Plugin;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Sender;
use Andre\Bionic\Plugins\Messenger\Messages\EndPoint\Recipient;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Text;
use Andre\Bionic\Plugins\Messenger\Messages\Message\QuickReply;
use Andre\Bionic\Plugins\Messenger\Messages\Message\Nlp;
use Andre\Bionic\Plugins\Messenger\Messages\Message;

$bionic->listen('message.text', function (Plugin $plugin, Sender $sender, Recipient $recipient, Message $message, Text $text, QuickReply $quickReply = null, Nlp $nlp = null, $channel){
    $plugin->takeThreadControl($sender, 'String to pass to secondary receiver app');
});

Usage with Telegram

<?php
use Andre\Bionic\Bionic;
use Andre\Bionic\Plugins\Telegram\TelegramPlugin as Plugin;
use Andre\Bionic\Plugins\Telegram\Message as TelegramMessage;

$data = json_decode(file_get_contents('php://input'), true);

$config = [
    'access_token' => 'your telegram access token',
];


$bionic = Bionic::initialize()
    ->setPlugin(Plugin::create($config));

// register your event listeners before calling the 'receive' method on the bionic instance
// $bionic->listen($event_name, $event_listener);
$bionic->listen('message', function (Plugin $plugin, $update_id, TelegramMessage $message) {
            
})->listen('channel-message', function (Plugin $plugin, $update_id, TelegramMessage $message) {
            
})->listen('edited-message', function (Plugin $plugin, $update_id, TelegramMessage $message) {
            
})->listen('edited-channel-message', function (Plugin $plugin, $update_id, TelegramMessage $message) {
            
});

$bionic->receive($data);
return http_response_code(200);

Usage with Viber

<?php
use Andre\Bionic\Bionic;
use Andre\Bionic\Plugins\Viber\ViberPlugin as Plugin;
use Andre\Bionic\Plugins\Viber\Message as ViberMessage;
use Andre\Bionic\Plugins\Viber\User as ViberUser;

$data = json_decode(file_get_contents('php://input'), true);

$config = [
    'access_token' => 'your viber access token',
];


$bionic = Bionic::initialize()
    ->setPlugin(Plugin::create($config));

// register your event listeners before calling the 'receive' method on the bionic instance
// $bionic->listen($event_name, $event_listener);
$bionic->listen('webhook', function (Plugin $plugin, $timestamp, $message_token) {
    
})->listen('subscribed', function (Plugin $plugin, $timestamp, $message_token, ViberUser $user) {
    
})->listen('un-subscribed', function (Plugin $plugin, $timestamp, $message_token, $user_id) {
    
})->listen('conversation-started', function (Plugin $plugin, $timestamp, $message_token, $type, $context, ViberUser $user, $subscribed) {
    
})->listen('delivered', function (Plugin $plugin, $timestamp, $message_token, $user_id) {
    
})->listen('seen', function (Plugin $plugin, $timestamp, $message_token, $user_id) {
    
})->listen('failed', function (Plugin $plugin, $timestamp, $message_token, $user_id, $desc) {
   
})->listen('message', function (Plugin $plugin, $timestamp, $message_token, ViberUser $user, ViberMessage $message) {
    
});

$bionic->receive($data);
return http_response_code(200);

Exception Handling

Any exceptions not caught when you are defining your event listeners logic are automatically captured. So remember to register a listener that listens for these exceptions.

<?php

$bionic->listen('exception', function (\Exception $exception){
    $exception->getMessage();
});

Bugs

For any bugs found, please email me at andrewmvp007@gmail.com or register an issue at issues