The Ultimate BotMan Chatbot Debugging Guide
#chatbotsStarting with BotMan to create chatbots is easy, but dealing with bugs is not. Since there are many external services like Facebook, Telegram or Slack involved, lots of things can and will go wrong. I have run into so many of these bugs and don't want you to struggle with them as I did. So here is my ultimate debugging guide.
My Chatbot Does Not Respond, What Is Wrong?
This the question we see the most on the BotMan repository issues and the Slack channel. It is also one of the most complicated ones because there is so much that could cause this behavior. Let's try to deal with that.
1. Check The Driver Setup
Make sure that your driver
is correctly set up with BotMan. The driver is a messenger like Facebook or Telegram. Each one has its own section in the documentation.
2. Try The Given Examples
To make sure it is not your code that is triggering the problem, it is best to try the given BotMan Studio examples. With typing hi
you should get a simple text reply back and with start conversation
a test conversation should be triggered with a question and buttons.
Of course, this only works if you are using BotMan Studio. For other applications try to make the code as simple as possible.
If the bot does still not reply, the problem has to do with your local setup or your used messenger.
3. Check Your Environment
To use BotMan Studio or BotMan within another PHP project, you need a working environment for PHP applications. BotMan does not care what you use locally, or on your server. Many solutions work with PHP applications and Laravel. This is also something I can't help you with. You need to figure out what you use and that the setup works.
Only good to mention is that using ngrok helps a lot when working locally with BotMan. It helps you to create a secured public URL to your BotMan application that you can use to connect it to a messenger. If you use Laravel Valet, ngrok is already integrated.
4. Look Into Your Log File
This is also something, many people forget. If an error happens inside your application, it will be logged. When you use BotMan Studio, the log file can be found under storage/logs/laravel.log
. The error message will help you to find the problem.
If you don't see an error there, make sure your logging system is working. You could force an error if you remove a ;
on a code line for example. Other frameworks also log their errors, so make sure to look that place up.
Mostly, at this point, we know at least something about the problem and can ask about it in the BotMan Slack channel or on GitHub.
5. Further Debugging
From here, your problem might be an ugly edge case. For example, your Facebook application could be blocked, or Telegram has a problem on their side without you knowing it. Those things are hard to find, but I still got a few tips.
Incoming Requests
Here it is a good idea to check if you receive HTTP requests from the used driver. You can see that in the ngrok interface. When you start ngrok, you will get a link to this local interface.
Additionally, I like to log the incoming requests. Inside the BotManController
, I'm using the info
method to log every request to my log file.
public function handle(Request $request)
{
info('incoming', request()->all()); // this line was added
$botman = app('botman');
$botman->listen();
}
}
This way I can see if I receive any requests. If you don't, then the problem is not inside your BotMan project. If you don't use BotMan Studio or Laravel, you need to look at how to write to your log file.
BotMan Listen
To make your bot replies to an incoming message, it is essential that you call the $botman->listen();
method. Normally, it is already placed inside your BotManController
, but I saw some issues where people deleted it accidentally.
Driver Class - Matching request
Every driver has one or more driver classes, like this from the Facebook Driver . These classes determine if an incoming message is one from the correct driver. This is the method to check if the incoming message is from Facebook Messenger.
public function matchesRequest()
{
$validSignature = empty($this->config->get('app_secret')) || $this->validateSignature();
$messages = Collection::make($this->event->get('messaging'))->filter(function ($msg) {
return (isset($msg['message']['text']) || isset($msg['postback']['payload'])) && ! isset($msg['message']['is_echo']);
});
return ! $messages->isEmpty() && $validSignature;
}
This is also an excellent place to debug if an incoming request gets matched or not.
Driver Class - Look for errors from the messenger service
If it gets matched, it could also be that the driver service (like Facebook) has a problem with your reply message. This will not be the case when you use simple text responses but could be a problem when you use more complex ones like templates.
BotMan provides, for example, several Facebook Templates you can use to create lists, cards or galleries. If you have a mistake in those structures, your bot will not
respond and you won't
see any errors. This is because those errors are not handled within BotMan
and it gets hard to debug.
Best way to check that is by logging the response of the used service/messenger. This can be done with the BotMan driver class. Here is an example of how that looks like for the Facebook driver.
public function sendPayload($payload)
{
$response = $this->http->post($this->facebookProfileEndpoint.'me/messages', [], $payload);
info('FB response' . $response->getContent()); // we added this line
$this->throwExceptionIfResponseNotOk($response);
return $response;
}
The info
method is a Laravel helper that you can use inside BotMan Studio. If you are not using BotMan Studio, you need to take care of using a Logger yourself. Import here is that you log the content of the response. If the messenger service has a problem with the reply of your bot, you will see the error message in your logs now.
Facebook Webhook Setup
If you have problems setting up the webhook for Facebook Messenger, check out my article on debugging this problem.
Facebook Standby Messages
Sometimes, messages from Facebook come in, but BotMan can't handle them because instead of the messaging
array, the message is inside a standby
array.
For bots using the handover protocol, this happens when a message has been sent to your page, but your application is not the current thread owner.
Code Update/Changes Are Not Shown
When working with conversation classes, you will probably run into situations where your changes in the code will not be visible in the chatbot output. This is due to the cached conversations. Active conversations are cached so that BotMan knows what to ask next. In these cases, you need to clear the cache. In BotMan Studio this can be done with php artisan cache:clear
. But be careful, since this clears the whole Laravel Cache.
The Loop Problem
Some messengers like Facebook will resend messages to your application after receiving a 500 response from you. It works like this. You have an error in your code, and your application sends back a 500 HTTP status code to Facebook. Facebook will then try again and again and again and here you have your loop.
Best way to deal with this problem is:
- You see the loop
- You check your log file for error
- You uncomment the code with the error
- This will let your application send a 200 HTTP status code to Facebook
- Facebook will stop sending more messages
- Then you can fix the problem and use your code again.
This is important because Facebook will block your Facebook application for a particular time if they receive too many HTTP error responses.
Laravel Dump Server
Next, to using the ngrok interface and logging stuff, you can make use of Marcel's Laravel Dump Server. It's a service that you can start inside your terminal. While it is running, it will catch every dump command from the running application and show the output. Here is what it looks like:
And here is an example where I dump the incoming Telegram event from within the TelegramDriver.
public function matchesRequest()
{
dump($this->event); // this line was added for debugging
$noAttachments = $this->event->keys()->filter(function ($key) {
// ...
}
Since Laravel 5.7, this package is already integrated into the framework. But you can also install it via composer. Just follow the instructions on the repository site.
Final Thoughts
I hope this article could help you with your BotMan problems. I will try to update this guide from time to time with more useful tips. If you got one, talk to me, and I will add it as well. Let's make debugging chatbots a less stressful process for everyone :-)