TL;DR: I am going to tell my story about my first chat bot experience (This is not a coding post but rather an ongoing journey that I want to share).
As promised in the following post I am going to talk about the following topics:
Few months ago my client Cnature asked me to start a new project.
The idea was to connect the bot to few of Cnature’s services in order to identify flowers’ photos instantly.
In other words, it worked like this:
Basic Implementation Details 🔨
You can skip directly to Admin Panel & Chat Bots if you have already implemented a Messenger chat bot before 👍
Messenger’s API documentation is relatively good. I almost haven’t had any problems consuming its API and it is being updated constantly.
The bot was implemented using PHP 7.1, Silex (just because it’s convenient, you don’t really need it), an unofficial Messenger SDK, MySQL and working on Azure - which means, Windows 🙄.
Subscribing a page:
$ curl -X POST "https://graph.facebook.com/v2.9/me/subscribed_apps?access_token=TOKEN"
Keep in mind that when you subscribe the page to the webhook, you already have to have a running server which will accept calls from Facebook.
This leads me to the next topic ➡️
Messenger Development Using localhost
Keeping it short, I am using PHP’s local webserver using
php -S localhost:9991 -t web web/index. Then I installed ngrok which acts as a proxy and allows access from the world to my localhost while also supporting HTTPS, as required by Facebook if I remember correctly. Then I simply put ngrok’s HTTPS URL in the right box:
🔎 It might be annoying to set the Webhook every time. It seems like if you don’t exit ngrok, it will keep the URL for you. It might not be good security wise, but if you don’t mind that while developing, you can just keep ngrok open and it will save you time editing the Webhook’s URL every time you start working.
Finally, getting into the more interesting part 🤗
Admin Panel & Chat Bots 👩💻
While working on Flowerzbot, I figured that some requirements might bring some extra effort, which will require me to deploy only in order to change configuration.
For example, we wanted to receive feedbacks from users via Messenger. The flow works like this:
- The user selects the Contact Us option from the menu.
- Then the bot tells the user to write a feedback or add a screenshot.
- Once the user finishes, the bot will send a message to whomever we define as a “feedback administrator”.
At the beginning we thought:
ok, lets check the Messenger user ID - aka senderId - of each one of our own Messenger users and use it in the configuration file, but quickly we figured that this will be quite disturbing because different Facebook Apps have different senderIds.
Then, I decided to create an admin panel through the chatbot (or sudo mode for the Linux folks).
Each one of us got a token, which is defined within the bot’s configuration file. With this token, we can ask the bot to do different things, for example, with the token we can register to receive feedback events (IRC anyone?).
This idea started because of the feedback issue above, but grew up nicely and basically ended up as an admin panel (or “back office”) within a chatbot. This is what we have at the moment:
Our implementation is simple, the admin has to use the token together with the command and value (if needed), and the bot executes and replies.
The bot supports fetching and changing information:
Yes, we could have used other implementations 👷. For example, differentiate between modes where the admin sends the token to the bot and then just interact with the bot as an admin and can only execute admin commands. When the admin finishes they can basically exit this mode either by having a magic word, e.g exit or by having a limited time so that that admin will be logged out after X minutes.
Chat bots and Notifications 🆘
Flowerzbot doesn’t only support the ability to send feedbacks directly to our Facebook accounts.
We have also implemented more features, such as health check status which sends the current status of our services:
And in case the health check fails, the health check will trigger a message to all of the registered admins (not all admins have to register, but you know, better they do) and it will write down what happened:
And last but not least, we also added the ability to receive timing updates from our services.
If you were wondering what
getNotifyWhenSlowerThen means, then you are in the right place. We figured that some of our services might be slow sometimes and wanted to receive updates quickly, having said that, we didn’t want to implement anything new and waste time ⏰ and money 💰 so we just took our health check timings, parsed it and in case it is greater than whatever is defined via
setNotifyWhenSlowerThen then the bot will notify all the admins about the status of all the services.
as you can see 👆, MessengerAPI was a bit slow on Sunday at 06:23PM 🙃.
Chat bots and UX flows, Feature Flags and an idea to do A\B testing 🔛
I decided to split the flows and kept the old one as is while creating another flow. That way I had the ability to control which flow is being used to the extent that I could choose if all users will have it or only part of them.
Basically, I have implemented the Feature Flag mechanism into Flowerzbot.
I also had to create another bot for Cnature with the first flow. I basically duplicated the code and changed the flowVersion by using
setFlowVersionForEveryone and that’s it, it worked!
After doing that, I figured that in the future it will be very easy to come up with an A\B testing solution as I can just control the amount of users getting flow A, flow B ... flow N.
Bugs, Tests & Unexpected Behavior 😑
Well, as always I also encountered some issues, 2 main Issues actually:
- When there’s an error, Messenger will keep sending you the same message over and over again. It’s like as if it didn’t receive the right status code/response and therefore is trying to keep on doing the last action. This is not completely clear sometimes.
- Messenger is not always as fast as you would expect. Especially when testing the bot. What I recommend is to save the responses Messenger provides and try to run your code locally, kind of the same idea of doing a unit test or any of the equivalent just sometimes there’s no time to test everything (sounds familiar?) and therefore, the fastest is to work with mocked responses IMO.
Currently I am working on another Messenger chat bot 🤷♂️ that helps you find dishes of restaurants by their calories and nutrition values 🥑. At the moment it is only available in Hebrew.