-
Notifications
You must be signed in to change notification settings - Fork 29
Home
Sections:
- Why Zanzara?
- Getting started
- Update listeners
- Update object
- Telegram Api methods
- Middleware
- Conversations
- Session
- Bulk messaging
- Error Handling
- Polling or Webhook
- Using a Local Bot API Server
- Proxy and DNS
- Examples
- Built with Zanzara
There is plenty of PHP libraries which help you write Telegram bots, so why should you use Zanzara?
We (developers) get annoyed easily, so if we are gonna make a Telegram Bot we want a working
environment set up as soon as possible
. Unlike other libraries that require you to configure a database and mess
up with webhooks/https-server/cron-job, you can copy-paste the following snippet and it just works:
<?php
use Zanzara\Zanzara;
use Zanzara\Context;
require __DIR__ . '/vendor/autoload.php';
$bot = new Zanzara($_ENV['BOT_TOKEN']);
$bot->onCommand('start', function (Context $ctx) {
$ctx->sendMessage('Hello');
});
$bot->run();
Thanks to ReactPHP, we can have a long-running process that
pulls updates from Telegram servers (polling
mode). This cannot
be achieved with traditional
PHP.
Your bot interacts with Telegram through http requests, a lot of http requests
. Why wait for a message to
be sent before performing a database query? Zanzara provides a way to call every Telegram Api method asynchronously and
get the result with a React promise. For example:
<?php
$bot = new Zanzara($_ENV['BOT_TOKEN']);
$bot->onCommand("start", function (Context $ctx) {
$ctx->sendMessage('Hello')->then(
function (Message $message) {
// success
},
function (TelegramException $error) {
// failed
}
);
// ... in the meantime perform some queries on MySql
});
$bot->run();
Asynchronous http requests are just one feature that ReactPHP brings to the table. With its event-driven non-blocking I/O model ReactPHP can drastically boost your bot performance.
Usually web applications delegate operations like authorization and internalization checks to middleware
.
ExpressJS provides it,
Laravel provides it, Zanzara
provides it. Here a simple example:
<?php
$bot = new Zanzara($_ENV['BOT_TOKEN']);
$m = function(Context $ctx, $next) {
// do something before
$next($ctx);
// do something after
};
$bot->onCommand("start", function (Context $ctx) {
$ctx->sendMessage('Hello');
})->middleware($m);
$bot->run();
More on Middleware section.
Have you ever got a 429
error from Telegram? It happens when you send too many messages
to one or more
chats. The official Telegram documentation encourages you to
spread notifications over longer intervals. We do it for you, just use the sendBulkMessage
method:
<?php
$bot = new Zanzara($_ENV['BOT_TOKEN']);
$bot->onCommand("start", function (Context $ctx) {
$chatIds = []; // ... read users from database
$ctx->sendBulkMessage($chatIds, 'A new notification for you', ['parse_mode' => 'HTML']);
});
$bot->run();
More on Bulk messaging section.
Zanzara is a framework to build asynchronous Telegram bots in PHP. We suppose you're already familiar with Telegram bots, PHP, Composer and that you've at least heard of ReactPHP.
Just make sure to have PHP (>= 7.3) and Composer installed on your machine.
We suppose you've already created a Telegram Bot through @BotFather and you have a valid bot token. If not, please read the official Telegram documentation before continuing.
You install Zanzara through composer
as follows:
composer require badfarm/zanzara
First thing to do is to instantiate the Zanzara class (ensure to have included the autoload.php
file):
<?php
require __DIR__ . '/vendor/autoload.php';
$bot = new Zanzara($_ENV['BOT_TOKEN']);
Its constructor takes one mandatory parameter: your bot token
. We strongly encourage you to put it in an external
.env
file and include it through dotenv libraries.
Note: by default Zanzara starts in polling mode. To use webhooks see Polling or Webhook.
Next thing to do is to tell the Framework that we want to listen for Telegram updates.
For example, to listen for the /start
command:
<?php
$bot = new Zanzara($_ENV['BOT_TOKEN']);
$bot->onCommand('start', function (Context $ctx) {
});
You can find the complete list of listener methods in Update listeners section.
Here for more examples.
As you have seen, each listener method takes a callback
function as parameter. The callback must always
accept one parameter of type Context
. The Context contains both the Update
received from Telegram and the
methods that allow you to interact with the Telegram Api
. Here some examples:
<?php
$bot = new Zanzara($_ENV['BOT_TOKEN']);
$bot->onCommand('start', function (Context $ctx) {
$userId = $ctx->getMessage()->getFrom()->getId();
$ctx->getUserProfilePhotos($userId);
$ctx->sendMessage('I have just stolen your profile photos');
});
$bot->onCbQuery(function (Context $ctx) {
$callbackQuery = $ctx->getCallbackQuery();
if ($callbackQuery->getData() === '1') {
$ctx->sendInvoice('1 Pepperoni Pizza', $_ENV['PROVIDER_TOKEN']);
}
$ctx->answerCallbackQuery();
});
For further info see Update object and Telegram Api methods.
After having defined the listeners just run your bot:
$bot->run();
If everything is ok you should see such a Zanzara is listening...
message.
Listener methods allow you to listen for an update based on its type, for example to reply to the the /start
you
do:
<?php
$bot = new Zanzara($_ENV['BOT_TOKEN']);
$bot->onCommand('start', function (Context $ctx) {
});
If you prefer, you may define callbacks as [class, method]
and Zanzara takes care of
instantiating the class and calling the method:
<?php
class MyCommandsHandler {
public function start(Context $ctx) {
$ctx->sendMessage('Hi');
}
}
$bot = new Zanzara($_ENV['BOT_TOKEN']);
$bot->onCommand('start', [MyCommandsHandler::class, 'start']);
If none of your listener matches the message sent by the user you can specify a fallback listener to be called instead:
<?php
$bot->fallback(function(Context $ctx) {
$ctx->sendMessage('Available commands are /start, /join, /help');
});
Sometimes you may want to listen for updates based on parts of the text and get the variable part as parameter, for example:
<?php
$bot->onText('Hi {name}', function (Context $ctx, $name) {
echo $name;
});
Here the listener methods for Telegram updates based on the type:
Method | Parameters | Description |
---|---|---|
onCommand |
$command : string$callback : callable |
Listen for the specified command |
onText |
$text : string$callback : callable |
Listen for a message with the specified text |
onMessage |
$callback : callable |
Listen for a generic message |
onReplyToMessage |
$callback : callable |
Listen for a message that is a reply of another message |
onEditedMessage |
$callback : callable |
Listen for an edited message |
onCbQueryText |
$text : string$callback : callable |
Listen for a callback query with the specified message text |
onCbQueryData |
$data : array$callback : callable |
Listen for a callback query with the specified callback data |
onCbQuery |
$callback : callable |
Listen for a generic callback query |
onShippingQuery |
$callback : callable |
Listener for a shipping query |
onPreCheckoutQuery |
$callback : callable |
Listen for a pre checkout query |
onSuccessfulPayment |
$callback : callable |
Listen for a successful payment |
onPassportData |
$callback : callable |
Listen for a passport data message |
onInlineQuery |
$callback : callable |
Listen for an inline query |
onChosenInlineResult |
$callback : callable |
Listen for a chosen inline result |
onChannelPost |
$callback : callable |
Listen for a channel post |
onEditedChannelPost |
$callback : callable |
Listen for an edited channel post |
onPoll |
$callback : callable |
Listen for a poll |
onPollAnswer |
$callback : callable |
Listen for a poll answer |
onChatJoinRequest |
$callback : callable |
Listen for a chat join request |
onUpdate |
$callback : callable |
Listen for a generic update |
Methods that take just a callable as parameter can be called more than once and every callback
will be executed.
Moreover, listener methods are not exclusive, so for example:
<?php
$bot = new Zanzara($_ENV['BOT_TOKEN']);
$bot->onCommand("start", function (Context $ctx) {
});
$bot->onUpdate(function (Context $ctx) {
});
$bot->run();
In this case both onCommand
and onUpdate
callbacks will be executed.
You access the Update object with $ctx->getUpdate()
. To make your code less cumbersome you can use the following
Context
's shortcut methods:
Method | Return type |
---|---|
getUpdateId | int |
getMessage | Message |
getEditedMessage | EditedMessage |
getChannelPost | ChannelPost |
getEditedChannelPost | EditedChannelPost |
getInlineQuery | InlineQuery |
getChosenInlineResult | ChosenInlineResult |
getCallbackQuery | CallbackQuery |
getShippingQuery | ShippingQuery |
getPreCheckoutQuery | PreCheckoutQuery |
getPoll | Poll |
getPollAnswer | PollAnswer |
getEffectiveUser | User |
getEffectiveChat | Chat |
Note:
$ctx->getEffectiveChat()
and$ctx->getEffectiveUser()
allow to get user info regardless of the update type. For example if the Update is aMessage
the getEffectiveUser() method will return the same value of$ctx->getMessage()->getFrom()
. If, instead, the Update is aCallbackQuery
the getEffectiveUser() method will return the same value of$ctx->getCallbackQuery()->getFrom()
.
All Update objects contain PHPDoc with the same info you find on the official Telegram Bot Api, so you can avoid to jump between code and website any time you need info about the api.
You interact with Telegram Api either through the Context
object or the Telegram
object provided by
$bot->getTelegram()
.
Since Zanzara is based on ReactPHP the http requests are made with an asynchronous http client.
Each method returns a PromiseInterface
. On success the promise returns the object declared as return type
of the method, an TelegramException
otherwise. Here an example with sendMessage()
:
<?php
$bot = new Zanzara($_ENV['BOT_TOKEN']);
$bot->onCommand('start', function (Context $ctx) {
// doc says: "Use this method to send text messages. On success, the sent @see Message is returned."
$ctx->sendMessage('Hello')->then(
function (Message $message) {
// success
},
function (TelegramException $e) {
echo $e->getErrorCode();
echo $e->getDescription();
}
);
});
As you have seen we didn't specify a chat_id
when calling $ctx->sendMessage('Hello')
. That's because
by default each method that requires a chat_id takes it from the Context's update. If you really want to send a message
to a different chat_id just specify it in the $opt
array param:
<?php
$bot = new Zanzara($_ENV['BOT_TOKEN']);
$bot->onCommand('start', function (Context $ctx) {
$chatId = // ... read it from wherever
$ctx->sendMessage('Hello', ['chat_id' => $chatId]);
});
Again, each method takes the required parameters followed by a param array $opt
which allows you to specify
optional parameters. Here an example:
<?php
$bot = new Zanzara($_ENV['BOT_TOKEN']);
$bot->onCommand('start', function (Context $ctx) {
$ctx->sendMessage('Hello', ['reply_markup' => ['force_reply' => true]]);
});
With Zanzara you can specify a generic parse_mode
that applies to all Telegram Api methods:
<?php
$config = new Config();
$config->setParseMode(Config::PARSE_MODE_HTML);
$bot = new Zanzara($_ENV['BOT_TOKEN'], $config);
Some Telegram Api methods allow you to work with files. For example to send a photo
you do:
<?php
$bot = new Zanzara($_ENV['BOT_TOKEN']);
$bot->onCommand("photo", function (Context $ctx) {
$ctx->sendPhoto(new InputFile("file/photo.jpeg"));
});
$bot->run();
By default the file reading operation is synchronous
. This means that the loop is blocked until the whole file
is read.
If you want it to be asynchronous you can switch to ReactPHP FileSystem:
<?php
$config = new Config();
$config->useReactFileSystem(true);
$bot = new Zanzara($_ENV['BOT_TOKEN'], $config);
$bot->onCommand("photo", function (Context $ctx) {
$ctx->sendPhoto(new InputFile("file/photo.jpeg"));
});
$bot->run();
Note: react/filesystem dependency is not present by default, install it through
composer require react/filesystem
.
This way has only one drawback: currently it doesn't work
on Windows machines, just on unix ones.
We hope that the ReactPHP team stabilizes the library as soon as possible adding support for Windows, but if this isn't
a problem for you, feel free to use it.
If your request takes too long you can specify a bigger timeout (default is 60 seconds):
<?php
$bot = new Zanzara($_ENV['BOT_TOKEN']);
$bot->onCommand('start', function (Context $ctx) {
$ctx->sendMessage('Hello', ['request_timeout' => 120]);
});
Middleware is a core functionality for any application, it allows to perform actions before and after the request
is processed. With Zanzara middleware can be implemented as callable
:
<?php
$bot = new Zanzara($_ENV['BOT_TOKEN']);
$m = function(Context $ctx, $next) {
// do something before
$next($ctx);
// do something after
};
$bot->onCommand("start", function (Context $ctx) {
$ctx->sendMessage('Hello');
})->middleware($m);
$bot->run();
If you prefer, you may declare a middleware as array of [class, method]
and Zanzara will take care of instantiating
the class and invoking the method:
<?php
class AuthMiddleware
{
public function processUpdate(Context $ctx, $next)
{
// ... do something before
$next($ctx);
// ... do something after
}
}
$bot = new Zanzara($_ENV['BOT_TOKEN']);
$bot->onCommand('start', function (Context $ctx) {
$ctx->reply('Hello');
})->middleware([AuthMiddleware::class, "processUpdate"]);
$bot->run();
In the above examples middleware are specific for a listener callback. You can make a middleware generic for every
callback calling the middleware()
method on Zanzara
class:
<?php
$bot = new Zanzara($_ENV['BOT_TOKEN']);
$m = function(Context $ctx, $next) {
// do something before
$next($ctx);
// do something after
};
$bot->middleware($m);
Use get($key)
and set($key, $value)
methods of Context to share data between middleware.
Sometimes you need to send a series of chained messages to a user and save his answers, actually a conversation
.
In this example we ask the user his name and age to, hypothetically, save them on MySql:
<?php
$bot = new Zanzara($_ENV['BOT_TOKEN']);
$bot->onCommand("start", function (Context $ctx) {
$ctx->sendMessage("Hi, what's your name?");
$ctx->nextStep("checkName");
});
function checkName(Context $ctx)
{
$name = $ctx->getMessage()->getText();
$ctx->setUserDataItem('name', $name);
$ctx->sendMessage("Hi $name, what is your age?");
$ctx->nextStep("checkAge");
}
function checkAge(Context $ctx)
{
$age = $ctx->getMessage()->getText();
if (ctype_digit($age)) {
$ctx->getUserDataItem('name')->then(function ($name) use ($ctx) {
// ... save user data on MySql
$ctx->sendMessage("Ok $name perfect, bye");
$ctx->endConversation(); // clean the state for this conversation
});
} else {
$ctx->sendMessage("Must be a number, retry");
}
}
$bot->run();
As you've seen, you use the nextStep()
method to declare the next function to be executed when the user will send a new
message and endConversation()
when your conversation is over.
The handler can also be provided as array of [class, method]
and Zanzara will take care of instantiating the class
and invoking the method:
<?php
$bot = new Zanzara($_ENV['BOT_TOKEN']);
$bot->onCommand("start", function (Context $ctx) {
$ctx->sendMessage("Hi, what's your name?");
$ctx->nextStep([MyConversationHandler::class, "checkName"]);
});
class MyConversationHandler {
function checkName(Context $ctx)
{
$name = $ctx->getMessage()->getText();
$ctx->setUserDataItem('name', $name);
$ctx->sendMessage("Hi $name, what is your age?");
$ctx->nextStep("checkAge");
}
}
$bot->run();
By default if a listener is found the conversation is terminated and the listener callback is executed. So, for example
if right in the middle of a conversation the user replies with the /start
command the conversation is terminated,
the next step function won't be executed and the /start
command's callback will be executed instead. To change
this behaviour set $skipListeners
to true:
<?php
$bot = new Zanzara($_ENV['BOT_TOKEN']);
$bot->onCommand("start", function (Context $ctx) {
$ctx->sendMessage("Hi, what's your name?");
$ctx->nextStep("checkName", true); // $skipListeners is set to true
});
function checkName(Context $ctx)
{
$name = $ctx->getMessage()->getText();
$ctx->setUserDataItem('name', $name);
$ctx->sendMessage("Hi $name, what is your age?");
$ctx->nextStep("checkAge");
}
$bot->run();
Sometimes you need to persist data between requests, we provide some methods to do that:
Note: this feature doesn't require a database.
Method | Parameters | Description |
---|---|---|
setChatDataItem |
$key : string$data : any$ttl
|
Sets an item for the chat-related data |
getChatDataItem |
$key : string |
Gets an item of the chat-related data |
deleteChatDataItem |
$key : string |
Deletes an item from the chat-related data |
setUserDataItem |
$key : string$data : any$ttl
|
Sets an item for the user-related data |
getUserDataItem |
$key : string |
Gets an item of the user-related data |
deleteUserDataItem |
$key : string |
Deletes an item from the user-related data |
setGlobalDataItem |
$key : string$data : any$ttl
|
Sets an item for the global data |
getGlobalDataItem |
$key : string |
Gets an item of the global data |
deleteGlobalDataItem |
$key : string |
Deletes an item from the global data |
wipeCache |
Deletes all cache data |
You can save whatever
you want in the cache: strings, arrays, objects, etc.
All these methods return a ReactPHP promise
, for example to retrieve an item from the cache you do:
$ctx->getUserDataItem('key')->then(function ($value) {
});
By default to persist these data we use a in-memory array
cache
implementation with a cache timeout of 180 seconds.
You can change the cache implementation (redis, filesystem, etc.) and the default timeout just by specifying them in
Zanzara Config
:
<?php
$config = new Config();
$cache = // my cache
$config->setCache($cache);
$config->setCacheTtl(240);
$bot = new Zanzara($_ENV['BOT_TOKEN'], $config);
$bot->run();
Telegram doesn't provide a way to send bulk notifications and if you try to send too many messages in a short amount
of time your requests could be rejected with a 429 error code. As
Telegram suggests, you should spread messages over a longer
interval. Zanzara
takes care of that, just call the sendBulkMessage()
method on the Context object:
<?php
$bot = new Zanzara($_ENV['BOT_TOKEN']);
$bot->onCommand("start", function (Context $ctx) {
$chatIds = []; // ... read users from database
$ctx->sendBulkMessage($chatIds, 'A new notification for you', ['parse_mode' => 'HTML']);
});
$bot->run();
Under the hood Zanzara sends the messages with an interval of two seconds
between them. You can configure the interval
with Config
class:
<?php
$config = new Config();
$config->setBulkMessageInterval(3.5);
$bot = new Zanzara($_ENV['BOT_TOKEN'], $config);
On errors Zanzara
logs them to STDERR
and to your log files (if a logger is provided). You can specify
a PSR-3
Logger implementation as follows:
<?php
$logger = // your logger.
$config = new Config();
$config->setLogger($logger);
$bot = new Zanzara($_ENV['BOT_TOKEN'], $config);
$bot->run();
If you want to perform further operations when errors happen, define a function that handles them:
<?php
$bot = new Zanzara($_ENV['BOT_TOKEN'], $config);
$bot->onException(function(Context $ctx, $exception) {
});
$bot->run();
By default Zanzara starts in polling
mode. It is the best choice for most Telegram bots since it does not require
a web server with https enabled.
If you want to switch to webhook
mode you need to set up an http server. ReactPHP comes with a built-in
http server. If you would like to use it:
<?php
$config = new Config();
$config->setUpdateMode(Config::REACTPHP_WEBHOOK_MODE);
$config->setServerUri(8080);
$bot = new Zanzara($_ENV['BOT_TOKEN'], $config);
$bot->run();
This way you have a http server listening for Telegram updates on localhost:8080
. Telegram requires your webhook
to be exposed under https
protocol. To try webhook mode locally you can use something like
ngrok in order to expose your local webserver to the internet. For production
setup we
suggest you to follow ReactPHP and Telegram
guides.
Before you actually start to receive updates you need to set your bot's webhook.
To use Zanzara with other http server, such as Apache or NGINX:
<?php
$config = new Config();
$config->setUpdateMode(Config::WEBHOOK_MODE);
$bot = new Zanzara($_ENV['BOT_TOKEN'], $config);
$bot->run();
Again, for production
setup we suggest you to follow Telegram guide.
Before you actually start to receive updates you need to set your bot's webhook.
Note: using this mode you don't have features like Conversations and Session working out of the box, since by default they are based on in-memory cache systems. Anyway, you can have them working just by relying on other cache implementations..
We prepared a snippet to set the webhook. Assuming that you placed your hook.php
script in the root of your
webserver:
<?php
use Zanzara\Zanzara;
require __DIR__ . '/vendor/autoload.php';
$bot = new Zanzara($_ENV['BOT_TOKEN']);
$telegram = $bot->getTelegram();
$telegram->setWebhook('https://mydomain.com/hook.php')->then(
function ($true) {
echo 'Webhook set successfully';
}
);
$bot->getLoop()->run();
As suggested by Telegram to make sure your webhook can be called only by Telegram servers, you can include your bot's token in the webhook url:
$telegram->setWebhook('https://mydomain.com/hook.php/<token>')
Zanzara will take care of the token check, just enable it:
<?php
$config = new Config();
$config->setUpdateMode(Config::WEBHOOK_MODE); // or Config::REACTPHP_WEBHOOK_MODE
$config->enableWebhookTokenCheck(true);
$bot = new Zanzara($_ENV['BOT_TOKEN']);
$bot->run();
Starting from Telegram Bot Api 5.0 you can use a local Api server. Follow Telegram
guide to configure it. Then, specify your server's
url through the Config
object:
<?php
use Zanzara\Context;
use Zanzara\Config;
use Zanzara\Zanzara;
require __DIR__ . '/vendor/autoload.php';
$config = new Config();
$config->setApiTelegramUrl('https://my-local-server.com');
$bot = new Zanzara("YOUR-BOT-TOKEN", $config);
$bot->onCommand('start', function (Context $ctx) {
// ...
});
$bot->run();
If you are working behind a proxy you can configure it through the Config object:
<?php
use Zanzara\Config;
use Zanzara\Context;
use Zanzara\Zanzara;
require __DIR__ . '/vendor/autoload.php';
$config = new Config();
$config->setProxyUrl('http://127.0.0.1:8080');
$bot = new Zanzara("YOUR-BOT-TOKEN", $config);
$bot->onUpdate(function (Context $ctx) {
// ...
});
$bot->run();
You can also change the DNS address:
<?php
use Zanzara\Config;
use Zanzara\Context;
use Zanzara\Zanzara;
require __DIR__ . '/vendor/autoload.php';
$config = new Config();
$config->setConnectorOptions(['dns' => '8.8.8.8']);
$bot = new Zanzara("YOUR-BOT-TOKEN", $config);
$bot->onUpdate(function (Context $ctx) {
// ...
});
$bot->run();
<?php
use Zanzara\Context;
use Zanzara\Zanzara;
require __DIR__ . '/../vendor/autoload.php';
$bot = new Zanzara("YOUR-BOT-TOKEN");
$bot->onCommand('start', function (Context $ctx) {
$firstName = $ctx->getEffectiveUser()->getFirstName();
$ctx->sendMessage("Hi $firstName, I'm replying to /start command");
});
$bot->run();
<?php
use Zanzara\Context;
use Zanzara\Zanzara;
require __DIR__ . '/../vendor/autoload.php';
$bot = new Zanzara("YOUR-BOT-TOKEN");
$bot->onCommand('start', function (Context $ctx) {
$kb = ['reply_markup' =>
['inline_keyboard' => [[
['callback_data' => 'one', 'text' => 'Button One'],
['callback_data' => 'two', 'text' => 'Button Two']
]], 'resize_keyboard' => true]
];
$ctx->sendMessage("I'm replying to /start command with an inline keyboard", $kb);
});
// reply to a generic callback query
$bot->onCbQuery(function (Context $ctx) {
$ctx->sendMessage("You clicked 'Button one' or 'Button two'");
$ctx->answerCallbackQuery();
});
// reply only to callback queries that have 'one' as 'callback_data'
$bot->onCbQueryData(['one'], function (Context $ctx) {
$ctx->sendMessage("You clicked 'Button one'");
$ctx->answerCallbackQuery();
});
// reply only to callback queries that have 'two' as 'callback_data'
$bot->onCbQueryData(['two'], function (Context $ctx) {
$ctx->sendMessage("You clicked 'Button two'");
$ctx->answerCallbackQuery();
});
$bot->run();
<?php
use Zanzara\Context;
use Zanzara\Zanzara;
require __DIR__ . '/../vendor/autoload.php';
$bot = new Zanzara("YOUR-BOT-TOKEN");
$bot->onCommand('start', function (Context $ctx) {
$kb = ['reply_markup' =>
['keyboard' => [[
['text' => 'Button One'],
['text' => 'Button Two']
]], 'resize_keyboard' => true]
];
$ctx->sendMessage("I'm replying to /start command with a keyboard", $kb);
});
$bot->onText('Button One', function (Context $ctx) {
$ctx->sendMessage("You clicked 'Button one'");
});
$bot->onText('Button Two', function (Context $ctx) {
$ctx->sendMessage("You clicked 'Button two'");
});
$bot->run();
<?php
use Zanzara\Context;
use Zanzara\Zanzara;
require __DIR__ . '/../vendor/autoload.php';
$bot = new Zanzara("YOUR-BOT-TOKEN");
$bot->onCommand('start', function (Context $ctx) {
$ctx->nextStep('askName');
$ctx->sendMessage("What's your name?");
});
function askName(Context $ctx)
{
$name = $ctx->getMessage()->getText();
$ctx->setUserDataItem('name', $name); // save name in cache
$ctx->nextStep('askAge');
$ctx->sendMessage("Hi $name, what a wonderful name! What's your age?");
}
function askAge(Context $ctx)
{
// retrieve name from cache
$ctx->getUserDataItem('name')->then(function ($name) use ($ctx) {
$age = $ctx->getMessage()->getText();
$ctx->sendMessage("$age ?! Dear $name, you are too old for me! Bye bye!");
$ctx->endConversation();
});
}
$bot->run();
<?php
use Zanzara\Context;
use Zanzara\Zanzara;
require __DIR__ . '/../vendor/autoload.php';
$bot = new Zanzara("YOUR-BOT-TOKEN");
$bot->onCommand('start', function (Context $ctx) {
$ctx->nextStep('askName');
$ctx->sendMessage("What's your name?");
});
function askName(Context $ctx)
{
$name = $ctx->getMessage()->getText();
$ctx->nextStep('askAge');
$ctx->sendMessage("Hi $name, what a wonderful name! What's your age?");
}
function askAge(Context $ctx)
{
$age = $ctx->getMessage()->getText();
$ctx->sendMessage("$age ?! You are too old for me! Bye bye!");
$ctx->endConversation();
}
$bot->run();
- @stargazers_bot Bot that notifies you when someone stars a github project. Source code