Text-To-Play Games with Twilio!
with Nathaniel Okenwa
Building interactive experiences that don’t require people to download an app or be present in-person doesn’t have to be hard — in fact, it can be *fun* Nathaniel Okenwa teaches us how!
Resources & Links
_Captions provided by White Coat Captioning (https://whitecoatcaptioning.com/). Communication Access Realtime Translation (CART) is provided in order to facilitate communication accessibility and may not be a totally verbatim record of the proceedings. _
Hello, everyone, and welcome to another episode of Learn with Jason. Today, we're bringing back to the show, Nathaniel Okenwa.
Thank you for having me. I'm happy to be here.
How you been?
I'm good, as you can see from last time, I've slowly upgraded myself.
You're looking sharp. Very professional. I like the background. I'm jealous of your background, right? I'm in a big, like, square box which means my room is echo y. And I have to have this box back here to keep from echoing. I want an interesting background.
I don't have the best in terms of sound. Right as COVID started, I'm like, I'm going to move all of my posters and everything so all of my personality is behind me. I don't come across as boring that way.
I love that. That's amazing. . So, yeah, looks like they fixed themselves. I had no idea what was going on there. So yeah. For those of us who didn't see your previous episode or aren't familiar with your work, do you want to give a quick background and an overview of who you are, what you do?
All right. It's funny because I say this spiel so many times, I almost reel it off the tongue. My name is Nathaniel Okenwa, and I work for a company called Twilio, and it's a crowd communications company that gives the power of sort of traditional communications SMS, email, what'sapp, API and other tools to help you build those things into applications. And I can almost guarantee at some point, you've used Twilio, you just didn't realize it.
Twilio is one of those things, once you start looking for it, you'll notice tons and tons of apps are doing something with it. You can text, you know, you can text to get updates or you can text for more information. Like, if you're going around looking for real estate and you see
Authentication, as well.
It's everywhere, people don't realize, that's the Twilio product. That's relatively new, but Sangrid email is powered with Twilio, too.
It was a cool acquisition. And seemed like a natural thing. Hey, you've got transactional text messages, phone calls, why not have transactional emails, as well?
Precisely. Flesh out the whole communication thing. We even had fax. You can send fax on Twilio but not email.
Can you still send fax?
That's amazing. I feel like, let's figure out somebody's fax number and send them nonsense. So what's up, Chad? Good to see you. Trying out the highlighted messages. That's the only stream part I have. But so, oh, so the last time you were on, another thing we didn't talk about, Twilio also offers video chat.
Live streaming video chat. This was something we did that was a lot of fun on the show where we built a video, kind of a Zoom client, right? Which was super fun. And we were able to do a lot. Holy crap, ten months, thank you so much for that sup.
It doesn't feel like I've been doing the show for ten months. Wow. OK. So yeah. So if you want to see how the video side of Twilio works, you can go back and watch that episode. There's also, I did an egghead course on that same content to teach how to do the live chat with a few extra things we didn't have time for, like the disconnect when somebody, or like removing video when somebody disconnects and a few other things like that. But it's a lot of fun. And what I like about Twilio is because it is not like an it does all of the communication things, but it's not trying to be all of the things to all of the platforms. It's just a set of good APIs, it's not like, hey, you should also use our static site generator. You should also, like, build your app in our platform.
No, no, no. Here's an API, do whatever you want with it. It's really good for that.
So today, what I was hoping we could do is I want to make this show even more interactive. Like, I love the chat, I love how active everybody is. And I was thinking it would be kind of fun if the chat had a way to help us determine the destiny of certain episodes. So I want to enable an onscreen poll for the chat.
Now, I know we're not going to be able to do this on screen because I don't know how to add things to the screen while it's running without breaking everything. But I want to make it so we have an app where I can set questions, like, if we say, hey, what should we build today? The chat can come up with ideas, we can put it in a poll and people can vote with their phones to text and say, like, I want to do this and we'll see the polls moving up and down as we go.
That's something, that's something we could definitely do. I'm looking forward to it.
All right. If we want to do that, I don't know. Should we just?
Yeah. And if people are texting in, so I foresee a couple of steps. The first thing, we need to first of all hand over incoming messages on a phone number.
And then, we would need some sort of thing to keep track of what the current status is, right? So, like, there's this many votes.
And then, we would also need to display that, but update it live. As texts come in instantly wherever that is that gets sort of updated with the latest information.
I think what's going to end up happening is, and this is a classic thing with Twilio. At Twilio, we do a couple of different things and sometimes you get to daisy chain them together. I guess the first thing, I guess, is to buy a phone number.
OK. Let's switch over to code mode. And we can start from here. We will let's see, we'll go to Twilio, I guess.
Twilio. I'm sure you should have credentials from last time.
We're about to find out. Let's see, this one. Let me pull this off screen so I can do the log in quick.
What's really cool, as well, just in case, some of it we've released since the last time we spoke, we released the CLI. So we could actually do this from the command line in the future. Not the future, right now.
I want to do that.
Yeah. I mean, I'm doing, I'm setting two factor auth on this because it says I have to. Give me just a second to get that running. On a Mac?
I'm on a Mac. Well, I'm actually on both, but we're coding on the Mac.
Do you use Home Group?
Give me just a second, I don't know what Home Group is.
No, Home Brew.
Yeah, I do use Home Brew. Just a second, I've got a code to save somewhere, I'm trying to find out where to put it that doesn't involve me opening up a bunch of stuff. Let me go to, I guess, here? Yeah, that's fine. OK. All right. So I have the wrong app open, so let's go back up here, and we'll clear that. I am ready.
And I think I'm logged into my Twilio account, as well.
The account said it can be public.
Account said it is public and auth token isn't.
So this is what the, we call it the console, it's not confused with the CLI, and this is sort of the graphical website where you can do the stuff and you can use the CLI, which released late last year. And to install it, if you go, you've got to tap it first. Twilio/brew and brew install Twilio.
Brew, tap. One of these days I'm going to learn what Home Brew actually does. This is my best example of copy pasta code. I have zero understanding of Home Brew, I just copy/paste stuff.
I'm so happy it's not just me. I'm so happy. Actually, right now, it's number two, one of the things I'm going to do a project to learn. So I recently, in my Macbook broke and I had to get it fixed and reinstall my dev environment. And one of my colleagues, he's like, he wrote a script in Shell, that uses Home Brew to install everything and config so all of the developer tools come back. And it's just, oh, he's got a GitHub repository.
I'm definitely going to check it out. But then, you can use Brew to install. Also NPM, install Twilio, CLI and install it globally. Everything single Twilio API that you can get normally. Sometimes, you're looking for it, you can see API features that were about to be released, just like a little bit before it happens. I found one by mistake the other day. Yeah, we're about to, we're about to release that.
Nice. So was it Brew install Twilio?
Yeah. Brew install Twilio.
All right. Here we go. I think the only qualm with Home Brew, and I've been told I can solve this easily if I Google it is every time I run a Brew command, it does a full update of everything in Home Brew before it starts doing the one thing. Like, just takes a while to get rolling. I'm pretty sure that's a flag I have to check. But you know. And right on cue with the hold. Also, did you see the new outline of the new files for the overloads with the tech? Isn't that cool?
Yeah. The whole sort of setup that you've got going on is so sick.
No, my sideways boops are back. What have I done?
This is like, it's like that movie. Oh, my gosh, Inception. When the room rotates all the way around. You've got that going on on your screen.
Oh, good. Good. All right. I'm going to have to sit down and figure out what that is and why that's happening. OK. So I now have the Twilio CLI is installed. I just checked using the witch command, which is a handy command to know I have it and where it is on my computer.
So now that I'm here, what should I do next?
So Twilio space log in.
Twilio log in.
And it's going to prompt you for the account and the auth token of your account.
I just learned about keytar the other day. And it makes me happy that exists.
I'm going to pull this one off screen.
Yeah. And hoe it's not lying to me. It's not. Shorthand identifier, do I choose whatever I want?
Yeah, what happens is, you might have multiple Twilio accounts. Twilio demo account and work account, which has different things on it. I switch between the profiles.
Stored the secret, OK. OK.
We are using Twilio to build. I think that lets people with SMS sort of message in and vote and things on the show, play games and stuff.
Oh, man, you just got trolled by the chat.
The robot is actually the chat bot that runs in here.
Oh. Got you good, man.
You got me good.
Got you real good.
Real good guess. Keeping an eye on the chat.
Oh, that's excellent. I like that idea. We need, like, a sneaky troll command. That's funny. OK. So now, all right. So I'm logged in, looks like I've got an API key, there's a secret that was not displayed, which is great. What do you want, Tony? We're paying attention over here. Jeez. So, I think
So we can buy a phone number, that's the thing we need.
Can I do that straight from the command line?
Yeah. So Twilio, API and so what you can do, Twilio API, if you hit enter, it then shows you all of the commands under it. If you hit return. So now, there are a lot of APIs that we offer. So it can take forever to sort of get through them. So what's also really cool is we have an auto complete. Are you using bash?
So we have autocomplete. You could write Twilio, autocomplete bash to install the autocomplete functionality. So then, you would just tab and it would add stuff.
Bash. Yeah. There you go. And
You can get Twilio, API and hit tab. Call, call first, API, no, core, API, core.
So, no, no. I'm getting everything wrong. Twilio, API, and then core c o r e, we're using the core API.
And I'm going to remind myself what comes next. Incoming phone number. No spaces just yet. And incoming phone numbers. And then, if you put colon list.
That would list all of the numbers you have. If you don't mind sharing the numbers you already own.
I don't know if I actually own any. I own one.
I built a GitHub action with Brian Douglas that texts whenever one of my repos builds successfully, like, I get a text message. Which is really funny because I forget it exists and I'll occasionally get a text message that's like, new repo build. I'm like, OK.
So then, the other one we want to do is Twilio, API, but rather than core Twilio API, we want phone numbers. And if you put, if you hit enter, trying to remember what the options is.
Isn't it numbers, not phone numbers?
Is it numbers? No, I'm wrong.
It's definitely Twilio phone numbers. Hold on. Phone numbers. Oh, Twilio API core available phone numbers. That's what we want.
API core available phone numbers. Twilio, API core available phone numbers.
OK. Mobile, national.
You probably want a local one, I think.
OK. Cool. And put list at the end of this. So colon list. And then, what you probably want to do is narrow it down to a area, country code and area code. Dash country code, which is like the US.
Oh, US? OK.
And do you want to put an area code, as well?
I don't really care. But we'll show how it works. It'll be area code.
Area code. And then you can put, I don't know what American area codes are.
Let's go Montana pride. That's my home state. Let's do one of those.
So here's a list of available Montana phone numbers.
Yeah. So you can, you copy any of those numbers, just any one of the numbers that you want.
And then, command would be Twilio, API core incoming phone numbers. Instead of list. If you go hit the up arrow. Instead of list, you hit create.
Do I need to drop all of the?
Get rid of the country code. Phone number, phone numbers always split with dash. Equals.
Oh, get rid of the local. Get rid of the local. You can list locals, but you can't
There you go. I should remember this. I created the bash command, bash script to buy phone numbers from me.
Doesn't look like it looks like this one either. Again, thank you for the sup, five months, thank you so much.
Change available to incoming.
Available to incoming.
Yeah, there we go.
So we list the available numbers and create the incoming phone number for ourselves. If you were to go into your Twilio web dashboard, just show this number exists. Under a browser page. Console.
Sorry, I got distracted because I got confused. I forgot that Tony has an alt account called the darta and he was yelling at me and I was trying to understand why. Thank you, Tony, I appreciate it. What am I supposed to do with this phone number?
So we own it and I was going to show you that it exists in our Twilio console.
Yeah. Awesome. So let me hide the auth token and bring this back across and let's go look at the phone number.
Phone numbers. Yeah.
Amazing, look at that. This is the one we brought through the API. And to show this, you don't have to do this with the CLI. We can push this plus button. I want to, and if I wanted to, I could say.
Different numbers of different functionality. Also some of them have requirements.
But the reason it's really cool, you can write scripts to larger numbers and do it much faster.
It's really, really handy. Let's say I was going to ship this as an open source library, anybody that wants to set up a text poll thing, I can write a dash script, hey, you need to log into Twilio and now you're going to get a phone number. That's KRAEL cool. Anyway, if I wanted to get a number, I can go here, choose the number it to be. And that works. That will pick any random number. You can choose it. Looks like I could say I want to do Montana phone number search.
And so, that's. It's a Montana phone number that I could grab one and go. It's really, really nice. And it's a really powerful thing to do.
So what you want to do is now configure. Person messages that number. Right now, it's unconfigured. Nothing would happen. This is where we need to go, the thing we're trying to achieve. Do we want to prompt them, how would we want it to go?
So, I guess well, how does American Idol work? How do those types of game shows work? Do you text a number?
Usually, yeah, text A to, or text B or text C or D.
Yeah, let's let's make it work like that. I think that will be fun. Because then, then it's kind of simplified and the other thing that will be fun is that we can also later extend this app to use a chat command, as well. So we'll be able to do a vote, A, vote B, and that way people can chat can vote, they can text a vote. However you want to play, you can play. Because one thing I'm noticing is that because this is a phone number, if anybody needs to, if they pay for SMS or if they're outside the US, it would be expensive to text this phone number to play.
We don't want to be exclusive. But this is one of those things, it's really, really fun. And depending on your application. If you're running a local event, then you don't need to worry about everybody having local numbers. You're most likely, everybody's going to have a local number.
If you're running an international event, you probably want to provide alternatives that aren't bound to a phone number or you could set up multiple phone numbers. We could grab a phone number from any locale we wanted to grab, right?
Yeah. That's the great thing. They have numbers from nearly every part of the world. I did a five minute demo of Twilio. Where people text me in and I phone everyone back and put them in a group call. I did it on a live stream with 700 people. It was more than 700, I'm pretty sure. I don't know the exact number. It was Hack Quarantine, hacks around the world. I bought numbers in the US, India and a couple of different places and I said everyone phone your respective phone number and then they got into one massive. We hit the limit of the group number.
Which is pretty cool. But I didn't think about that ahead of time.
Cool. So, yeah, if we're going to have people text in a number, then the way we can figure this is we pretty much want to handle incoming. And send a message, your vote was received kind of thing?
Yeah. So this is where we could use the Twilio functions. So Twilio functions is kind of like the functions I use everywhere. The good thing about Twilio functions, all of your Twilio credentials are available inside it if that makes sense.
We could do it in Netify.
I'm thinking ahead to the chat command thing. I think it would be cool. Let's use nullify functions, because I've already got chat commands there and we can show off how to use Twilio SMS in a general node environment without the auto set stuff. If you want to see how Twilio functions work, they are dope.
And we set one up in the, this series where we talked about the Twilio, the video stuff. Let's do it differently this time. Use nullify functions this time. And that way, we can get the Twilio stuff set up, and then in that same function, we should be able to listen for chat commands and fire that same thing from both places. And I think that will be really nice.
If I want to do that, do I need to
Yeah, create a Netify sort of site with functions. We're going to need the site to display our results, eventually. And we're going to use the functions to handle when text messages comes in, SMS messages.
Yeah. So let's do Twilio text to vote like that. And there we go.
So this is like a demo template. It's just a shared header and footer so it's got styles and stuff so we don't have to worry about it looking nice, it'll kind of look nice.
And then, grab this. And let's create get clone, this thing, and we can move into it. And let's open it up and take a look. We'll be able to work in here. It's already configured to run functions for us. So we just need to create a functions directory. And here, what I can also do is, let's see. Let's initialize this as a nullify site. And then, we can set the environment variables there.
And we can leave these. And then, we can open it. All right. So this site is now building. It'll be live in a second. And while we're doing that, I assume that one of the first things we're going to need to do is set some environment variables.
Yep. So the environment variable, you're going to need your auth token. What you can do is use API keys. You need your account and auth token. And what often times you can do, especially when, we're going to need to generate tokens later. So we're going to need an API key and an API token. My brain just froze. Secret.
OK. Here is a token.
What tool do you use to blur out your screen?
This is an extension that Sarah Drasner built. And this is just specifically for environment variables and nullify. Did you say I needed an API key, as well?
We will, yes, we will eventually.
OK. Should I just grab one now and
Let's do that later because then we can sort of add is that to the section on handling the website.
OK. Cool. Yeah. So here's my sid, my token, they're saved. If we go back, we've got a basic site. And now, we are ready to build, ready to build. Ready to do stuff. I've got this running over here, actually, let me use this one. So if we run nullify dev, or actually, I'm only going to run nullify dev to show the environment variables. Here, they're being loaded, right? And then, we're going to need to set up everything else so I can NPM install. And then, while we're doing that, I'm going to create a function. And what should I call this function?
Let's call that SMS.js.
Got it, SMS.js. And that's going to export a handler which will be an async function. And that's going to return status code probably of 200 with a body of some sort. And that's all the boilerplate we need. So that's a nullify function. So next, we need to get the Twilio stuff in that we're going to need. What do I need there?
So what's going to happen is Twilio's going to call this function. So is this available public URL?
It will be, yes.
So what we're going to do is we're going to go back to our phone number and say that when an SMS comes in, make a request to our function.
Going to make sure all of this is hid the token, get this back on screen, and now, I'm going to go to the number. And this number.
So I'm in the configuration voice and fax messaging. When a message comes in, I'm going to send it to nullify functions SMS.
Perfect. Hit save. And then, now, what we're going to do is make sure our function is returning tml. It's like XML. Fancy XML.
OK. Do I need to set a header for the content?
Going to need to change the content type to XML.
I'm not going to lie, I've never done this. Application XML?
Applications, no, it's text. I'm pretty sure it's text xml.
Wow, what an adventure, I've never done this.
Oh, and aliases. So the XML is an alias.
So it should be application, then?
It could be either. I've always used text XML.
Apparently it can be over.
This is the one thing, as I'm going, I learn things I did that I didn't know myself.
This is the rabbit hole of working on the web, right? Is that we're sitting on top of 50 years of history and so, more, like all of the computer science history and the science and everything behind that. It's like decisions that were then abstractions built on that and then, like, improvements and more abstractions. And it's just turtles all the way down. And that's kind of what I like about it. If you want to be a detective, you can go deep, or if you want to get stuff done, you don't have to go deep. That's what I like about this industry. It lets you choose your level of, like, wonk, how much of a software wonk versus someone who gets something done.
Yeah, it's sort of the different moods I get in. Some days I'm going, and especially, if I'm writing a talk or preparing to share content. I go deep inside something. And then, other times, I'm like, what's the fastest way to get this working?
Yeah. 100%. So Tony has a question. Are all of the commands in the CLI already able to be set up in the cloud communication set up?
So auto commands, I'm confused by the question.
I think if I can attempt to reword it and Tony tell me if I'm wrong, I believe the question is, is the, like the console dashboard, everything that we can do in the CLI, we can do in the console.
There's a few things you can also do. There's things you would need the API to do.
Doing the console, but you can do in the CLI because you have access to the API.
And I'm trying to think of anything off the top of my head that you can, can't do in the CLI that you have to do in the console and nothing jumps out at me. Most of the main functionality is available in both.
There may be fringe cases. I'm not going to put money on the vast majority of everything you need you can do with the API, I mean the CLI.
That makes sense. So I have now created this and I'm, I'm assuming that I need to just send back a string of xml.
Yeah, so it has to be a response. So it has to have a response tag with a capital R.
And a response is going to be a message. So we want the response to be a message.
Yeah. And for now, we can put, I received a text or something like that. Make sure we've got that.
I've got to keep it on brand.
I love it. I love it.
So we can get commit that. And we'll say work in progress. Incoming SMS. Let's push.
Message that phone number. So let's give it a test. So I'm in my phone right now. It's this number here. So that's a little hard to see. Need to blow that up.
If you want, if you're in the US or willing to spend money for a test. Zero three eight nine. And send anything you want. And assuming, actually, hold on, let me make sure it's finished deploying before we do this so I don't we're deployed. So try that text. And we should get that back. There's my boop. Impossible for anyone to read that. I've got a boop.
I've done wrong on a stream before, and I'll try to make sure we don't do it. Don't show the phone numbers of the people in the audience texting. Don't.
Don't do that by not clicking messages?
Perfect. Let me actually pull it off screen and I will find mine. And then, I can, let's see.
So what it does is Twilio only holds information about numbers and stuff for 30 days because of GDPR and stuff. It's kind of 30 days and after that. If you haven't taken that data, companies might need it and say this is the numbers we've messaged, then we get rid of it.
Awesome. Yeah, I think I need to, like, I believe what happened is I'm in the process of switching over from an old version of my Twtich bot to a new app I'm building called Stream Blitz so anybody can do this stuff. It's a website that sits over the top of the videos and I insert different videos and stuff. It's a GraphQL subscription. And I think what happened, the old Blitz Bot. At some point, when I was messing with Stream Blitz, I took the blitz bot and rotated it. I assume that's a setting in OBS I selected. Eventually, this will get cleaned up. At some point in the future, I'll learn how to actually, you know, do computers.
So I was going to show the message response. But it's actually not that interesting. And I would have to do photo editing to hide my phone number. I'm not going to do that. But it is very cool. It's, it's really handy. It's really nice that the message just comes in, right? We get that response back, which is awesome.
But what we kind of want to do is be a bit more dynamic, right?
Maybe the first thing we should do is be, like, thank you for voting, your vote was A, B, C or D. Sort of spit out what they said to us?
Yes, let's definitely do that.
So in the Twilio's request to the function, it comes with in the body of the request. You also get the body of the message. The body of the has the body of the message.
Yes. I believe so.
OK. So I'm going to does it get sent as JSON?
OK, and we'll do JSON parse event.body. And that's, let's just do a straight echo. And then, see echo. And this should build nice and fast. I tried to make this demo as quick as possible to build so that it only took a couple seconds between trying things.
So let's see how fast that goes. And then, I'm going to send a new message.
Hold on. Did we use JSON?
I said I did use JSON.
Oh, I'm pretty sure, I think it's encoded.
We're going to find out.
Every time in building stuff with Twilio. I'm always, I'm debugging for ages and then, I'll check my email when I'm tired of getting this wrong. And I see 100, it's always 1, 10 and 100. But it tells me how bad my debugging session went. You've got one error or ten errors or a hundred errors.
Let's see. I think this broke, which you're probably correct. It's form encoded. Let's look at the function response. I'm going to pull this off screen just in case the body has. I don't want the error showing anybody's phone number. Let me check real quick. Unexpected T in JSON. Not giving me back phone numbers. So yeah, we're getting an unexpected T in JSON, which means it is not.
You hackers, you dirty hackers.
Yeah. Position zero. So something, it's not, it's not
Can't parse something.
Correct. So what should I be using instead?
We want to use.
Like query string?
The phone number you're going to be receiving is X formula encoded.
Yeah, so QS should get that. I guess we'll try it. Did you just whisper drum roll?
Yeah. I was so close to, like, answering blitz. But I read the message before I read the username, and I was like, my brain started building a response. And then, I went, the username, no. I'm not falling for that, again.
Excellent. OK. Let's see. This should be just about done here so that's ready. Let's send a text. Do it. Oh, undefined.
That's better, though. It gave us something. What I'm going to do. Is I'm actually going to. Let's just console log the whole event, I think. And let's see, I'm going to console log event.body, that way we can see what's in there. But looks like we're not getting, it's not giving us this. I'm also going to see what happens if I give, what's just the body? Let's get commit.
I love this. Being able to sort of deploying things.
It's like, I cannot imagine. I remember doing stuff like this when I was back when I was working on different deployment platforms. And the amount of effort I would spend making a file change, going over to FTP, dragging and dropping a thing or worse when I had actual CI/CD, I would have to make a change and have to open the pull request and merge my own pull request so it would trigger a CI run. So all of these things. It added friction, right? So being able to just very quickly do the push and have it work is really, really nice.
Now, if I follow in.
I think this is the first time I've ever had a stream where I'm actively texting during the stream. So the body part didn't work, but that's kind of to be expected. So let's see what the log says. Info. So it sent back, so the body is
Do you want to take that off screen?
Yeah, I think it's going to have my phone number. So from zip.
This may sound stupid, but does it use body over capital B?
It probably does. Given the way the rest of this works. Where is the body? Body? Message sid to country from city, SMS status from state. To city. This legitimately doesn't have a message in it.
Yeah. Hold on. Let me pull this over so that we can see what's in it. And then, I'm going to, let me take this off screen for one quick second. I'm going to pull my phone number out.
And just check with me here that I'm not wrong. Oh, no, it's right here.
And it does have a capital there.
OK. So we need body and then, we're going to return body.
That console log, is that going to work?
This console log still works, yeah.
But let's, let's do this instead, actually. Let's console log this. Because that way if something fails, we might get get a little more information.
Oh, actually, you know what I'm going to do.
My body, my body's telling I can't sing, but at least I should get points for effort.
I love it. Thank you. I can't even read that user. Thank you so much for that.
You hackers, dirty hackers.
Did somebody hack? Oh, thank god. I'm so happy to be streaming, again. I took a couple weeks off because it felt uncool to pretend like nothing was going on. But I definitely miss the chat. And especially, like, in quarantine, this is pretty much the extent of my social interactions.
Right. So OK. I'm on the same page as you. Because I love meeting people. Human interaction is one of my favorite things. And suddenly, working from home, it kind of that's actually, I started streaming just because I was, like, I need to talk to people. My handle on everything called chatterbox coder for a very good reason. Talking is my jam.
All right. Where did my let's get this back on screen here. So here is the deploy. We are now sending the body, not the body, which means cue up a text here. Once this finishes. You're already done? Oh, you're already done. OK, we've got an echo. So, it is now, it sent me back what I sent it. Like, it send me the same message. So that is doing what we expected. If you want to give it a try, you can do that.
Again, the phone number, let me just paste the phone number in here. Feel free to just send a text to that number if you want to try it out where it's at now. So the next thing, then, is we want to figure out how we're going to, like, do stuff with this. Right?
So the next thing we kind of need to do, like, this is going to run individually every single time that someone sends in a message. We need to have an external body, not body, I should not use the word body, used it too many times.
Bodies on bodies.
External thing to just hold all the information that we've got. And so it's very interesting. What happens at Twilio. And I keep going back to Twilio, but we often get side products, that we build a thing and we realize everyone else is using our product is trying to build this thing we've already built. So we're like, well, why don't we just let people use that? So we have a thing called Twilio sync.
And it was originally built for our chat platform. So if you had down to scroll towards the bottom, you should see sync. And where it is, with programmable chat, you need to make sure all of the different clients all have the latest version of the chat history. So every time someone
Writes a chat, it needs to go and update every single person, right?
And basically, that of itself is useful. It's not limited to chat. You could use that, for example, in a game. If you're playing a turn based game and you need every other sort of game session to be updated every time someone makes move and things like that.
You can create a sync service. So if you hit services.
And you already have a default service.
I have no idea. I created that today.
Is that today?
That's interesting. I don't know how that happened.
I don't know.
If you click on default service. So what happens is, and the reason, every single account has a default service, has one service. You can give it a name. And what you do is within this service, different types of, should we say data structures, so you can have documents, maps, a document is just a JSON, like object. And what will happen is every time you update that, hey, Laila.
Thank you so much. Welcome, everybody. We are building a text to play like voting app right now. So Nathaniel worked at Twilio, and he's teaching us how that works. But yeah, thank you all for stopping by. This is going to be great. Copper Beardy, I love that your emotes is your own face. I need to do that. That's funny. So we were talking about
Talking about Twilio Sync. And what you can do is you can have, documents and documents just like a JSON object that gets updated everywhere. You can have, this is what people use for chat. This is a list of JSON objects. So every time you add, it gets to the bottom of the list, which kind of makes sense.
And then you also have maps which is unordered list. What I'm thinking, create a sync document. Every single time somebody texts our number. We go and update it with add one to whatever. The second thing we need to do, we need to create a sync document within our service.
Again, that's within this service?
Yeah, within that service. The reason you use different services, on one Twilio account, you might have different applications that do different things. You don't necessarily want them to share the space.
So Laila was working with the Twilio Studio. What were you building today? And the boops are open source, if you want. I built a code pen somewhere. If I can find where is my code pen?
Cloud flare, I'm not a bot. Here is all of the code you would need to do some boops. So that's the code for the boops if you ever want to play with that. I triggered the boop drop. And we broke gravity and that's why they fall to the side now.
Inception, it's inception. We are in a stream within a stream within a stream.
You know what would actually be really fun and I should do on another stream is I should, I should make it possible for the chat to set the angle of gravity. So that the boops fall to different sides of the screen depending on what the settings are. That would be really fun. So I used TMI.js. I think I have this online, actually. LWJ scenes. Yeah. So this is all of the, so here's the boop drop. And this is not super interesting. But what is interesting is the hook, use boop. This is all getting cleaned up, by the way, it's going to be usable by humans. But right now, all the matter stuff is down in here. And then, I have a hook called "use chat" that uses TMI.js to pull in the chat. And that's what triggers, whenever I get a chat, I look for whether or not it's the boopemoji. I drop it from the top of the screen. This is fun if you want to play with it.
All right. We've got to focus up or we're going to run out of time. Do I need to set a web hook or anything?
No. It exists. So now, we go back to our nullify function.
And the code we're going to need. So we've already got our account set and auth token, right?
Yes. We have those in, let's see, process.n.Twilio account sid. And Twilio auth token.
Cool. So the first thing that we need to do is create a new document and create a new document, I'm going to quickly
Thank you for the sub in the new code.
We don't have Twilio available as an NPM package, yet do we have?
We haven't added it, no.
We do need to add it. That's my bad.
Is it Twilio?
And then, while we're letting that install, I'm going to Twilio.
And you can put an extra bracket right afterwards and have it taking your account sid comma auth token immediately.
Oh, that's cool. So just straight up like this?
That is very handy.
And then, if you come underneath, we would like to, we need to create a document. So the way we would do it is we'd go Twilio.sync.
Services. And this is going to take in, no, it's going to yeah, and that's going to be the sid of the
Thank you, have a good day.
Yes, that had a sid.
Pop that in there.
Should I, you know what, I'm going to hard code this. But probably we would want to do something different.
In production codes, you wouldn't hard code it.
And then, you would go documents.create.
And we're going to run this once and take the code out, right?
.create. And we could give it a name. We can give it a unique name.
Is it just a string? Or an object?
It's just a string.
And then, .create. And then, it is a promise, so you could go, like, .den.
It autocompleted that.
Nice. Wait. I didn't know that was a thing.
I didn't know that was a thing either. That was Chad, did I pass out for a minute and write code I forgot about? Or did VSCode do that? I feel like VSCode just did that.
What plugin is this?
That's nice. It looks like it picked up some autocomplete, though, because when I do the Twilio stuff, it does do some autocompletion.
It might be just be VSCode knows that returns a promise and just kind of handled it.
I was about to say, this would have been the right time to put the hackers thing up on the screen.
It really was.
That would have been perfect.
I need a new one. I have a new. Does the hackers one have, did I update it? I think I might have done
You hackers, dirty hackers.
I have new animated where I take off my glasses and put on sunglasses. I need to get that updated because that one makes me smile. So let's do, I've created this. How do I put, like, how do I structure it?
So it's just a JSON object.
But do I put, do I do it from here?
We don't need to structure it yet. We need to update it now. So you would update it and make sure it's the same structure each time. So this is faux free form. Which is good and bad. You need to build your application to make sure it is consistent.
Yes, Vinny, you missed the part where I exposed my API keys. I'm getting so much better.
He did a really good job.
I have not in like three episodes.
So this will return a sid that we need to catch.
This returns a sid?
A document. But we don't need this because we know the document's unique name. If we make sure LWJ text to .result, we must remember that, we'll use it later. So we want this code to run once so we can create our document. And then, we would actually like to put stuff up.
So, let's just, yeah, whatever, we can do this. We'll do get commit setup Twilio sync service. Push. And is this going to collide. If it runs twice, does it fail? Or override?
I've never ran it twice. So I don't know off the top of my head.
OK. Well, chat's here and they're ready to cause chaos. CLW thinks it won't fail, which that also seems like something.
I don't think it fails, I think it will throw up an error rather than fail.
Sure, sure, sure. OK. Get build. Do the thing. Live. All right. Sending it through the thing. And my response. Did you get your response?
I did not get a response.
An error. Do you mind heading over to Twilio, as well?
Error mode. .create is not a function. Interesting. Oh, I wonder if it did, so check this out. It did like a weird .create .create. Oh, wait, what did we do?
We didn't do that.
Maybe because it autocompleted and it still hit
Yeah, I think I did something silly. So is this correct, then?
That is correct.
OK. Let's try that one more time. Actually, it should be created. Can I validate?
You should be able to list. I'm actually, this is the, this is one thing. So sync is still in beta. And you can't actually see. If you go to usage.
Usage. Because it looks like it did the execution and tried to call create on the response.
I doubt it. Just because.
Made it all the way.
Yeah. So sync is still in beta, but it's nearly done. And they are going to, like, I'm pretty sure they're going to add more visibility in the console.
The number of get commit messages are, this time this will work.
This will work.
That was me. Thank you.
That was so good. That was, like, on point.
OK. So that's up
You hackers, you, you dirty hackers.
OK. So I want to look here. I want to look at Twilio text to vote, building, should be basically done. Which means, I'm going to send another text. Oh, I jumped the gun. Hold on now. Hold on now. There we go. Do the thing. OK. So that sent back what I expected it to send back. And we still don't see any usage. That's interesting. Let's see. All right. So we've got about 20 minutes here.
Can we quickly head over to your terminal where you had the Twilio CLI?
Yeah, I'm here. Here's the Twilio CLI.
If you go Twilio, API: Sync: V1: Services: Documents:list. But then, you've also got to put in a flag service sid app. There you go.
I mean, at least it gives a helpful message. So let's get that service. Sid.
We have full. That's fine. But they don't have a unique name.
So we messed something up in this call.
You messed up. When we go create, rather than using that create objects. And then, put unique name.
That's my bad, yeah. And then, we put in that.
So this is where the CLI can sometimes be handy, as well. I'm going to try and figure out what the command is to actually just create one from the CLI.
That would be faster.
Well, at this point, we're basically there. So we'll see, if this one doesn't work, yeah, then that's probably the right thing to do. And while you're doing that, I forgot to do a shout out to sponsors today. We've got live captioning, LWJ.dev/live and brought to us by auth 0 Sanity, trying to make the show more accessible. That's a very cool thing that I very much appreciate.
So yeah, go check them out.
Yes, they are. So, OK, so that worked. I'm going to run the list command. There we go. Unique name.
I'm going to grab, yeah, grab that.
Yeah, let's do it. So now, that we've got this, we should be able to do different things, right?
Yeah, rather than create, you would like to update.
Yeah. And what we want to do is, I'm going to quickly grab that. So within update, you're going to, rather than have a unique name, you're going to so right after documents. So documents.. so you need to put brackets in there. Do you have brackets? Or parentheses and then give it the sid that we just listed.
Yeah. Perfect. And rather than unique name, we can put in what you want. Now we need to decide what we're voting for.
Let's do this. We are going to vote for we're going to vote for whether or not hot dogs or sandwiches. It's going to be a yes or no vote. So a yes or no. And so, I guess.
So we want to count the yeses and the nos.
Yes. It would be, like can we just do that simple?
We could do that. Is there a way you would prefer to do that?
Right now, we're going to update what we're going to need to do is fetch. Then update.
Right. Right. So this will be our object structure?
We're going to get the body back, right?
And so, we're going to say vote and we'll say if content.body match, yes and we'll make it case insensitive. OK. So let's let's just test it. I'll do this, my favorite way to test which is to go into the console and do something like this. Holy buckets, yes. And then, we can do a match. And we'll say, yes insensitive. And that comes back like this. And if it's a no, we get no. So we can do that. That will be a test. So then, we will set the yes or no.
Basically, any text that contains the word yes will count as a yes. Anything else will count as a no, and then, we can basically increment that value.
So then, we need to fetch this thing.
So it's just like the promise. It's just exactly the same, but instead of update, you put fetch. And then, it will return rather than return that, yep. It will return the entire document. When I say the entire document, it also has, yeah. Document results, yeah.
And so, then.
What you're going to want are results.data. And so I would go, yeah. That's what I would do. OK.
So then, what we can do is we can say Twilio sync, this is where we need the, I'm going to actually copy this whole thing.
So let's bring this down here. And we don't need the result of this one. And instead, we're going to do an update of.
What we're going to also need to do, data is going to have data.yes and data.no. So what we're going to do is if, like, we want to get data.yes and add one, we want to get data.no. Dependent on what they say, dependent on what their vote is.
Yeah. So, tell me if I'm wrong here, but here's what I was thinking of doing. I'm basically going to take the data.vote plus one as
And so, then, when we update, we can say new data. And that should give us, like, we'll keep the old number, and then, we'll just grab whatever key they voted for and increment its value by one. And then, set that. And I think that should give us an actual thing, right?
And then, we can also say you voted on sandwiches. OK. This is good. Let's ship it. Do you see anything I need to do still?
All right. Let's give this a shot. Get commit. And we're going to say feature.
And you can send the text.
OK. Let's go over and watch this deploy. And
I definitely have answers that don't match. This is the classic developer. Oh, let's show this person that can work this. And this is the same as me. We are like, oh, how can we break this? How can we
I will break this.
I will break this. It's the mission of developers. We claim to have these like really outstanding, like, motivations and we want to build and make cool things, but really, we like breaking other people's code. Speaking for myself.
I think I got an error here. So let's go figure out what it is. Error, expected at least one optional parameter, but none were provided. Data TTL, Twilio. Let's go look at this.
When we hit update. I know exactly what's happened.
Did I miss a piece?
Yeah, we missed a piece. When we hit update, we need to update data. So when we hit update, so we go data:new data. So put that in a new object.
Oh, I understand. Oh, so like this?
That was my bad, I should have seen that.
He said, I don't need to break other people's code, I break my own code. Oh, gosh.
That feels right. That's about how I feel about it. Let's go back. Deploys. And this is going to happen. It's going to work. Let me try to send a no vote. You voted no on sandwiches, let's try a yes vote. You voted yes on sandwiches. OK.
So if you head over to the CLI, we can actually, like, fetch the resource.
Yes. Let's do it.
Open that. If you go up, rather than list, you want fetch. You still want that service.
Oh. No worries. I have it over here. We're all good. Here's the service sid. Do I need the
I'm pretty sure you need the document sid, I don't know what the flag is.
It'll tell us.
Yeah, that makes sense.
This is the good thing about building, I can tell you when things are not working properly. The fact that we knew immediately that it's going to tell us sid.
OK. It gave us the unique name, the revision but not
Put a flag on it dash O JSON, so we can get a JSON object.
O, like this?
Here we go. If we go up to data. Seven yeses. Seven nos.
You contain multitudes. I expected much more unanimity there. I voted yes on sandwiches. Well, yeah, Robert, listen, you've got to make this, got to make this work. OK.
Is it, are we 100%. In my head, I'm like, that is, I rarely ever seen a chat where everyone exactly alike on both sides.
No, they rallied.
Incremented both of them at the same time. There's no, like a chat agree on something equally. I'm joking.
If you want to vote, you can text a vote of yes or no to this phone number. So chat, tell us, is a hot dog a sandwich? Cereal is a soup. If you're in the US, that will be a text message. If you're not in the US, not today, obviously, but we will build in the future to use a chat command to vote. But the ultimate goal in something that we'll have to do on another stream is we want to be able to display these as a chart that will update so I can actually put the poll right on the screen, which will be really fun. Maybe put it down in this area somewhere so you can see the chat moving up and down.
How much time do we have?
We have, like, seven minutes.
Oh. It's what happened last time. We got the basic thing working and we're laughing too much, having so much fun. So the last bit that we need to do is sort of create, for now we can create a web page which will show the results live.
Yes, and we have that, we have everything that we need here. So we just need to pull this in. So let's just, we can just kind of, oh, how are we going to do this?
So what we're going to need to do is we're going to bring in the Twilio sync client. And I'm going to quickly
And is that, is that something I can load from the CDN? I don't have NPM support.
I'm trying to remember precisely where that is.
I had it on earlier.
That's what we want. To scroll down. So if you just type in sync.
So show me.
Oh, here we go. Quick start.
OK. I was wrong.
I'm going to grab that from here.
You need an API key and an API secret. The reason, you need to create tokens. Imagine you had your users and different users were being able to submit information to this document. And get information from this document, you would need some sort
We can't just read it without. What I'm worried about, we can't put it on the client side because it's a secret. And so, we'd have to write some kind of a weird round robin function thing that I know we don't have time for. Is there a way to do read only on this?
Not that I know of.
Crap. We might have to do this on another episode.
No, no. It's totally fine. But it gives me an excuse to have you back on the show. It's always a blast. I get a bunch of laughs. Here's what we're going to do. We're going to schedule a part 2, where we're going to take this episode, what we did today, we're going to pick it back up and we will do a follow up where we'll visualize it, we'll play and if we have time, we might be able to do the chat part. We'll get as far as we can. And the other thing that will be fun, figuring out how will we change this document when we change the question?
That's another thing we're going to have to do, is figure out how to make it arbitrary.
The cool thing is, you could probably set something up so you could have some logic going. So depending on
Oh, my god, the corgis are sideways.
Oh, my god. I can't even handle it. That is
Your chat is hilarious. I love this chat.
That was amazing. All right. So that was a special blend of chaos, I think, to send us off. Really? You're killing me. You are absolutely killing me. The corgi limit is 20. I rewrote the corgi stampede, which we'll roll out whenever I have time to work on and it's going to be a higher limit because there's so many of you. Really? You're going right at it. Cool, thanks, Jordan.
This is super fun. I'm really looking forward to tackling the part 2 on this. We'll be able to do a bunch of fun stuff with configuration. We'll figure out how we can set up and tear down polls on the fly. And we'll figure out how to actually display it on screen, which I think will be an absolute blast all the way around.
Going into the Twilio.
For anybody who, if they want to follow on, Nathaniel, where would you recommend people go from here?
If you would like to follow me, my name's on Twitter and Twtich, chatterboxcoder. I stream on Tuesdays, the baby developer show, where I talk to people about their journeys. If you want learn mure about Twilio, you should check out Twilio TV also on Twtich and hosts a variety of streamers. I know some of the streamers in the chat. And if you build cool stuff with Twilio and you can learn more about the amazing products that you do. So definitely check it out. A show I usually do every Wednesday, I'm going to be restarting from next Wednesday is Twilio questions, answers and tea. I'm British, I love tea. And I sit down with different people in the company. We talk about the new products they're making and the stuff they're working on.
Sometimes, it's technical, sometimes, we talk about what is life like as a developer in Twilio. All sorts of different things and content at Twilio TV. Give us a follow, we love the follows.
Yeah, definitely go. This is a fun show. Nathaniel, this stream in general is fun to watch. Go check that out for sure. And we will figure, we'll coordinate behind the scenes, we're going to figure out how we're going to do this followup episode. We'll do it sooner rather than later. My schedule is amazing, like I am the best possible problems right now. So many amazing things coming up.
Joel Hooks coming on the show. This is the mind behind Egghead or one of the minds. And we're going to build that ridiculous app Secret Sandwich, which is going to be fun. And yeah, Lucky Number 7 is coming on, Matt Howard coming on. This is space design. He does the flagship Nike store in New York. He's helped design that, he designs retail spaces and stuff, that's going to be a cool episode. A big departure from our coding content in a fascinating way. Benjamin Lang going to teach us actions, Sarah Drasner is coming on, that's going to be, bookmark that one. That's going to be unbelievable.
Alex Banks is going to come on, David Easton, this list goes on and on and on. So go and check the schedule. Add one to your calendar. If you use this Google calendar, it will automatically add them to your Google calendar so you can see them and make sure you never miss an episode. Nathaniel, thank you so, so much for coming on. I appreciate it. And thank you one more time to our sponsors. All making it possible to have the incredible White Coat Captioning doing live captions for us on the show. Y'all are amazing. We will see you next time. Chad, stay tuned, we're going to raid. Nathaniel, see you next time.