Video details

NodeJS: Build a Facebook Bot with API | Kevin Lewis

NodeJS
02.20.2021
English

Kevin Lewis

Speaker: Kevin Lewis
Users message a Facebook page, and it gets stored in a basic database. When they message ‘RECAP’ we return all messages they’ve sent to-date.
Target Audience: ================= Learners with low technical proficiency/confidence with JavaScript or the Vonage Messages API.
Technologies: ============= - JavaScript, Node.js, Express.js - Vonage Messages API - nedb (small file-based database)
Requirements: ============== You don’t need any technical skills, but if you know some JavaScript it will be useful. You’ll need to have:
- Node.js - Code Editor - A Vonage API account - A Facebook account
Speaker: Kevin Lewis
Bio: Kevin Lewis is a Developer Advocate for Vonage, where his role is to support the local tech community in London. He’s an experienced events organiser, boardgamer and (inexperienced) dad. He’s also the lead organizer for You Got This - a network of events on the core skills needed for a happy, healthy work life.
Event Page: https://www.meetup.com/Junior-Developers-Singapore/events/276101622/
Produced by Engineers.SG Recorded by: Michael

Transcript

My computer. OK, great. Yeah, so once again, Kevin will be showing us a little bit about how to create your own Facebook messenger, not using a Vonage API. So today most of our practices will be done with logs and make sure you set up once again, you haven't signed up for the developer account on your. Shall we go check check it out and use a coupon code to redeem your free credit? I think I also understand you also lift the limit on your account when you get the free credit. So they'll be helpful, for example, for the tutorial. Right. And now heading off to Kevin, who will walk us through the rest of the. You haven't. Hello. I'm just going to check. I need to reshape my screen, I believe. So let me go ahead and do that. Or am I sharing my can you see my screen? We can see your brother. Oh, OK. There used to be a little a little boulder on it and it's disappeared, but I'm glad you can see it. Hello, everyone. My name is Kevin Lewis and I am a developer advocate at a company called Vonage. Now, you may previously have heard of us as a company called Máximo! We are now called Vonage. But that's why in a couple of places you'll still see the next MOT terminology. But we are now firmly Vonage. We are a cloud communication platform that lets developers integrate voice video messaging and security into their applications using our APIs and SDK. Our goal is really to give you a set of a set of solid foundational building blocks to integrate communications into applications and then let you do that in whatever way you feel happiest. So we have a set of APIs sending and receiving SMS messages programable voice, which is not only voice over IP, voice over the web, but also traditional phone numbers that you can rent from us and then write code to power. programable video. Two-Factor Authentication can sometimes be a bit tricky, but we've turned it into like quite a pleasant to use API, actually, one that I underestimated in the first time I used that, I was like super blown away at how easy it was. And a whole bunch of other APIs today, we're going to be using the Vonage messages API that lets you send and receive messages with SMS, Facebook, WhatsApp, Viber using a single API. So that's pretty cool. So just by changing a couple of keys in an object in your request, you can send using different platforms. Today will be using Facebook, but the exact same code would stand should you be using WhatsApp, SMS or Viber. So that's pretty cool. So, yeah, that's what we'll be doing today. We've got plenty of time and I have the chat open, so if you have any questions. By all means, pop them. And as and when I can, I will answer them for everyone while I'm here. I'm going to do a quick, shameless plug as well, because I think it's particularly relevant to this audience. I also run a conference series called You Got This, which is all about core skills, sometimes called soft skills, that you need to kind of excel in your tech career. There's currently almost 50 talks available for free and the talk library, and I recommend that you go and take a look at them because some of this stuff is like super, super valuable also, regardless of where you are in your career. Right. Enough of the shameless plug. Let's talk about what we're going to be doing today. Today, we're going to be building a Facebook bot shock horror. I think we we kind of knew that one will be building a Facebook, but using the Vonage messages API, it's not going to be a clever, but it's not going to do it's not going to do anything to advance. But what it will do is take messages that are sent to a page, stored them in a database, and then when a user sends a specific command, I think we're going to use the word recap, will go and get all of the messages from that user and just send it back to them. However, when you receive messages, you can do anything. You can go off to third party services and APIs and then respond and you can start conversational flows. You can do you know, you can use machine learning platforms to understand what the users are asking for. But today, we're very much going to focus on the foundational part of building bots, which is getting messages in, storing them and replying to them with specific functionality on certain commands. So you don't need a lot of technical skill to take part in this workshop, but we are going to be doing it in JavaScript, a bit of JavaScript, if you know it will be useful. You need to have no jobs installed before now. If you don't, this is your kind of five minute warning, I guess, to go ahead and do it. Now, just to all download the latest version. I always recommend the ELT's, the long term support. Install that and we'll need that to run some of our code today. You're still going to need a code editor. I'm going to use visual studio code here and you need access to a terminal or command line. I'm going to use the one that's built into visual studio code here. You're also going to need a Facebook account and you are going to need a Vonage API account, so if you haven't already got one, you can click start building for free here and sign up for an account and then in the zoom chat or paste it just once more. I think at this point, most people here have seen this. You can go ahead and sign up for an account as a coupon code that will give you 10 euros of credit. And it'll also lift the initial restrictions on your account, which means after this workshop, you can also play with some of the other APIs we have. Right, let's get to it and open your code editor and create a new folder for this project. I'm going to just create one on my desktop here. And I'm going to call it. There we are. I'm going to call it Facebook Doszpot. I'm going to recommend you don't put spaces in it. I'm just going to drag that into visual studio code to open it. So here we are, we've got this kind of empty directory to work with. Now, when we run applications on our computer, there are only accessible via a local host, you are allowed to devices on our local network. But for our application to work, the Vonage API platform needs access to our application via a publicly accessible neutral, because obviously we can't see as Vonage what's happening on your local network. So we're going to use a tool called End Grok to make that work, open up a terminal and this is a terminal. You'll want to you're going to want to keep running throughout this workshop and we're going to type in the following command ENPI X. Not NPM, NPLEX space and rock 'n' g r o k space. H ttp. Space three thousand NPCs and Brock HTP three thousand. So when we enter in a moment, what this is going to do is use the ENGELKE platform to provide a publicly accessible, temporary you URL and when people access that URL, all of their requests will be sent to our local hosts application. This is going to save us having to constantly go and upload this application somewhere on the public web and restart it. So let's hit, enter and grok HTP three thousand. And you get this little dialog here. So it's given us this temporary URL, we want to take note of that for later, and any requests that come in here will get forwarded to our localhost application running on three thousand. We don't have an application running on three thousand, so we'll need to build that. Just to know if anger stops running and you rerun it, this uproar will change. So it's important to leave this open. And if you do restart, I'll point out where. But you'll need to update this value in a couple of places. I'm going to click plus here. To open another terminal, so that's still running in the background and then we have our kind of working terminal here, which will use in just a moment. So we've got our empty directory. We've got our terminal here, our terminal is inside of our directory. If you aren't using the Bakhtin terminal here. Oh, you're not in the same directory. That is open in visual studio code, you want to move into that directory, just a reminder, if I go back to my home folder in order to do that, we type in code for change directory space. And then wherever this folder is for me, it's on the desktop and Facebook bot and hanta and that will move us into the folder suite. The next step is to go and create a Vonage API application. So let's go back to our browser and go to start building for free. This is your point to sign up or sign into your account and you'll end up here on the Vonage API dashboard. And just just a reminder for everyone, I have my eye on the chat, so if I'm going a little quickly or you have any questions or issues, by all means, throw them in the chat. So what we want to do is set up a Vonage API application because we can set up many applications within our Vonage API dashboard. So we're going to get to your applications here. And create a new one. You can give it any name you want. So. That's why I'm going to combine S.G. Junior's. And you'll want to generate a new public and private key. Oh, so, yeah, so I see Engelke installation takes time. Yeah, so when you run, what it actually does is exactly as was posted here in the chat, it will go off and grab the files needed and then without installing it, it will run the application sometimes. That takes just a moment. I'm going to finish the explanation of this part because you can be doing what we're doing now while an grokking stalls and then I'll pause. And Steve, if you don't mind, it would be great if you tell us when you are when you've got it installed and if anyone else needs a moment, by all means, let us know. And if it's taking a couple of minutes, then then I'll move on in the interest of time as this is being recorded. So the next thing we want to do is generate a public and private key. So we just click this button. I see that you have got in grokked now, which is great. And it would cost to download a private key file. Make sure you save that. And that's currently in our downloads folder, but we will want to move that into our application directory, so let's go and do that quickly. So we've got this private key here. We've got this Facebook folder here, which is going to track that in. So that's now in our Facebook folder. So let's talk about what these keys are for. Well, actually, we don't need to spend that long on what these kids are for. We're going to need the private key to authenticate ourselves with the Vonage API platform in our code. That's basically it. So it needs to be in the folder where our code lives. Now, this application can have a number of capabilities. We can do kind of phone calls and voice over IP, what we want here is the messages API, so we turn that on. And it requires two pieces of information. It requires two publicly accessible euros. Spoiler, we're going to use Engelke for this, so it pipes it to our local application. So what are these two, Yarl's? The first one inbound to you, Earl. Will receive data from the Vonage API platform every time our Facebook page receives a message with information about that message. That's what the first one is, inbound URL status URL, what that will do is when we send a message, there's quite a few states that that message goes through. It's been sent, is being delivered, is being read. The status Earl will receive data from the Vonage API platform to keep you updated on the status of your messages. We're not really going to use the status of too much today, but we do need to provide it and we do need to build it in its most simple form. So what are we going to do here? We're going to pop out and rock you IRL, so let me go back to my ENGELKE terminal here and copy this URL. Copy that. And we'll pop that in here. At the end of it, we should type in slash inbound. So what this will do is send an HTP post request to this URL, which is equivalent to localhost three thousand on our machine slash inbound. Whenever we receive a message. And exactly the same on the status Piestewa and khyal, but this time will go slash status. So let's just recap the settings. Give it any name you want, it doesn't really have a bearing. Generates a public and private key. Your private key, you should have moved into your project directory. We've turned on messages. In inbound, you, Earl, we've put the Engelke, you Earl, which pipes messages, which pipes I request to localhost three thousand inbound on the status Earl which will give us updates when we send a message slash status, lets it generate new application. And that is our application generated now, just as a note, this application ID here, we're going to want that later. I'm going to copy it. But you may well need to come back here later to grab that if you don't have it on your clipboard so you can get to this page your applications. S.G. Junior's and this is our application page, which also has details about all Web hook Yarl's. Now, we're actually almost at the point of being able to write code, the last step is to actually link a Facebook page to this application. Now we have a really nifty feature called the Messages Sandbox. So in the sidebar, if you go to messages and dispatch and you click on Sandbox. I really like this, I didn't use it until quite recently. But it's it's really cool. So instead of needing to sign up for your own Facebook page to test this. The sandbox lets you use our page to test this, so here's how it works. Here's what you need to do. In the Facebook Messenger section, there'll be a button that says add to sandbox and when you click that, it will pop open and a little view like this. There are two things that are important here. The first is this link, which you can also scan from your phone and use on your phone if that's how you're going to use messenger. You can click on the link and that will take you to a brand new message on Facebook with the Vonage sandbox. The second thing that's important is this three word posturings. Right here. So you can copy these three words and what you do is you just send it as a message to the account and what that does is it makes is it kind of links your account. With this application based on those three words, which means we have hundreds or thousands of users all using the same sandbox, but because they use the different passphrase, their applications are linked to different accounts. It's pretty cool. So you want to go to that Facebook message and type in or copy these three words and send a message. If you hit refresh down here, you should then say you have one user waitlisted, which means everything is connected correctly. Now, I'm going to give you a moment to do that. This is a moment where I'm going to encourage some participation. Just come into the chat and let me know you've done that. OK, let me know if you have issues. I'll wait just a moment. And I will wait for a few people to tell me that before I move on. Thank you. When I got that sorted. Brilliant. Thank you. I think we're good to go on. I think we're good on time. Excellent people have got it. Thank you. So now our application. Is linked or our account, our Facebook account is linked with the sandbox. At the end of this workshop, I'll show you how to get this set up with your own Facebook page. But it really is not a lot of additional work, I'm I'm like I'm impressed with how easy this part of it was. Now, if we scroll down this page. We have to provide two more URLs specifically for the sandbox now in this case, we're just going to use exactly the same ones, exactly the same one we used for our application. So you'll end up zero slash inbound. And you are I'll slash status and then we'll hit save web folks and I'll give you just a moment to do that as well. Now, I'm not going to scroll down any further in this page, because if I do, you'll see my APIC and secret, but there is actually a code snippet just below here. If you just want to open up your terminal, you don't have to do this. Thank you for joining us, Ryan. Have a great day. Hope everything's okay. If you if we weren't building a complex application and you just wanted to check everything worked, you can copy the whole request as written in this black box just here at the bottom of the page. Paste it in your terminaling, enter don't have to do that. It's not an important step for this workshop, but the code is there. But we're going to use we're going to use a no JS library for Vonage to get this to work now. This is everything we need to do in the set up. And in fact, I think it might be the last time we need to touch the dashboard apart from at the end of our show, you how to link your own Facebook page. So let's just recap what we did. We have set up a we set up the sandbox. We've locally, we have set up ENGELKE. So we have a public URL which will go through to localhost three thousand. Alfred, no, it doesn't actually matter where you kick off and it can go anywhere. It was just. Indiscriminantly, look for applications running on point three thousand, Owen, do you need to hit the save weapons button? Yes, please. It's once you've done this, just hit save, where perhaps you should get this little success dialog up at the top. So he set up and got locally so our application can actually get so the Vonage API platform can actually send data to our application. We set up a Vonage API application with ah and grok you URLs. We set up the Vonage messages API sandbox here so we can use. This page instead, instead of our own and again, I'll show you how to set up your own at just the end. And we've also downloaded our private key from our application and popped it in the Facebook bot folder. So we're now firmly at the point where we can go and start writing some code. So go to your Ed. Open up your terminal. I'm going to start in the terminal, we're going to grab our dependencies. Or install some dependencies, so a couple of commands we're going to need to do this. In fact, let's just take a step back and talk about installing packages in general so NPM or the node package manager contains thousands of packages that developers have written, which we can include in our JavaScript projects. And in fact, our own Vonage node SDK is available through NPM instead of including tens of thousands of lines of other people's code. When we share the project, we can store the packages we want in a file called packages. Jason, we can just list off all of the packages that we want to install and then developers can install those packages using this one file as a reference to what needs to be downloaded. So we want to create a package, Jason, file that we can then describe our dependencies in. And we can do that by opening up our terminal in the Facebook bot directory and typing in NPM. Space in it for initialize space, that's why. And hit enter. And what that does is it creates a new package, Jason file for us with all of the defo answers. If you leave off that, we will ask you a bunch of questions. Typing And that's why just answers default with all of them, because for this, it doesn't really matter terribly. I thank you for joining us, Nicholas. So now we're going to go and install all of the dependencies we need for the whole workshop. We're going to install them and I'm going to explain what they will do and we'll get to see them each in play as this workshop progresses. So let's type in NPM space. Install. Space. Am I going to install Xpress? Space. Body Dasch Passa. Any DB. And again, I'll explain what each of these do while they install space and the assign Vonage. Forward slash server. And I'll pop this in the Azem Tazewell Dash STK. And then that sign again, and Peter, the reason we're going to install the beta is because the messages API is still in beta, so we need the beta version of the SDK hit Enter. And now I'm going to copy all of that. I'm just going to pop it in the chart here and I'll give you just a moment to install all of those while I explain what each of them do. So. By installing these packages, they get added here to the package that Jason file, so it's the name of the package and the latest version, as we can see that. So Express Jazz is a Web application, which is a Web application framework for no jazz, so we can build Web applications more easily using express body parts, so lets us access data sent to our applications more easily as well. The Vonage service SDK for Narges gives us an easier way to interact with the Vonage APIs. So what this means is we actually have, as Vonage let me pop over here, we actually have an API that you can use without installing any dependencies. So each of these API calls comprise of a method and a neutral all of the information you need to send along and any authentication details you need to send using the SDK, we can interact with this API in an easier way. And if you've written JavaScript before, we'll be writing it in a more JavaScript way as well. Finally, any DB is a simple file based database. What that means is when we start using it, there be a little file that pops up in our directory and it will be that file that contains all of the data from our database. And we'll read right to that file is not really suitable for anything serious, and it's used in a very similar way to Mongo DB. So if you want to move later and use this in the real moving from ETB to Mongo, DB is a huge step, but we're going to keep it like today. Right. I hope everyone's got those dependencies installed, this is your chance to come into the chat and tell me that you haven't got them installed. But we are now going to write some code. So the fact that no one's told me they haven't got it in, so I'm going to assume you're all good, so let's create a new file. And this is this will be the way we do all of our application logic index dot J.S.. So the first thing we're going to do is set up a Web application. With with express and Body Passa. So the first thing we do is create a new app. CONSED app. I'm not sure if you will be at the point where you've kind of experience kont consed let anvar consed is a way of creating a variable that will not change later and cannot change later. You may well have seen VARE or that doesn't really matter for this workshop. But what I do is I always use CONSED unless something needs to change and then I'll use that. So CONSED app. And what will do is require express with and initialize it with the default settings. So what this will do is go grab all the functionality of the express package, initialize a new instance of an express application and store that in a variable called app. Next, we're going to we're going to include Body Passa. Require body dash posture. None of these extra brackets on the end, sorry, consed body posture. Equals. Oh, butterfingers, this morning. We are now, just as a note, you'll notice that for that I'm using body and then the capital people say this is a convention in JavaScript. A dash is not a valid character inside a variable names. So we leave that off. So that is us requiring body parts. Yes, I mean, it's called cammo case, and there's a whole set of variations. So I think, like, body parts are awesome. I think this is called Kabab case. Anyway, yes, it's called Camil Case Lowercase first letter, and every subsequent word has an uppercase. Next, we're going to actually tell our express application to use body parts. Now there are two lines of code we need to do this. I'm going to type them in quite quickly, then I'm going to copy and paste them into the chart, so we're going to tell our application to use Body Passa. Body posture, Jason. And we're also going to say you are al and and coded. An MP in her extended. True, like some body parts, Jason Brown, Brackett's body pastor, uncoded rounded brackets and then cited that as an object with extended trees. So let's let's pop all of that in the chat here. These are lines of code, these two that I almost always end up copying and pasting. So we've required an initialized express, we've required body passa, we've set up a body passa, and now we're going to start our Web application that currently does nothing, but we are going to get it set up. So we're going to say, listen. Round brackets. And we can put the number three thousand in here and this number here is the port that this application will run on. Now, you may cast your mind back now to when we set up and we said send any requests to localhost. Three thousand. We said Engelke HTP 3000. If that number wasn't three thousand, that number was three thousand and one. This would also want to say three thousand and one, for example. So this is the kind of skeleton of an ExpressJet application. Right, let's set up our inbound and our status and points now, remember when the Vonage API platform receives a Facebook message to the Sandbox page? And later our own Facebook page. It will send a request to our local hosts, three thousand via Grok Slash inbound. When we send a message, it will send updates to slash status. And you may remember these were. Where is it, HTP Post? Requests, so this Web application will have a number of points, each of the endpoints will contain a path such as halo or slushing bounce status and a method which in this case is post when an incoming request matches that method and that path, collectively known as an end point, a function, a set of code is going to be run and that will be our custom functionality. There are a number of supported methods where HTP methods, so we'll be using post, there's also get requests as well and several others, all endpoints should send a response, whether it is a success, whether there is an error, whether there is or is not data to accompany the response, there should always be a response. Now, when working with the Vonage messages API, as mentioned, there are two endpoints we're going to need to create. The first will be used when there's an incoming message that will be a post request containing the message information itself and the other will be used when there's an update to a message. Status that we send is also a post request. It contains some information. And remember, you always need to respond to requests if you don't send a response to a request of the Vonage API platform sends you the data, it never knows that you received it and it will constantly try and send it, which means you could end up with multiple messages in your database that are actually the same. Right, enough repetition, let's get on with it so we can build these root handlers is what they're called just above this app don't listen line. So this should be the last line. So what we do is we say app, dot post, and that's because it's a post request, Atget would be a get request, but we're going to do a post request. Brackett's. Now, the first parameter, the first argument, the first option is going to be a string which contains the path. So in quotes now forward slash bound. So this route handler will be triggered whenever we get a post request to slash inbound. So the other side of that close quote now, comma, we are going to write a function that will run when this endpoint is hit. Function. And this function has two parameters request and request contains all of the data that is sent to us from Vonage, and the second argument is response, which is something that we need to prepare and then send. Fantastic, and all we're going to do is we're going to console Dekalog. Request Dott body. So the whole request, everything to do with the request, every tiny little bit of metadata is inside of an object called request, but the data that sent along is in request body and it's in request body because we have included an initialized body passa makes it way nicer to work with. And then remember, we have to respond, so we're going to send a very basic response, it almost doesn't matter what it is we're going to say response don't send. And then inside of brackets and quotes, just OK. But what this will do is let us see what the request is. So to recap, when we get a post request to slash inbound. This function will run, this function will just console log. The data that came to us from Vonage. And then just respond so fond of the JPI platform knows that we received it. Let's just copy all of this and duplicate it and just change inbound for status. Hit, save. And now we're going to test this out. We should now be able to see something which will be quite exciting, so. We've said all of this up, we've got our two root handlers that should receive data when we send a message to this Facebook page inside the Facebook box now inside of your terminal. Sorry, let's start this application node space index DOT James, enter. And your terminal should just hang. It's a Web application that continuously runs, so that's good. If it's Arad's at this point, there's a problem. So before we test this, I'm going to give you just a moment to come in to chat just a few seconds and tell me if there was anything that doesn't look like this. Basically, if there was any error that may have occurred, things to watch are things like Brackett's. Sometimes it will be things like misspelling log, little bits like that. Let's go test this out. Let's go to the Vonage sandbox, which we should have already waitlisted our account. We can type anything we want in there. Hello. Um, nice to see you just bump that up to enter. Now, we shouldn't expect anything in response, but if we go back to our terminal, you should now see a set of data. This is your chance to come in to let me know if this works. And we can in just a moment talk about what all of this data means. But come into chat. Let me know if it worked. Let me know if it didn't work and if it didn't work. We can try and unpick it together. Excellent. Brilliant, glad to see it's working for you. Let's talk about the data. Message UUID is a unique identifier for this individual message, every message that you get sent will have a different view. You it. I mean, why does your different let us know your. Yeah, it shouldn't look different at all. Um. I'd be interested, I'd rather you didn't share your screen, you can describe the difference in the chat and we can relay that to everyone. So I'll keep going through the explanation while Owen shares the differences that they're getting from. Describes the user account that sent you the message. Oh, excellent. So this is not just a little different. This is a straight up error. So what I'm going to ask you to do is you're going to copy all of index. And you're going to just pop it in the chat and I should be able to spot what it is. Hopefully it won't be anything to too difficult to fix. So this ID here is actually the ID for my Facebook page, like my personal one, that just message, this page. Every account has a like a unique identifier to this is the ID of the Vonage sandbox. I only seem to have fixed it wonderful. Now the message is the actual message that was sent. So instead of message, which is an object, we have a property called content object. It has a type of text. Remember, it's not always going to be text. It could be an image. We'll be working with text today and the actual message that was sent. And then finally, a time stamp. This is exactly when this message was received. So that's this route slash inbound console logging. Brilliant and again, just to clarify, I think, like you fixed it right, you found the small type time. I'm just wondering, whatever is in dysfunction, it must be corresponding to whatever is in the console. Look, for example, if you use request within a function, practice within the console, you have to use spell the entire word request. Exactly. OK, so so so what you'll often find when you're looking at code snippets is and when I write applications, you'll see people shoot it to rack and raise request response. And if you do that, this must also be ready. And I think that's I think that's what I think that's what got a. Hung up. When I ran, workshops are generally forword them, so so it's a bit more explicit, but yeah, they this word here that's highlighted has to correspond to OK. Oh, thank you so much for just running through the steps we've done to date. The private key. Yes. Came from when you created an application. I won't be going back there right now. But yet the the steps are right here. Now if you've created an application, actually, I will say this because this gets people if you've created an application already and let's say you didn't save your private key, you can edit, you can generate a new one, install the new one. You must hit save changes. Hey, I have lost hours to not hitting save changes down here. So make sure you are doing that. So this is our incoming data. Now, the next thing we're going to do is actually store this message in a database because right now the message comes in and then apart from it being here in our terminal, it vanishes from thin air. There are lots of databases available. Lots will be hosted for you on the Web in this workshop. We're going to be using a database called Any DBI, and it works by storing JavaScript objects in a file in this directory on your computer. I chose it because it's the most straightforward. But it can easily be swapped for Mongo DB later at the start of this workshop, we installed EDB as a dependency. So now it's time to require it and use it inside of our project. So let's include it up at the top, so I generally like putting all of my requires at the very top, then kind of all of my set up and configuration, then my root handlers and then my Abdol listen at the bottom. That's just the way I do it. So up here. But just to be clear, you could quite easily write this code down here as well. It doesn't matter what I'm going to pop it up here. So let's create a new excuse me. Let's create a new variable called any DB. And we will require. In the same way we did Body Passa and EDB. This gives us all the functionality of any DB. Now we're going to go set up a database. So I'll do that down here in this kind of configuration section, create a new variable. I'm going to call this messages, but you can call it anything you want, you could just call it Debe for database. I'm going to say messages. Equals and again, I'm going to copy and paste this into the chart, in fact, I'll do it first. And then I'll type it out. We are going to set up a new and EDB instant's. And in here, we're going to put an object with two options. The first is a file name and this will be the file that all of our code, all of our messages, our safety. I'm going to call this messages. Messages dot the B. Messages, you can call it anything you want, and it doesn't need to already exist. After that, we're going to create one more option auto load truth. And just remember, true does not have quotes around it. And this, as soon as the application starts, will make this database available to us because we are also loading it. Now, when a message comes in, we're going to delete this console log. We're going to go ahead and we're going to store this whole object here, this whole object, which was request a body inside of our new database. This is how we do it. Messages or whatever you've called this variable messages, dot insert. And there are two options that we need to provide two parameters, the first parameter is the actual data we want to put in the database, and the second one is a function that will run after that has happened either successfully or unsuccessfully. A callback so we could do lots here, we could pull out specific information from this object because I think all we actually need is like the timestamp, the text and the account that sent as the message. But for this, we're just going to throw in this whole object. So we can straight in here request. Richard Quest body. We could stop now, that will work, that will put data in a database, but we will want to do something once the entry has gone in or once that's been attempted and failed. So off the body, we're going to write a new function. Two parameters, error and record, again, you can call them whatever you want, but this will be the data held in them. You will only ever get an error or you will get a record. So first thing we should probably do is check if there's an error, if error. We will return we're going to put the return word here, so we will end at this line. It won't continue this this function return, which is going to go console direr. Error. So whatever the error is, just pop it in our terminal. Hopefully this will never happen and we won't see it. Maybe, maybe we will we'll find out in a moment a. After this statement, we're going to write the logic that will happen if this application didn't return here, which means that isn't an error. And what we're going to do is console log record so we can see what happens there. So just to recap messages or whatever our database is called, insert. We pop our object in here and then a function that will run after that has happened, if there there's an error, we will stop the function running further. We know more logic will run and we will console error, the error. If this didn't happen, we'll just cancel the record. Now we need to restart our application if we go to our terminal here. Control see to stop our application running, keep up so it says no index jacks again or type hit and hit enter, that will restart our application. Now, just as a note, this application has just restarted and you'll notice that messages D.B. got automatically created for us because it didn't already exist. If it did exist, it wouldn't recreate it wouldn't wipe it, but it would load it. And so it's available to us. But that happened because of this line here. So let's go back to our page. And and type in, type in another message. Can't wait to eat lunch. We're having a mac and cheese. Enter. Go back to our code. Look at that, brilliant. Now, a few things have happened here. This happened successfully, we're not seeing an error. This is the data that got inserted into the database. So it's the whole record. What you will notice, though, is that there is this new property called Underscore Idy any DB automatically adds this value for us when we put data into a database and it is a unique value for every single record. You won't have to with the same underscore it. Even if we pass it to identical objects, they underscore it will make sure that they are different. We don't really need to care too much about this, but just know that she has done that. If we go into messages, Deb, we see that is our object right there, including all underscore ID value. So, Chad, let me know, did that work for you, because we're we're making really good progress, we can receive messages to a Facebook page and interact with them. All we're doing right now is storing them. Will do more in a moment. Brilliant. It seems to be good. Fantastic. Steve, I'm glad you're no longer coding on the train. That is my personal idea of hell of there. Yes, I'm glad that's no longer where you're at, right. We know that items are being stored in the database because as developers, we can go into the database and we can see them there, we can see the terminal like this is great for us. But our users, they have no idea what happened to this message. They had no idea that it actually was successfully received. So we need to provide some feedback to to them both when there is a success, but also when there is a failure. And to do this, we're going to use the Vonage messages API, because up until now we set up an application. We've received messages in, but we've not actually done anything with our Vonage account details at all. So our time to do that is coming up. So let's do that, let's require at the top the Vonage service for no James. So I'm going to call this Vonage with a capital V.. And I'm doing this to match our documentation. So require. And we're going to have to go at Vonage Slash Service SDK, because that is the name of the package in NPM. As a know, when we installed it, we installed the beta by putting at Beta at the end that describes the version, the actual package name is at Vonage Slash Server Dash SDK. Own the results are not coming up after I entered Noad Index, as it worked earlier, though, this is your chance again. By all means, like this is a fairly small application. So you can always just grab your coat here in the chat. We can look at it together. We can figure out what the issue is, have eagles' for stuff like this. So by all means, we can we can try and work that out. OK, let's take a look at this. Due to due to right up top posts, inbound function request response, great messages, don't insert request up bloody great with a callback function if error return console log error, otherwise console log record. Now, that does look right to me. So I'm going to ask you a few questions. Have you restarted your application? Is your application running? Is Engelke still running successfully? And is it you haven't restarted it because if you've restarted it, the Eurail will change and you'll need to go into both your Vonage API application and the sandbox settings and update the URL. This code, though, we can't see anything wrong with it. So I. Don't think it's this. Yeah. So I'll let you troubleshoot that if you have other questions and or you get it working or you're still struggling. Last night. So just to recap where those jurors go in the dashboard, they go both in your application here. And the messages and dispatch sandbox to use the sandbox, you pop them here. And remember, if you restart and grok this part of the URL changes, so you will need to go in and update those. So we have required the Vonage server SDK, now let's initialize it, let's let's set it up. So we're going to create a new variable called Vonage with lowercase V because remember, JavaScript is case sensitive here. So const Vonage equals new Vonage with a capital V. Brackets and squiggly brackets for an object and enter. There are four pieces of information that need to go here. In order to configure this correctly, the first is your API key. This is going to be a string which you can find if you go to the home page on your dashboard by clicking copy here. So you can copy that, paste that right in. Now, I actually have this available in a slightly different way just for me, because I don't want to show you my key and secret. So, Vonage. In the code, anyway, Vonage underscore key, but what you'll want to do inside of quotes is just copy and paste that value. The next one is the API secret, don't let other people see your secret is a string, but if you do let other people see this secret, it basically lets them use your account, including charging credit to your account so people see it. You can go into your account settings and like refresh it. You can get to it by hitting copy here. And then pasting it in here is a quote again, I have this available in a slightly different way for the sake of this workshop. So your API key and secret will link this application to your account. There are two other things we're going to need. Your application I.D. and again, note that camel casing I in I.D. is uppercase and in here we're going to put our application I.D. So let's go get that your applications go into it and copy it here application. I'd just put that straight in there. And then finally, to authenticate with your account and your application, this is where that sneaky private key comes in, private key capital K.. And then here we are going to put the path to that file in Narges to to do this we go dot slash, which means this current directory, private key. These are the four things we need to set up your to initialize the Vonage server SDK for no jass. Now, because we're using the sandbox, there was one final step that we need that changes things just very slightly. When we get onto showing you how to do this with your own page, this step goes away. But for using the sandbox as one final step and I'm going to I'm actually just going to copy and paste a part of this in into the chat. Alfreds asking, could I repeat to each of the fields on the Vonage website again? Absolutely. On your dashboard. Home dashboard dot next dot com apic. API secret. Spiky and secret. And applications inside of the application we made earlier, application ID and your private key you generated here, and if you don't have if you can't put your finger on it anymore, re download it, hit save changes and pop it in this directory as private docky. That might require you to rename it if you downloaded it a couple of times, if you're uncertain, just regenerate it like it, you think time into going, what was it that won or was it that won or did I hit save? So is it that one or that one? So just regenerator and pop it in here is private docky hope that helps offered. So this final step. After. The epic secret application ID and private key object is to add a comma and one more object. Not that we are going to put in an API host, I'm going to take this quickly and you can get the application ID at the top of inside of your applications, your application. And up here at the top, it's called Application ID. And there's a little coffee button here at the site, API host to use the sandbox. I'm going to type this quickly and I'm going to copy and paste the messages. That sand box next dot com. So I'm just going to copy this pop in the chat. So this should go after this first subject. And when you're doing this in the real you don't need this step, but you do if you're using the sandbox. So I'll give you a moment just to make yours look like this, remember, I'm doing process Vonage, keep it. You'll just want to put your key here. And same with your secret. Just in the interests of me sharing stuff, I don't want to share these values right now. Well, you shouldn't share them, so I don't want to share. So I'll give you just a moment to do that. So just to recap, we required it here. We're initializing it here. So in order to send a message with the Vonage messages API or send a Facebook message, you're going to require three pieces of information. You're going to require the Facebook page that is going to send the message the in this case, it's the Vonage sandbox, you're going to require the Facebook page ID for the recipient. So that's my personal ID. And the actual message you want to send, that's what we need, we're going to send messages in two different places, we're going to send them. When there has been a successful, you know, successful, you know, message received entry into the database and also one where there's an error. And because we're going to do this more than once, we're going to create a reuseable function that we can use in both cases. So just above this first post, below our Vonage initialization, let's create a new function. Could send a message. They are going to be three pieces of information center. Recipient recipe, and yes, I spell that right and the actual text. I mean, just open that function up. So, as I said, we're going to need these three pieces of information that need to be formatted in a certain way, so let's do that together. I'm going to go through this bit just a tiny bit more quickly, and then I'm going to take the whole function text. I'm going to pop it in the chat. So first thing we're going to do is create a value call to this is the person who will receive the message, it's going to be an object with a type of messenger. And an I.D. of whatever we've passed in as the recipient. Just note here, we're saying messenger, we could easily say Vibha or WhatsApp, as long as we have the correct recipient I.D. or phone number, we can do exactly the same for from type messenger. I.D. of Senda. Then we're going to set up a message and the structure, by the way, completely mimics what we got in from time messenger ID to type messenger ID, and the message contains a content which contains a type of text. And the actual message you can see here, the actual message itself, I think we call it text. So now that we've got these three pieces of information ready and formatted, it's time to send our message. This is how we do it. Vonage, which is our initialized SDK with our API key secret application and private key and API hosts Vonage dot channel. Dot Send. Who are we sending it to? Who are we sending it from? What is the actual message that's everything we need to do. There is an optional fourth parameter, which is a function that will tell you if something went wrong or if something went right. So here we're going to just do exactly the same thing, if there's an error, then we're just going to return a console error error. And if that what didn't happen will console log the result. So that's our reuseable function, it takes in a senda, a recipient and the text you want to send. It formats it correctly, which, again, is exactly the same format that we got the data in from. And the message. And in fact, I've thought of a slightly nicer way we can do this. But I won't because there's no reason to, like, change things up, I thought of a slightly nice way to do this next time I run this workshop. Very good. Anyway, so we say we have this send a message to from message and we send it via messenger back to the person. Now, let's actually use this function. If there's an error, we are going to send a message. And we're going to remember the first value is going to be the sender recipient, Texas sender is going to be request body dot to do it. So this is when we get an inbound message. They sent it to a page. We get that value and we're going to make that person the sender. Request up body from the ID. And finally, the message, sorry, there was a problem, please, if if you are using this in the real give more descriptive errors. We'll copy and paste that. And will replace this console log here that this time will tell the user that we received that message. Thanks for your message. Save. So now we've got this reuseable function, it set up, it will basically just respond with either there was a problem if we couldn't store it in the database or thanks for your message. And remember, we have to respond to this whole API request, this whole weapon. We have to respond on the Vonage API platform will continuously try and send us the same message. Let's start all over again, controversy up into oh. Enter. Let's send another message to our page. They should work into. And we get a response and we don't only get a response, we we we saw that in the database as well. Did that work for you? Come, let me know, because this is the bulk of it, the final step where we build this recap, where we send messages back to the user that they sent to us, just an example of extending this. This is the bulk of it. We get messages in. We do some work with. We respond. Don't even need to respond immediately. And yes, exactly as Hilary said, if you have questions, pop them straight in the chat, I'm here to help. We've got plenty of time. We're going to come in and the times that there will be time to ask questions, either now or at the end. You can ask me about how to extend it. I'll tell you more about some of the other APIs as well. We should have received a response, hopefully a positive one as well. So storing messages is fine. I think that's the core thing, it's just we're doing something with that data. We could easily go off to, you know, we could put in a city, we could go off to a third party service, find the weather in that city and reply with an answer. What we're going to do, though, is build a recap, key word, so if the user, if they send us anything, will store it, but if they send us the word recap, we won't store it. Instead, we'll go to the database or get every message they've sent and we'll send it back to the user. And just a list. So let's do that. So a message comes in. Right, and let's let's just start at the top. We're going to check if that message is the word recap so that data might sneeze. If I do, I'll meet my mike. So if request Dopp body. The message. Not content, not text. I know it feels ridiculous, but that is how you access. That's how you kind of go down the chain, request up body dot message and then content and then the value of text if requests body dot message dot content that say that five times quick. Is equal to two equal signs because we're checking whether things were equivalent quotes, recap. Then do something. Now, this doesn't quite factor in what if someone types in recapture the capital or they type in all caps, recap this won't work. So what we're going to do is take the message that came in and we're going to force it to lower case. And then we'll compare it versus the case of the string. We could go further, like there are so many things you could that we could go doctrine, which if someone wants a space at the beginning or end, it will strip that off as well. This gives us the biggest coverage if you type the word recap only in your message, even if there's spaces at the beginning and ends of your message, even if one or more of those characters isn't lowercase, this will now match. If it's recap, we're going to do something. And if that isn't the case, it isn't a recap, then we're going to take this coat. I'm going to pop it in here. So if it isn't recap, do the same thing, story, message back, you know, that was a problem. Thanks for your message. Now we are going to interact with the database, get all the messages from this user. And then we're going to reply with them, this is how we do it, messages or whatever you call your data base variable here, messages find. And the first parameter will be all, I'll filter our actual search. So if we look at the structure of the data, I know this isn't too nice to look at. Let me think about how to fix that toggle Wardrop that we are. The from DOT ID is the user that is currently sending a message from dot it, so that's what we want to grab. So what we'll do is we'll in quotes from dot eyed. So if from the I.D. is the same as, yes, this workshop's being recorded from the ID, if that is equal to the person sending us this message, request body from ID. Then grab it and if not, ignore it. Just hide that sidebar. Then we do a function, same kind of pattern in many JavaScript libraries error. And then the results or records. Now, you know, you probably want to do. Solomon, if you're asking me to get the key and secret, we've covered it a couple of times and we're reaching the end of the workshop. So I'm going to encourage you to watch the recording button so you can get it from your vantage API dashboard. So in here, you'll want to check if there was an error. So if error, so log consultor error, error return. We're not going to do that this time because you've seen this pattern a couple of times. I've seen it here. And you've seen it here. But let's assume we've got the data find. What we're going to do is we're going to send is we're going to send a message with all of the records. So request the body to to request the body from the ID. And a message. So let's create the message, right, because we need to do something with this now at the start, this message is going to be in a right. In fact, you know, let's let's just respond with, like, OK, and let's just console the records. You can see what comes back from the database. Hopefully there won't be anything too surprising here, so I'm going to restart the server and I'm doing this a little quicker because you don't need to follow this part. This is more illustrative. What we get back from the database is an array. This is it here, it's an array of objects of matching items, the message that we send has to be a string, so we somehow have to get this array into a string. Now, there is a quite elegant way of doing this. So what we'll do is we'll say records dot map. What map does is it takes it takes an input. It takes an input of an array and it does some work on every item of that array, and it returns a new manipulated array, because all we really want out of here is the, I suppose, the message you sent and maybe when you sent it. So records map. Function record. And we will return. What are we going to retain records? And record, which is the item, the specific item in the database, that message content dot text. And then we'll add to that, like, you know, sent at. Records dot timestamp. And then we'll just add onto the end of that string. So now this is going to be an array of strings. Let's let's do the same thing again, so. I'm going to just call this a for a moment, I know that's not not great. I'm going to just you know, what I'll do is I'll call this I'll just put that in aside for that message. Right. Let's see what this message is all about now, so we're using a map, it takes in each of the records and it will return just a string that contains the message, the word center in brackets, the time and a close bracket. And then we're just going to cancel like this just so we can see what it looks like, so I'm going to restart the server. Send another message recap. We should just get an OK back again. But now our Ray. Just has a single string in it. Just as a single string. Because that's what we return from the map. So instead of that big object. We just sent back this. OK, now we're at the point of needing to actually turn it into a string. Fortunately, there is a way of taking an array and turning it into a single string, and it's called join. And inside of here, we put what we want to separate it by, so let's just say a comma. Restart Restall server. Well, to recap again. Where is it due to due to oh, then console logic, that helps, you know, we're at the point where we can send the message now, so let's change this to message. And again, I'll provide this code for you in just a moment. Let's restart the server. Recap and what do we get back, we should get back all of our messages, yes, they should work since that time stamp coming to L.A., Mac and cheese center time, big, ugly, ugly. So let's instead of just start separating them by comma, let's separate them by a couple of new lines so backslash and backslash can restart the server. Again, recap. Now, you are in if you were actually building this and we had more time and we were interested, we would probably also do something about the date formatting. But I can leave that to you to do. Let me copy and paste this code into the chat. And I'm just going to give you what was inside of I'll give you the if part and everything else should go in the LS part. So let's recap what we did, we set up a Vonage API application and the Vonage API messages sandbox where messages come in, the first thing we do is check if the recap word was sent, if it wasn't, or store that message in a database and just respond to the user that was good or that that didn't work for whatever reason they did. Said the word recap, regardless of whether there's some extra spaces on the left or right of the word recap. So if we typed in recap space in the message, it would still match whether or not any of its uppercase or not it will match, will go to the database, grab every item that this user sent. Former message, which is all of the all of the resulting messages. Put into just a nicer, shorter string that a user may want to see. Make sure there's a couple of empty make sure there's like an empty line between each message. And send it on. That's our whole application. Let me show you now. Actually, this might be the point. I'll show you how to do this with your own page in just a moment. But this is a perfect point for if you have any questions. There are lots of things we could do, you know, we just saw it in the database, we could send it off to a translation service or use something like dialog flow to add some conversational intelligence to the bot or, you know, get the status of trains or busses or the weather banking. You could use this just to gather data, you know, like a Q&A. Now, I could have set up a Facebook bot and had you submit your questions straight through the bot. And just by changing messenger and the ID, you can use exactly the same code for Viber, WhatsApp and SMS. Now, just before I get onto the page, do we have any questions? Tony, if you don't, don't worry about it. I'll give you just a couple of moments if you do have. Any plans to expand, to expand, to telegram? I don't know. I think there's always plans to increase the the number of channels supported by the messages API, but I am not privy to what they are. Yeah, I wouldn't be surprised if we see more channels being added to. It's pretty nice because, you know, you could absolutely just use the Facebook Messenger API and build something like this, you could easily build, but you're not so easily. But, you know, you can just use the WhatsApp for business API and do that. And all of that's fine. We're having to rewrite the entire implementation every time this makes it nicer to work with any single one of them, but also the fact you can use multiple. I'm going to show you how to set this up with your own Facebook page. It's actually not a lot of steps. So what we do inside of messages and dispatch, we had sandbox. There's also social channels. You can connect your Facebook page. Login with Facebook. Give it access to the specific pages, so I've got one here. Then you can select your page. And complete the set up. Then inside of your application. There's a link, social channels. You will see on new pages pop up here so you can just link it to your individual Facebook page. And then in your code, just delete this, I say now you're sending and receiving messages from a real Facebook page. It's pretty nifty, different applications could be linked to different different applications can be linked to different pages and you can have multiple pages per application. You know, you may have this ultimately the same intelligent, like the same underlying code, if you have variants of your page for different countries, different groups, different clubs, but underlying it all, they're the same. You can use the same application running for that. So that's the end of the workshop, hopefully you found it valuable. As mentioned, it is being recorded. There's also some lovely instructions that have been written up. Wow. I wasn't expecting that at all. That's lovely. Look at this. Fab, thank you. Um, if you have. Any questions, I'll give you a couple of minutes. If you are about how you could further expand this, but while you might be formulating those if you are and again, no pressure to, of course. Just worth noting a couple of the other APIs. programable voice is pretty cool, you can send and receive calls and control those calls and what happens in those calls with code? The way this basically works is we have a service called numbers. You can rent numbers from us. They cost a different amount in every country. And then you have these numbers in your accounts. And then you can these are programable, both when you receive and when you make calls, really call one use case of numbers I quite like is called proxy numbers. So if you ever use something like Uber, Lyft grab, you often will be able to contact your driver via a phone number to text them or to call them. That isn't their real number is actually a virtualize number like this. And likewise, the number they see for you is the exact same virtualize number. There's an application running with logic that says, okay, well, this person is currently in a ride. So if this person or they've requested a ride, so if this person calls this number, route it to this driver and vice versa, these numbers don't even need to exist before you click contact driver. They could be acquired immediately via an API to work with numbers to rent and release numbers. And then released, or they might have a pool of them that they use for multiple uses at the same time and then like cycle those in and out. The video API is one of my one of my faves is a really lovely way to build multi-user video applications on Web, iOS, Android, Linux, Windows, Mac, and I think maybe there's a unity beta as well. If you have any two factor authentication, I think this is one of the easiest ways to do it. The Verify API sits on top of our SMS and voice APIs, and it handles the handles, the creation of codes, the expiration of codes, sending out those codes and including multi. So you might text it then three minutes. If they haven't done it, call them. Wait three minute, text them again and then finally expire the code all inside of one API. Really, really lovely. No insight. Kind of does what it says. Insight's four numbers understand where it's from, who owns it and so on. And then basically everything you can do inside of the dashboard, you can also do via an API. So numbers. Yeah, you can list the numbers you own. Search them, buy them, cancel them, update them. Everything you can do here in the dashboard. So that's pretty cool. So for lack of other questions, I think that probably brings us to our conclusion today. Thank you so much for having me. I hope you found this valuable. If you want to kind of get more support, ask more questions. I'm going to encourage you to check out our community slack. I think that's over here on community. And I think it's I developed our next dot com slash slack. Let's find out. It is so you can get an invite for it here if you have other questions, we're there to help you. We have a team of developer advocates and a range of languages. So if you want to learn how to do something like this in another language and the getting started guides or tutorials aren't quite hitting the spot. Check that out. Just a couple of other quick, quick, quick things before I go. We have a new start ups program that's just launched. You can find out more about it on the page. We have this program called Voyageurs. If you are using Vonage APIs and you are interested in kind of getting early release, early access to different APIs, understanding more about how we work, Vonage, how we help you learn how to create better content for developers, things like blog posts and videos. I will answer your question in just a moment. Unless I have a nice, supportive community, you can apply to be a Vonage Voyager. And we also have learned Vonage Dotcom, which has a ton, absolute ton of blog posts showing you how to use different APIs in different ways, in different languages written by different members from our team. So I think I think that's very much worth checking out. So I've got a question here. What else can we do with the status endpoint? Fantastic question. Let me quickly show you what my terminal was actually looking like, so. When we sent the message right, we got a bunch of data, in fact, do you want to know what let's let's quickly show you how this data standpoint works by turning off all of the console logs other than status. So we don't need that one anymore. I don't need that one anymore. Uh, right, let's restart the application and message it once more. So that should still work just without the console logs. Now let's look what happened here in the terminal. We received an update, so this is from the state's end point, looks the same as what we got from inbound, but it has a status and that status will change multiple points in time. So you may receive multiple statuses for one message when it's been submitted, delivered and read. You know, you see that in Facebook Messenger, the little tick in the tick goes like solid and then the person's head replaces it when they see it. You receive a status every time that happens. So if you want to keep track of what's happening with a message that you send, you can do that. Now, I did something fun with this a few months ago. I built a chess bot. The way the chess bot worked was you had us sent a picture of the board and your color. You were able to move a piece. You said a two to a four, and then it would send the other person a picture of the updated board the moment they see that their timer starts counting. Not until they see it, so if you know they're busy and they don't see that message for a couple of hours, that doesn't chip away at their time. More practically, you may just want to know within your application when your messages have been delivered and read by users. You may want to build your own dashboard for that. I hope that answers your question about the state of Sandpoint. Any other questions at all? I realize I didn't talk too much about it. It does need to exist, even if you don't use it, you don't need to console log, you know, the minimum viable status. And point is, is this and that's quite often what it will look like. Yeah, someone just asked why I didn't intend to read now the know, I assume it is a sandbox quirk limitation. Yeah, I do know. I know that too. Just wasn't going to draw attention to it as I was asked. Yeah, but but like, I've used it with an actual page and it works grand. I think you get three or four for every message that you send. Yeah. Only use the sandbox for the first time. A couple of days ago, this workshop I wrote maybe eight months ago before the sandbox was a thing and I thought, oh, let me let me go update it, make sure everything still stands in the sandbox. Made it way nicer to get started. But it also means I haven't explored it in like a huge amount of depth. So I assume there's no other questions. Thank you so much for having me again, if you need us. I mean, the like if you have questions, there's a channel for each of the APIs. If you have questions and all of our language specific advocates, you know, across many across many programing languages, are there to be able to help you if you have questions. So thank you very much. Great, thanks. Thanks, Kevin. That was really helpful. I think I speak for everyone that says by saying that we really appreciate you spending time in the morning and we can sharing all this knowledge of how to create our own Facebook messages. But we appreciate that and never. Wow, cool. And yeah, that's that's that's all we have. Clearest. You actually have any do you have any other thing you'd like a share of. Oh no. That's all great. Yeah. Without further ado, that's, you know, that's, that's our workshop and we really appreciate everyone staying all the way through. And yeah, the links are on in the chat. I believe you should be save a copy. What you can do is a can maybe try and save a copy of the chat. Otherwise you can also find the link to the tutorial, the sample code some because again, it's just me following along and kind of like typing along, so. Yeah. Yeah. So what are the links to the helpful links that we associate just now. Yeah. And you should be a working copy of that. I also update your URL for the YouTube on on Meetup dot com as well as in the GitHub page later. Yeah. So that's all we have. Thanks again, Kevin and Therese for arranging this and thanks everyone for attending. That's all we have for developers to have a great day. Yep. Thank you. Bye. Thank you. Bye.