 Introduction about me my name is Marcel Pozziot. The name is pretty hard to pronounce. I'm not French even though it might look like it I'm managing partner and developer at a company called Beyond Code. I started it in December last year So it's very new And you can follow me on Twitter if you want. That's my Twitter handle Where I'll be talking about PHP development chatbots All sort of things or a ramble about gaming um When I'm not working at my company, which as I started in December has become quite rare I actually enjoy doing a lot of open-source work It's not completely true I also enjoy spending time with my family and I thought about Adding a slide here because I just started playing pubg. I don't know if anyone knows this game. I Just wanted to tell this It's awesome because I started realizing I'm just too old for a Call of Duty kind of games and all these 17 years will just Defeat me there. So But nevertheless, I do open-source quite a lot because I just love giving back to the community We do a lot of use a lot of open-source tools in our daily life as developers I have somewhat around 40 or 50 open-source PHP packages around with close to a million downloads and So just want to encourage you if you want to get started with open-source. Just do it get started with it There is No kind of losers in there just publish your code and you will definitely learn from other people And another quite popular thing is the Laravel test tools Chrome extension Just want to quickly talk about it's a Chrome extension that lets you record the actions that you perform on your website and it generates a Laravel test code out of it. So when you click on it, it generates the code for you I know it's not TDD, but it uses 15,000 people use it weekly. So it at least helps to create more tests for software, which is great and It's also available for codeception All right chatbots, they're not all as evil as the T1000 here plus he wasn't that chatty, but So let's take a look at the definition of a chatbot according to Wikipedia So according to Wikipedia, it is a application that is conducted by a computer program and it either uses some audio information for input or textual information and on the Wikipedia side it also says that This software passes the Turing test. So those of you who don't know what it is. It's a test to For a software to behave like a human being But my definition of it is It's just an interface that you can use to access your application. So it's nothing more. You can just think of it as Somebody talks to Alexa and this triggers a specific part of the application or someone in uses Facebook or Telegram or Slack. So it's just another interface for you to use your application and To give you some examples of what bots are like Because what I what I experienced is a lot of times people think that chatbots should be the super intelligent artificial intelligence machines that you can ask any kind of question and they understand what you mean And I think we're not there yet So a lot of use cases that you probably knew in your day-to-day life is Slack So this for example is a slackbot that I developed For a company and allows me to use Larevel Forge For those of you who don't know what it is. It is a server management system And it allows me to create a new site on one of my servers So in this case it creates a test site using the webshop Larevel repository. I can just Say that in Slack The chatbot will pick it up and create a new database for me create the server for me create the site clone the repository Install composite dependencies everything and it just once it's ready. It will just give me the URL and I can browse the website and So this is cool because it saves me a few minutes of my time because With this this is just one minute if you know the right syntax for the bot Which would otherwise take around 10 minutes But the other thing is that it informs everyone in my team who is also on the slack channel that I just did that and That I created this website. So it's also about sharing information This is also another bot that has some kind of more natural language approach to it Which pulls out the DNS information for a specific domain Then there's a huge market for brand marketing with chatbot. So this is an example from TechRange They have a chatbot on Facebook and when you talk to it It allows you to subscribe to specific RSS feeds So when you talk to it, it will say, okay, which of these topics Interest you and then you can subscribe to the most popular feeds on TechRange and every day at a specific time which you can also choose You will receive an overview of the I think it's the top 10 articles of that day And TechRange will send it to your Facebook Messenger inbox and I use this quite a lot because it's not as Spammy as newsletters, I think And as I'm using Facebook Messenger anyway, it just feels more natural to me It just added it this morning when I was visiting London yesterday for some quick sightseeing I saw that the travel for London, TFL, they have a travel bot on Facebook I just tried it real quick this morning. It allows you to view the The times when your buzz arrives and it allows you to check the status on some lines So the whole self-service Market is also very important for chatbots because it lets users interact with your application or your service on The messenger services that they already use And then chatbots are just fun. So this is just an example I built an Alexa skill that allows me to deploy to my websites This is my voice So this is what it sounds like Alexa Ask Laravel Forge to deploy botman.io Deploying botman.io ship it Well, this is not Extremely useful in daily life. I just build it because it's really fun to interact with Alexa and let it deploy my website Plus, I couldn't find the the updated chart of this, but the timing is just right. So starting in quarter one of 2015 the number of users and messaging apps increased compared to the number of users and social networking apps So there's a huge User base just waiting for chatbot applications to get on their messaging services Okay, so we talked about chatbots and they can be fun and Use for self service. So let's build our own chatbot week. We're developers. We can do this Okay This looks a bit weird on this resolution So when you start writing your own chatbot, there are a lot of services available that you can choose from there's Slack you can use nexmo for SMS Twilio for SMS Skype we chat Telegram you name it. So they all have The ability to add chatbots to it. So you first have to choose which Service you actually want to use And to show you how chatbots work in general, this is like a brief chart of it So you go for example, let's choose Facebook. You go to the Facebook developer side create an account and Then you can just use webhooks So when someone writes your Facebook application at Facebook will then send this data to the webhook you provided so this would be your bot application and There you have to validate the incoming data. So is this actually a command that my chatbot should listen to? You maybe need to check for existing conversations date. So if the user previously talked about Getting a bus and now he says something completely different. Is this still related to the previous conversation? and then you have to respond back to the messaging service and While this works pretty much this way for all of these services. It's very different in detail So for example Facebook sends JSON payload to the webhook With a very weird structure We chat for example sends XML a raw XML body And when you want to respond to these services you also for slack for example, it's enough to send just a return 200 Response with some JSON for Facebook. You need to make an API request for Skype you need to get an OOS token and send this back. So it's not easy to get Your chatbot once you've developed it and you chose Facebook for example, and then your client comes and says Okay, now we want to get it on slack, too. You have to do it all over again So that's what why I developed this Little library. It's called Batman and that's the cute-looking logo It's framework agnostic it you can pull it in in Elzend application symphony Laravel Or without any framework at all you can require to be our composer or It also comes with a few additional features using Laravel That's just because I like the framework Which is called Batman studio, but you don't have to use that you can just use it in your framework of choice and So this is one of the features that automatically come with the Laravel integration So it has a command that shows you the available drivers that you can can connect your chatbot to so on the previous chart with all these messenger services With Batman it allows you to abstract your chatbot logic, and then you can just say okay now I want to connect my chatbot to Amazon Alexa then you pull in the driver configure it and you're good to go and This is what the installation would look like on What man studio and if you would use it without a framework it's just a composer require and you have to do two additional steps and Every driver for example Facebook comes with a configuration. That's hopefully good documented Where you see what you need to do to get your driver up and running So this is really all you have to do if you want to add a new driver to your chatbot application So the fundamentals of a chatbot are it needs to hear the incoming message from a user It needs to process them and understand what the user was actually trying to tell you And then you need to respond to the message. So let's just look what this is like with Batman so This is the most basic example of using Batman. You just it has a hears method and there you just paste the keyword and you then have a closure as a second argument and So in this way you structure all the commands that you want to listen to Or if you don't want to use a closure, you can also use this class namespace class at method syntax and Once you've defined all the commands you call a listen method and this is What will be behind the waffle QRL? So since this presentation is actually running on top of Batman using a web driver. I can just try this out in the in the presentation here. So if I type keywords it replies hello, my friend and With this exact code if I just hook in the telegram driver, this is what it would look like and This is the Facebook implementation So it's all just connecting configuring tokens And it just works with the same code base And of course, you're not limited to just send one reply. So if I type tell me more I get two replies from my chatbot So since you are able to use multiple messaging services, you might want to Group the commands that your chatbot can listen to for multiple messaging services So for example, if you use next mode with SMS You might only want to listen to Specific commands that make sense for SMS and if you use Facebook Messenger or Slack You have different commands that you want to listen to so this group method with Batman allows you to do just that Let you say okay group all the commands For this driver Inside of this closure. So it allows you to structure your code Now hearing to just static keywords is fine but at the end of the day, we probably want to retrieve some input from our users and Extract parts of what the user said and use it in our application the easiest way to do this is with curly braces around a parameter and So in this case we have call me and then curly braces name and Then in the closure, we get the Batman instance and as a second parameter We get the name so what the user answered after call me. So I type call me Marcel We will call this method with a Batman instance and the name so then we can just reply hello, whatever was said Or this is also not limited to just one If we have I am name the adjectives Then these parameters will just add get added to the closure in the order that you specified them so I am Kind of the right These curly braces are really just forgetting everything if you want more control over what you actually want to listen to You can just use regular expressions. So everything that's in a regular expression matching group Like the zero to nine plus. Well, Jen just get passed to the closure To the variable. So if I type I am 32 years old, which I am Get got it. You're I just 32 and if I would type I Am 30 Years old Then we get another response. I have no idea what you're talking about because it will not jump into this closure You can also depending on what messaging services you use listen for incoming attachments So for example with Facebook or telegram or slack, you can just send images So there's a receives images method It gets the botman instance and then an array of images that the user sent to your chatbot and the same can be applied to videos or audio and Some services like Facebook and telegram at least also supports to send the current location So that you can listen for the location data from your users You just saw that when I typed I am 30 with just letters that You can also define a fallback method So this is the method that gets called when none of your here's commands match the Incoming information. So if I just type some random garbage, I will go into the fallback map If you want to store some user information, but man has a very simple user storage. It's underneath It's just a JSON file with the data in there So if you want to cash it you better be using database or Redis But it's it allows you to actually just store the information So this is what the code looked like in the I am Whatever age years old example we replied it and then I saved this in the user storage and this means that when another user on Slack for example talks to my chatbot then the user storage is automatically bound to the user that interacts with my chatbot. So it's not shared across users And to retrieve Items and keys out of storage. I can just call a get method and get the age back So if I now type hold MI It returns the value and Beside the user storage, there's also a channel storage. So this is useful for Messaging services that has that have the concept of channels or groups the most popular would be slack where you have different channels, but also for services like telegram where you have group chats Then you could use the channel storage to store information that is then scoped to this channel or to this group and If you use multiple Drivers or messaging services, you can also store information scoped to this specific driver Batman also has support for events. So for example on slack There's a team join event that you can listen for So every time someone joins your slack team, you will then get the event fired and you could add a Simple bot that will greet everyone that joins the team Facebook has for example events for message rats. So every time someone reads your messages You get an event and you can do whatever you want with it. You receive the payload from the messaging services and Another example would be terrogram. It has a left chat member event. So in this case We say goodbye to the user, but he already left the channel Anyway, it would work Okay, so up until now we just reply it's text but Again depending on the messaging service. You can also reply rich media like messages with attachments so To you do to do this you can just create a outgoing message class with some text and then you can say With attachment and then attach in this example an image with a URL So if a type give me images We get a reply with an attachment Same for videos again It depends a lot on which service you use if the service supports videos or images So this obviously wouldn't work with SMS Give me videos. I turned myself into a pickle Morty boom big reveal. I'm a pickle. What do you think about that? I turned myself into a pickle all right pick a Rick and If you want to make use of some Driver specifics you can also do that. So you're in this example Facebook has a Whole bunch of different templates that you can use So you can create a list template so the list template is part of the Facebook driver that you pull in and With this you can create a response, which is then a list with two elements one is botman documentation and this is all part of how Facebook deals with it with a subtitle and image and specific buttons and Then you can reply those templates. So this is what it would look like for Facebook Now if you would reply this template on some other messaging service, it wouldn't work because this then created just generates a very specific syntax that only Facebook understands or To give you another example, this is a button template also from Facebook where you can create a button template with Two buttons here. One is a post back. So when you click on it Your chatbot could listen to the value and the other is just a URL and This is what the button template will look like on Facebook messenger Okay, let's order some pizza. So And not really but our chatbot could probably now understand To order some pizza So the user could say something like I want a large cup of Chosa with extra cheese delivered to the brewery and It's super easy. We can just create a super funky regular expression and Then listen for it This would work, but it's probably not What we want to do because our chatbot users need to know that they have to write exactly this so The solution is just if you think of it in real life when you want to order a pizza you call the delivery service and You start a conversation. So he asks you what pizza do you want? Your answer then he asks where to deliver it to and then you give another answer and The whole conversation concept can also be applied to Batman So in this example, we hear for the trigger keyword, which is I want images Then we jump into this closure and there we are going to ask which images and We're going deeper in the rabbit hole. So another closure, which will receive the answer and the bot instance and There we are just getting the text from the answer and then use Lauren pixel to output the image give me images Now ask me which images and of course we want cats so we get cat images and The important thing is that once we are inside of this ask method and the bot Asked us the question even if we would reply to something that is another here's command The chatbot would just skip it because it knows. Okay. We are currently in this conversation now with the pizza Example This could get a bit ugly because we have multiple Questions nested so for this there's a Conversation class which on one hand allows you to reuse conversations throughout your chatbot application and It is also a lot better to structure the code So a conversation class is just a regular class that extends the base conversation class that comes with Batman It just has to implement one method which is the run method that gets called when the conversation gets started So if we stick to the pizza example, the first question that we're going to ask is what pizza size do you want? Then we get into the closure and we will save the answer as a Class property on this conversation class and then the next thing we would do is we will just call another method on the Conversation class. So we would call ask call ask topping We will ask what kind of topping do you want and then again, we will store the answer in the topping and the topping argument and Then we will ask for the address So this is in the ask address method and there we will just Dumb out all the information that we stored in the class properties and to trigger this Batman object has a start conversation method where you can just pass in an instance of the conversation class that you want to use I want pizza What pizza size do you want a large? What kind of topping? Let me just clear that Bellamy I Wanted to deliver it to Brewery and then we got all the information That we have and once again, we're just with the smaller Conversations that just have the ask method every answer that is given inside of this conversation is bound to The scope of this conversation class now This is quite good with the conversation, but now we allow every information from our users So someone cat could say I want a pizza. That's the size of a wagon wheel But maybe we don't have wagon wheel size pizza So what we can do then is we can also create question objects with buttons and These buttons can have a label So in this case we create the question object what pizza size do you want and we add two buttons One with the label super size and when we click on it We can retrieve the value which would be xxl and one button with the label large and the value l And I called this better pizza and This is what we'll look like so we have now have these buttons I want some hamburger on my pizza and We can get it delivered to the brewery so Maybe you noticed that there was still the input field and if you run this on Facebook Messenger people could still type whatever they want But you can check for that in the In the ask closure. So there you check. Okay, was this answer Really a button click and if it's not you could just repeat the question with some different text or something like that and This is what it would look like on telegram So you have these two buttons there and this is how Facebook renders it Okay, so another approach to Pizza ordering if we stick with it would be natural language processing Natural language processing means that we have a sentence like hey calendar schedule dinner with Nicole at 8 p.m Tomorrow we then send this sentence to a service and This service will return some structured information back to our application that we can then use so in this example We would get the results that the intent of this sentence is to create a meeting and This intent has a couple of entities So the name of this create meeting intent would be dinner with Nicole Invities would be an array of just Nicole and the time would be tomorrow at 8 p.m there are a couple of Services that are available for natural language processing There are also more than these three API is Now called dialogue flow Google acquired it. There's wit AI which is built into Facebook and There's Raza, which is my personal favorite because it's open source. It's Python and you can just run it on your local machine So you do not need to send every message that you receive to some Google service to to process it. So it just remains on your service and It this is a screenshot from dialogue flow So this is what it would look like if you set up the whole natural language processing So it works like this you give it a few sample sentences how users would interact To trigger the pizza intent in this example So people could say I'd like for cheese pizza or can you make me small? Agree to and deliver to whatever address and then you go into the sentence you mark for example the small the text Click on it and then you can say okay small is an entity of the type size and When this gets called I want it to be in a parameter that is called size and the same with type or address which is a Pre-configured entity from dialogue flow. So you do not have to Enter all the available addresses. So these services automatically detect. Okay. This is an address I am just I just know that it's an address or a country or a zip code things like that are built into these services so once you configured all these example utterances you can then use these natural language processing in your chatbot and With botman this is through done through some middleware system So we can create a dialogue flow middleware In this example with a dialogue flow token and then we say we want to listen for actions I will explain this in a bit and then we say okay every message that your chatbot received Will go through this middleware Because we need to send every incoming message to dialogue flow to determine is this actually in an intent that we want to listen to and Then in our here's method we can just say okay. We want to listen for order dot pizza And then we can tell the here's command. Okay, but only listen to it using this middleware So if someone just types order dot pizza, this will not work because the text order pizza would be sent to dialogue flow and not return the intent that we want to and Then we can access these parameters that were added from the middleware using the get extras method on the incoming message so I have rather NLU running locally so I can do something like I want a Large salami pizza with I don't know onions and Then this sentence will be sent to my local python Rather NLU service. I will get analyzed and I can get back. Okay. The type is pizza the size is large and the topping is onions or I could say something like I am hungry Give me a medium Margarita with extra cheese and then this also gets processed and these services are smart enough to to be These sentences that you send to them. They don't have to exactly match these sample sentences So if they just differ a bit, it will still pick up the the arguments from this sentence Another very useful feature of Batman is that you can originate messages. So When you think of slack, this would be just be a notification So you can notify someone on slack or Facebook or SMS with some text Which is nice, but the real benefit is that you can also originate conversations so for example, let's say there's a PHP conference in London and After the event we want to notify everyone on telegram or Facebook and send them a conversation where they can give feedback in Messenger so all you need to do is you have to get the the user ID first So the people need to interact with your chatbot in some sort of way But then you can just originate conversations and send them out Testing is also added in Batman. It's a feature that most of the available chatbot frameworks don't really care about because testing chatbots is quite hard and with Batman At least I tried to make it pretty simple. So This is just a PHP unit test and there we say, okay The bot receives the message test and then we assert that the reply is hello And it comes with a whole bunch of different method that you can use to receive tax and assert replies Assert that the reply is in an array That it's not a specific kind of reply that it's a question or some kind of Facebook template So there are a lot of more of these testing helper methods that you can use when Developing chatbots so that it really is possible to use TDD when developing a chatbot I talked just briefly about the middleware concept in Batman And I think it's one of the most powerful features of the library because it allows you to hook into the various Parts of the chatbot lifecycle. So this is what the the whole lifecycle of Batman looks like So when you call the listen method and someone sends your message Batman will get the incoming message from the driver that is matching this message And you can hook into this using the received middleware. So this is for example, what we do with dialogue flow We get the message send it to some third-party service add additional information to the message and then it goes into the next part Next we check is the user currently in a conversation and if That's true, then we can call a captured middleware So it's sort of like the received middleware, but only for Inside of conversations and after that the active conversation will be loaded If we're not in a conversation, we have the message matching So this is the actual regular expression matching is the text that we send The same text as the regular expression does it match and you can modify it too. So for example as we did with dialogue flow, we Not only check for the regular expression, but we also check if this is actually an intent from dialogue flow or if you have Messages on your chatbot that you only want to listen for when the an admin of the Facebook page sends it So maybe you have some admin commands to list users delete users things like that then You can write your own matching middleware to check for that and There's a herd middleware, which is basically the received middleware But it will only get called when the message was actually matching Then the closure or the class method will get called and You have a sending method which you can use that gets called before the message Payload will be sent to Facebook or Slack or telegram. So you could lock the outgoing data manipulate it do whatever you want with it and This is how you would apply it just a basic example a logger middleware It will log so we we say we want to apply this middleware to all Message that we send and to all the messages that we receive And batman ships with I think 10 drivers for all sorts of different messaging services But you can also create your own the documentation has a part of it Which describes how you can create your own driver. So if you use For example in your company some messaging services that is not yet supported You can just create a custom driver and use it or even Use different protocols. So I started working on an IRC driver, but Stopped spending time on it, but it's also possible Okay, I think we have some time for a super quick demo Okay, see the code in the back probably not right Should I make it bigger? Yeah better Okay, so this is a service that's called batman playground. It's currently in beta but What it will do is it Let me just refresh so I'm locked in it allows me to quickly try out a chatbot So I have this code editor here and underneath. I have this web widget that I can use to try the chatbot so If I would say batman here's Hi, and we go into the closure There we're going to say but reply Hi PHP conference. Okay. So if we try this and type hi We should get the response. Okay so Since a lot of the speakers here rely on feedback, I thought it might be a cool idea to just build a Quick demo of a chatbot that you can use to rate this talk on Telegram, I don't know Quick hands up how many people have telegram here Okay, quite a few So what we're going to do is when you connect something to telegram You have a get started button and when you press on it Telegram will send a slash start method a message. So we will use this to Start the conversation Which is new app conversation and in this conversation class, we have the run method So I'm going to create a question. How did you like this talk? Then we're going to add Buttons to it. So they thumbs up and the value will be good and another button that Was down that All right And then we're going to ask this question. So it's this ask Question And we get the answer and I'm just going to store it. So this rating Equals to answer a get value Sorry, I Still I need to connect it in a minute So since I saw this property, so let's say rating Text so we save the rating then we're going to ask Is there anything else you want to tell me get the answer? Sorry, that's the text property and In here, I'm not using get value because it's not a button click So I'm just using get text to get the text real input And then I'm going to say Thank you Enjoy the rest of the conference. All right So if I haven't fucked this up I should be able to say a slash start. Oh No, I forgot something. Oh, no That's the instance That shouldn't be an issue with the array. Oh, yeah I need to add syntax highlighting there. Thank you Awesome. Okay, so I can click on this if there anything else nope okay and then I have My telegram token here So I can then connect this thing to telegram There's the token in here press connect All right, and since I want to see what you are Using this for I also have a super small snippet to Send this anonymously to a server of mine I'm not accessing any user information here Okay, so this should work if we open this in telegram Restart All right. Okay. Cool. So just real quick because I'm a bit running out of time This is how you can create a super simple chat bot with Batman in I don't know five minutes Okay, so this is all I have you can find the whole Batman Library at botman.io. There's also the link to the GitHub repository as it's open source the But that we just connected is called botman talk feedback bot or you can use this link if you want to try this out right now and If you find the whole concept of chatbots interesting I launched a video course on the whole topic at build chatbot.io Last week so you can check this out as well Thank you