- Hi there, I'm Craig,
and I'm a developer. In this course, we are going to explore the wonderful world of webhooks. Understanding the
concepts behind webhooks, will open up a new and powerful
world of possibilities, for your projects and your applications. There are infinite
opportunities available for you to connect applications that
you know and love together, to create new experiences
for both you and your users. Now, in order for you to get
the most out of this course, I'd love it if you had
a basic understanding of how to access web-based APIs. Now, if you don't yet, no worries. I've attached to this
video, some teacher's notes. I've listed some ways for you
to gain that experience there. Now, even if you've already
met the prerequisites, can you please take a minute
and locate the teacher's notes? Throughout the course,
I'm gonna refer to them. In those notes, I'll drop
additional information, and share places where
you can learn more about what we're chatting about. I'll also use those notes to
keep you updated on anything that might've changed from, my right now, when I'm
filming this course, to your right now, whenever you're watching
this in the future. I hope things are going
good for you in the future. Well, while we'll talking
about your future, let's chat a bit about what you
can expect from this course. We're gonna first talk about the high-level concepts of webhooks. Where they come from, when and
why you might wanna use them, and I'll walk you through
some inspiring solutions that you can build without
writing any code whatsoever. You're gonna love it. Pretty sure you're gonna get hooked, and after you get webhooked, we'll move from a no-code solution, to explore some more low-code solutions. We're gonna explore events
that GitHub sends out, when activity happens on their site. Now, no worries, if you haven't
had any previous experience with the code-sharing site, GitHub. We'll start from the very beginning, and get you up and running quickly. We'll also then spin up
a serverless function, using a free platform named, Netlify, and we'll handle or do something with, the event data that comes from GitHub. If you haven't used
serverless technology before, again, don't fret. We'll walk through what that means, and how to take advantage of its power. Now, all the code in this course, we'll walk through together. You'll have access to all
of the completed code. After we've got a good
grasp on the basics, we'll make use webhooks to build an entire telephone-based application. We'll build, from start to finish, an entire idea capturing and
text transcription service. The application will lean completely on webhooks for workflow management. All done with, shockingly
few lines of code. This course it's going to
deal with consuming events, passed through our webhooks. Now, that is to say, we
won't be writing code that sends information
to register webhooks. Check the teacher's notes, if you're interested
in learning more about how to send webhook events. I am super excited to get
started with this course, but there's just one more thing that I'd like to talk
about with future you. If at any time you need
me to pause or slow down, remember you're in a video-based course, take advantage of that. I am more than happy to repeat myself, if you miss something. Speed me up, slow me down,
flip on the closed captions, make yourself at home. These days, I know I've
gotten pretty bad about the way that I consume video content. I just watch and watch,
and then I watch some more. Well, it turns out that
education doesn't really work too well with bingeing like that. If you feel like you're
starting to zone out, like I did through the
endless seasons of "Survivor," it's time for a break, and
I'm not here to make friends. I've put some deliberate
stopping points in this course, and I'll do my best to
remind you to take a break. Breaks are important, they're super critical for your learning. You need to let things sink in, and I want you to get the
most out of our time together. Whew, there we go. We got all that housekeeping
stuff all covered. I'm sure you were starting
to get like my kids do on a long drive and they're
like, Dad, are we there yet? Actually, that's a pretty good example for where a webhook works wonderfully. My kids continually ask
me that question over and over again, are we there yet? They keep making that request,
the same one, over and over, polling me directly to see if we've arrived at our destination. Now, typically, my response is, I'll tell you when we get there. More or less, what I'm promising
is that when we get there, I will broadcast our arrival status. When that approach works, like when my kids actually decide to subscribe to my status updates, I can tell you that it makes things a lot easier on the whole car. I don't get overloaded and they can relax. They just sit there
and wait for my update, so much more efficient. I guess what I'm attempting
to broadcast to you now is, we're here, we've arrived
at the start of the course. Now, I think the best place
to start our journey is to explore a concept often present in application development, events. Let's get started. An event, in code, is a
defined action or occurrence. Now, these events are
typically exposed to us, software developers, so
that we can write code that runs specifically when one of these actions
or occurrences happen. The first type of event
that I'd like to talk about is one that is caused by the
user of your application. Let's think about a button on a webpage. This button will trigger an event when it is clicked by an user. You can optionally write
some code that will run, and only run when that event occurs. You do this by adding or
registering what is known as an event listener. You write code, also
referred to as a handler, used to handle the specific event. In this case, click, this code will only run
when that event happens. This is called, event-driven programming. In this example, it's used to empower you to not have to write code
that continually checks to see if the button is being pressed. Just like the kids in the car, it isn't very efficient for
you to write code asking, hey, button, are you clicked yet? Are you clicked yet? Now, how 'bout now, are you clicked? The click event is just one of many events that webpages allow for listening to. Check the teacher's notes for more browser-based event examples. Similar in concept to
a user-generated event, is what is known as a lifecycle event. Lifecycle events are
typically exposed to us via application libraries or frameworks. You can think of application
libraries and frameworks as tools that help us rapidly
develop our applications. These libraries do this by
providing repeatable ways for us to write our applications. For example, these libraries
allow us developers to customize various
parts of the application, at specific times, in specific contexts. They allow us to hook into
specific lifecycle events. For instance, when you're building a web application these days,
you're almost certainly using a front-end application library. One of the main benefits
that these libraries give you is the ability to write code
for only your specific needs. A great example is you can write code once your component has
been loaded on the screen. This load is a lifecycle event. Usually this looks something
like, has been loaded. What's happening here is what is known as, inversion of control. Now, this is because the
control is being handed to you, the developer, from the application, at exactly the right time. The library does its magic,
it prepares your component. It then renders it out to the screen, and when it's loaded on the page, it calls the code that you wired up to your has-been-loaded hook, and that abstraction is super nice. You don't call the function yourself. The library actually calls
your function when it's ready. This inversion of control pattern
is also often referred to, as the Hollywood principle. In Hollywood, casting directors usually tell the person auditioning, don't call us, we'll call you. Now, this is because if they didn't, the actor would just keep calling them. Yeah, I was just in there auditioning. I pretty sure I got the
part, I did a really good. Weird, they hung up, I
guess I'll call back. No, I was the older guy. I was just wondering when should I come in for my wardrobe fitting, hello? Weird they disconnected, I
guess I'll try that again. Again, like my kids, these actors are totally going
to overload these directors with their needy questions. If they were allowed to call the director and check for their approval,
they'd do it all the time. That Hollywood-principle abstraction, allows the actor to not need to understand the entire process that Hollywood directors
are going through. The directors do whatever
it is that directors do. I think it involves tall
chairs, and megaphones, and snacks, definitely snacks. The point is, only when the
directors make their decision, do they call to inform the actor. These patterns of event
handlers and lifecycle hooks have really proven useful
in helping developers to build extensible applications. The good news is, that this powerful abstraction
can also span across entirely different
applications over the internet, by using what is known
as, ta-da, a webhook. Now, that we've got a
light understanding of the basics of event handlers and hooks, let's run through a quick
refresher of how to use an API. Have you heard of IOT,
the internet of things? Well, this here is a thing. Well, not this adorable/weird
dog lamp thing, but the actual light bulb itself, it's what is known as a smart bulb. Now, I've got an app on my phone, which lets me turn on the
light, pretty cool, right? I mean, don't get me wrong. A plain old light bulb is pretty amazing when you think about it. When I turn on the light switch, it allows power to come to
the bulb and it lights up. That's cool, but that's me
doing it, I'm turning it on. In reality, it's not
much different with me using an application on my phone, is it? I'm telling it to turn on. I can also even change the color, but even that, I'm saying
to make the light green, and I'm telling it to do it when I click. Now, what makes these
light bulbs really shine? That's a dad joke, I tend to
do that, sorry about that one. What makes these light bulbs really smart, is that they can be
controlled by external events. Like for instance, I can make it so the
bulb turns on at sundown, I can even set up a schedule
so that it gets darker the closer it comes to my
bedtime, making me feel sleepier, because my lights are outsmarting me. In fact, you've probably seen it. There's a whole industry
around smart homes. So many products, all sorts
revolving around the house, being smarter than what's
going on around it. Now, the industry saw incredible growth over the past couple of years. Now, the way this
particular light bulb works, is that I define a schedule
of how I want it to behave. The light bulb isn't sitting
there asking my schedule over and over again, if
it's time to turn on. There's an external
program that's running, and when my defined time occurs, it sends the request
to the bulb to turn on. It's almost as if the sun
said to my light bulb, don't call us kid, we'll call you. At sunset, turn on the lights, and it does just like I did
when I clicked my phone. It sends the same message to
the light bulb to turn on, and in fact, in this particular example, it quite literally is as if
I did it using the phone. This light bulb is actually
connected to the internet with an exposed API. I can control it via an
API from my computer here. This here is Postman, if you haven't seen this tool before, you should totally check it out. I absolutely love it for exploring APIs. Now, the API that I'm exploring
here is from LIFX or LI-FX, the company that produces my light bulb. Now, you'll see here that
I can change the values, and you'll notice here that it's a PUT. PUTs can be used to explain changing a particular property of the resource, and not replacing all of them. In this case, I'm gonna
send a PUT request, so I'm gonna send a PUT
request to my light. This API uses a bearer
token to authenticate, and I've got that all set up. You can see here that I am
changing the color to red. Now, I'm gonna send a PUT
request to this specific bulb. I'm gonna click this here, and boom, it's red and
that's pretty cool, isn't it? I can use this code to
turn this light off and on. We already know that
just letting this light turn off and on, with regards to the sun, has made it labeled smart. When the sun goes down, turn on. Sure, that's pretty smart, but I bet us being able
to control it via code might make this thing labeled a genius. I mean, if you think about it, it's like when anything,
like anything at all, that I can dream up happens, turn it on. Even better, we saw that
we can change the color. I can make this turn green
when I have a new email, or flash different colors, when someone comments on a YouTube video. Or, I'm sure if I was into sports, I bet I would love if this
blinked my team's colors when they scored a
point, go, team, sports! What if I use this for an on-air light, for like when I was in a video conference, so my kids knew not to
come barging in on my call? They'd see this, "Rudolph the Red-Nosed"
dog lamp-thing was on, and they'd know that I was on a call. When it was done, I could turn it off. Genius, I tell you, genius. Now, whoa, I actually
need that like right now, but wait a second. Would that mean that I'd
have to write a program that just sat there and
checked all those situations? Like, keep checking the sports scores, and keep checking my email inbox? Like for that video call
example, if I think about it, what it feels like to me, is that I'd have to write
some code to continually check and see if I was on a video call. It doesn't feel very
efficient at all, does it? It fact that feels an awful
lot like my kids asking if we were there yet? Ooh, but what if a video call starting was considered an event? What if I was able to write some code to handle that video-call-started event, I'd be able to, in that handling
code, turn on the light, just like we did in the code. I guess that would mean I'd
have to write some sort of, plug-in for my video
conferencing software, if I wanted to share it? I'd have to have everybody in the world install some software if
they wanted to use it. Yuck, wouldn't it be nice
if somehow that event could trigger outside of
the application to anyone, like over the internet. This is my friend, is where
webhooks come into play. Chances are your video
conferencing provider allows you to listen and handle events using webhooks. That solution basically already exists. We'll look at webhooks like
that one, here in a bit, but do you see how if that event was sent across the internet, I wouldn't need to write
code to continually pull to see if I was in a meeting. I can just wait for the video-conference-started notification. Now, my video conferencing provider says, don't call me kid, I'll call you, and our handler just
says, turn on the light. It only runs when our provider says, psst, hey kid, a video conference started. Now, I hope that you just had one of those light bulb moments. I mean that quite
literally and figuratively, like the type above your head. I hope that thing just turned on. I'd like to ask you to
take a little break now. I'd like this to sink in for you, and one way to help this all make sense, is for you to pause the video, and think about what we just saw. Can I get you to come up with three ideas of what you might want to do
if you owned the smart bulb. Everyone has different needs, and remember quite literally
anything could trigger it, could make a change colors. Now, if you're having
trouble coming up with ideas, check the notes. Really, I want you to
let your mind wander. What would you like to have happen to make this light turn on? It can literally anything
you can dream up. Let's take a break,
and when you come back, I'll share some tools that will give you a lot of inspiration. I'm thinking you'll be
pleasantly surprised. You might even be able to achieve what you dreamed up with
just a couple of clicks. See you in a bit. (mellow electronic music) Before the break, I asked you to come up with some ideas to make this smart light bulb,
even smarter, how'd it go? Did ideas just flow out of your mind? Sometimes I find that
when I'm told to dream up anything at all, suddenly I can't. I have ideas pop in my mind all the time, but the second you asked
me to come up with one, like right on the spot,
my mind goes blank. And, that's a bummer, especially when you're trying
to learn a new technology you wanna put into practice, but you have no real idea where to start. If that just happened to you, no worries. I kind of expected it would happen. I've got a solution for
that lack-of-ideas problem, and we'll get to that here in a second. To get there first though, let's talk about a growing
movement called, no code. Don't worry, it's not a
movement to abolish coders. No code is the concept that
you can, and often should, build applications without
actually writing any code. You're given building blocks
and you snap them together. The concept is that the
applications we build are similar enough that
they can be broken down into reusable parts and snapped together into new formations to
build new applications. It's wonderful for
prototyping, and frankly, sometimes you can build exactly
what you were trying to do without writing a single line
of code, like no code at all. I'm talking about some
super impressive stuff. E-commerce sites and integrations
with third party APIs, Check the notes, if you're interested in
diving deeper into this. One of my favorite no-code sites has been around for a long time. Even before the no-code movement took off, it's called, IFTTT, which
stands for, If This Then That. It's a no-code solution for exactly what we've been leading up to. It's an event handler for the internet. If this happens, then do something, and there are a smattering of options that they call, services. These are services that
expose events that can happen. There are a bunch of them,
from your location changed, to it's snowing, to the sun is setting. You'll also notice that
there are other services here that are web specific. There's an email service
that exposes events, like new email received. You define the service that you wanna use, and you choose the specific event. If this, and now, you choose what happens when
that event occurs, then that. These are called, service actions, and there are a different
set of services here that allow you to do different things. For instance, the company that makes this light bulb I was using,
was called, LIFX or L-I-F-X. They provide an action service, and it exposes a bunch of things that I can do with my light
bulb, like change the color. Because, I've linked my accounts already, I can choose which of my
light bulbs, what color, and many other things. Combining the service with
an action, like a whole, if-this-then-that combo, is
called, an applet, cool, right? I'm pretty sure that you could
build a couple of applets to create your own ideas,
with just a couple of clicks, and definitely no code. I think that this #nocodemovement
might be onto something, it's #nojoke. But, now though, what about the situation that we had where you didn't have an idea? Well, this is awesome, and this is a developer
hack that keeps on giving. Sample applications are a
wonderful way to get inspired, and guess what? These applets are shareable. In fact, if you up here to
explore, you'll get suggestions, but you can also type
what you're looking for. I asked you to come up
with ideas about lights, so let's type that, lights. Let's see all the applets
surrounding lights, so here we have toggle
lights, blink your lights, that's nice, disco party for
hue lights, that's wonderful. Alexa, turn on the lights. Sorry, if I just triggered
your Alexa at home, if you have one. Turn on my lights blink,
when your doorbell rings, these are great. All sorts of things. Now, I can enable one of
these for my own account, and when it comes up, it asks
for my specific configuration. Now, you probably noticed that there were different types of smart
bulbs in there, in that list, but that doesn't mean that
you can't take that idea and make it work for your own-use case. Can you see the power in that? Now, this is actually
a pretty common pattern in developing software. You take the base code,
and you make a copy of it, and you make your changes. This is called, forking,
you fork your new copy. Remember, this is just one of
many no-code automation tools. If you're enjoying this way of thinking, I encourage you to look at Zapier. They provide similar building blocks to the complete same sort of,
if this happens, then do that. You wire up services to
create what they call, Zaps. It's super fun, and I highly
recommend exploring here too. There are lots of inspiring
ideas to be found. Zapier makes you happier,
I just love that. These no-code automation
tools go a long way in making just about anything possible. But, as you can imagine, there are gonna be cases when you're gonna wanna have more control. You're gonna wanna
write some specific code that the action doesn't provide. I'm pretty sure that's
why you're here, in fact. You want to use a
webhook, so let's do that. Let's explore how that works
right after a quick break. I'd love to give you
some more time to explore these no-code tools. I really want you to think
about these applets or Zaps, as an abstraction of
the power of webhooks. Oh, one thing that might help, if you wanna just play
around with some actions, there's a smartphone app and
it lets you install buttons on your home screen, just
like this, like look here. I've wired it up, an IFTTT
button so that when I click it, it turns on the red light. That way Roxanne doesn't have
to do it, that was a bad one. Don't call the joke police on me. I hope that one didn't sting too much. (cymbals crashing) Check the teacher's notes for
more exploration guidance, and please let me know
what you come up with. See you in a bit, and when you come back, we'll explore how to capture information sent from a webhook. I think in order to get
the clearest picture of how webhooks work, it will help if we
travel way back to 2007. It was a time of wearing
double polo shirts, so you could pop your collar, twice. People wore Ugg boots with shorts, and Justin Timberlake was actively trying to bring "SexyBack," and web forms were still a thing. It was a simpler time. To gather information from
a user on your website, you'd write an HTML form and
you'd put a method on it of, POST, and in the action, you'd
put the name of the script. It's important to remember,
that the web is stateless. Once this request to generate the page that the form lives on,
the web server job is done. The GET request is over. Your user would fill out the HTML form with the named fields and then
they'd click a submit button. What the browser does
for you in this case, is it takes all the values
that were entered in the form, and it makes a brand new HTTP request to the URL that you specified
in the action attribute. That POST request contains the data that the user entered in an encoded way. As a developer, you would write a request
handler on your website to capture the information
from this request, and then you'd act on it. Again, your browser is making
a request to your server. Way back in 2007, a developer by the name of Jeff Lindsay, made a proposal to use an
existing idea already very present in software design patterns. He proposed to use the hook
model that we talked about, but instead of locally, he suggested to do it over the internet, and he called it, a webhook. Jeff realized that it would
be fairly straightforward for web developers who
were already very familiar with processing form data
submitted via a POST request. What this approach would
feel like to developers, is just another form submission. In this case, instead of the
user submitting the form, a third party could submit the data. The handler could be written the same way the developer already knows. The information is pushed to the handler, in that same familiar way, to the developer and everyone wins. In order for this to work, the third-party application
needs to be informed from the developer where they
should post their information. You know, the URL where
that handler lives. And then, when the
third-party event happens, it posts the information
about the event to that URL. (icon exploding) That app is definitely embracing the Hollywood principle, right? Don't call us, we'll call you. It took off, for all the reasons that
event-based programming wins. It's, of course, way
more efficient to receive a POST request, than
continuously polling an API, checking for a change. Instead of, are we there
yet, are we there yet? Via an API, the POST
request sends, we're here! That was 2007, webhooks
are now everywhere. I'm guessing what brought
you to this course, was that you encountered one in the wild, and you weren't exactly
sure how to use it. No worries, this happens to everyone the first time they run across one. It's a bit challenging
to understand at first, the web has changed a lot since 2007, but the webhook concept here,
is still pretty much the same. Our apps are now built differently. Like for instance, we
may be using services, and instead of form post, we build our own APIs
for our clients to use. The client post information to our API, usually not using a form. We developers use
web-based APIs all the time to build our applications. You should view webhooks as an extension of that type of work. This is why sometimes you'll
hear webhooks referred to as, a reverse API. It calls you, instead of you calling it. When you use an API, you need to understand the
parameters that it expects, and the reverse is true for webhooks. You need to know what
information is being sent to you, and in what format. There's no formal specification, and any data can be sent to your handler. Now these days, our web
handlers most likely look a wee-bit different than they did in 2007. Technology has evolved, some handlers still accept
traditional, form-posted data, and some of our handlers accept
JSON, posted in the body, for client side, the APIs
that we're writing, right? See the teacher's notes for more on this. You'll find a variety in what webhooks post to your handlers as well. As a developer, writing one
of these webhook handlers, it's pretty important that you understand how to capture and parse
that incoming data. Let's take a look at an
existing webhook implementation and see if we can't capture
the data to inspect, right after a quick break. By now, I'm hoping that
you're inspired to connect unrelated applications together. Well, we've got a good taste of some powerful concoctions
through the no-code solutions of IFTTT and Zapier. You've seen what's possible. You understand why you'd want to use events to trigger actions, as opposed to pulling an API repeatedly. With the what and the why,
of webhooks out of the way, I think it's time that we take
a deeper look under the hood to see how these webhooks
are actually working. I was trying to think
of common applications that all of us developers
are bound to use. The obvious one to me, is GitHub. If you've taken a look at
the notes for this course, which I hope you have, then you've for sure
already encountered GitHub. I've put the notes and
code for this course, in a GitHub repository, or repo. GitHub is a social coding site. It enables you to share your code, and work on projects together. You can submit issues, and keep detailed-version
history of your software, and you can read documentation. It's a wonderful place to explore when you're first learning to code. If you don't have an account yet, I'd love for you to pause the video, and sign up for a free account. Now, quick note, I'm gonna show off a little
bit of how to use GitHub. I've dropped notes that
give a more detailed tour in the teacher's notes to learn more. Make sure to check it out. There's even a link to a video game, that will walk you through
making your first poll request, or a request to make a change
to someone else's code. I know that can feel
a little bit daunting, but it doesn't need to. I want it to feel fun
for you, because it is. After you've got yourself
logged in to GitHub, wheel fork my teacher's notes
repository to your account. This will make it all yours. Now, forking is the process that happens when you see a repository that you like, and you'd like to explore it,
and make your own changes. You fork it, and you make it your own. You make your own copy of that repository. Now, you can always later
ask to apply the changes back to the original repository. Now, I want you to fork the repository, because once the repository is all yours, you can specify some webhooks on it. Here I am on the notes
repository for this class, the links attached in the video. I did wanna make a quick note, that the layout might look
a little bit different on the GitHub site, as they're constantly making improvements. Now, in the off chance that
you can't find what I'm doing, because the site has changed. Please remember to check the
notes for this specific video. I'll update future you
there, with what's different, and we'll get back on track. Sure glad I used GitHub for this. Up here, you'll see some social features. You can star a repo, which is equivalent of a
social media love or thumbs up. Now, as a developer, someone giving you a star
has that same dopamine hit as a like does. The more stars your repo receives, the more likely it'll be discovered. Here is the fork icon. What I'm gonna do, is
I'm going to fork this, and I'm gonna put a copy in my account. Now, you'll see it's
copying everything over, and this is now my own copy. Boom, just like that. Pretty forking fast, right? Note how this repo is mine. It's under my username, and you can see where it was forked from. Now, that this repo is mine, you can see that I have
a settings tab now. I'm gonna go ahead, I'm
gonna click into here. You'll see here on the left nav, that we have an option for webhooks. Awesome, let's click into it. Ooh, webhooks allow external
services to be notified when certain events happen,
just like we talked about. Awesome, totally makes sense. Okay, so let's add a webhook for our repo. I'm gonna click this add webhook button. I was thinking that we
should get the information when someone stars our repo. What we're going to need is
an URL to handle that request. Do you have one? I don't have one. A quick solution to capture a webhook, just to check things out, is to use what's known as a mocking tool. One of my favorite ways
to mock a webhook handler, is to use a web-based
tool called, Beeceptor. Here let me show you,
I'm gonna open that up. I'm gonna come here, I'm
gonna make a new tab. We're gonna go to beeceptor.com Let's make this a little bit bigger. Again, Beeceptor might
look a little bit different if you come in here. Check the notes, if you can't seem to follow
along with what I'm doing. Let's see, what am I gonna do? I'm gonna try a GitHub event. Let's call it, github. Basically, what you do is
you just put your name there, and you can click this create endpoint. Now, as you can see, I have
this github.free.beeceptor.com. I'm gonna go ahead, I'm gonna copy this. I'm gonna keep this page open. I'm gonna pop back over to
my add-a-webhook page here. I'm gonna paste that into the payload URL so that that's where it will be sent, where the information will be sent. We're gonna capture the stars, so I'm just gonna put
/stars at the end here, so that I know what that is. That's the cool thing about Beeceptor, you can just invent whatever you want, that that route doesn't exist,
but it will still catch it. All right, let's keep
filling out this form. We have content type, that's nice that GitHub lets you do that. We have a couple options here. We can either send JSON
or form URL encoded. I'm gonna choose JSON, let's do that. The other nice thing that GitHub does, is they let you choose which events you would like to trigger the webhook. You can send just the push event, that's when somebody
sends code to your repo, or you can say, send me everything, but they also let you
select individual events. We really only want when
someone stars the repo, so let's do that. I'm gonna click that, and I'm
gonna choose, down in here, there is one for, see how
many, much stuff you can do. You can sure do a lot,
so I'm gonna do stars. Here it says, a star is created or
deleted from a repository, and I'm gonna uncheck pushes, okay. There we go, we just have stars. Anytime somebody stars this
repo, we should get an event. Cool, all right, so I'm
gonna click, add webhook. Now, if I go and star my own
repo, because I can do that, 'cause I like myself. I star it, and if I
head over to Beeceptor, you'll see that there was a post to stars. Actually, there was two, because GitHub posts
originally to you're link, just to make sure it works. Here is what happened when we starred. I'm gonna click into this here, and then I'm gonna click
this little cody-thing, looking thing over here. I'm gonna click this, 'cause it will help format things better, and this is what GitHub sent
us, it's pretty cool, right? It shows you all the different information of the repo that was on, and if we scroll down
a little bit farther, we can see all things about the repo. All these different,
rest APIs that I can hit, to get more information if I wanted to. This is all about the repo itself, and I think if we get down
here a little bit closer, this is kind of, hard to read in here, but definitely captures
exactly what was sent. If we scroll down, wow, that's a lot. If we scroll down into here. There we go, we can see who sent the star, and we can see who the user
was, which is very nice. It's got more information,
it's got the avatar URL. I'm gonna actually, let's open that up. Let's see what this is. Wow, look at that dork
who liked this repo. I can use this to figure out, what I would like to handle, right? This was a post that was sent to any URL, and I can figure out what I wanna handle. I wanna go back and
show you something else that's pretty cool inside of GitHub, that not everybody offers,
that offers a webhook, but GitHub is pretty great. I'm gonna come back into
our webhook, that it exists, and it will show you what happened, right? It will show you the
deliveries that were made. If I open this up, I can see, and this is actually
more nicely formatted. Not everything offers this, so it is important to remember Beeceptor, because you're gonna wanna
catch other webhooks, and not everybody has
this nice functionality. Again, we can see this, and we can see, see that dork, this dork here. It's so nice that GitHub
lets you control the format, and actually see the way
the data's presented. They really webhook you up. Okay, so now that we
have a firing webhook, let's see if we can't
make use of that data right after a quick break. We've now got a webhook that fires when our repository is starred. I think we should use that
knowledge to celebrate and we shouldn't celebrate alone. I was thinking about another
pretty common developer tool that you're bound to
encounter is some sort of, real-time group chat software. It's very common that you'll
end up in a chat room of sorts. Now, whether that be Slack, or
Microsoft Teams, or Discord, these channels are a great
way to stay up to date with whatever it is that
you're congregating around. It's also a good place to
just hang out and learn. I was thinking, why don't we
explore sending our GitHub data into one of these chat platforms. We'll make sure that everyone celebrates when our repo gets starred. Now, I'm gonna choose Discord, but you'll find that
most platforms provide a similar sort of integration. Now, like we saw with GitHub, we were able to define a
webhook that would fire when certain events happen. Now, Discord actually allows you to set up the other side automatically. They set up a webhook handler for you. Let's see what that feels like. Just a friendly reminder. This is probably gonna look
a little different for you, in the future. Now, if you run into any
problems following along, check the teacher's notes, I'll update you there with changes. All right, so if you don't
already have Discord, it's a pretty quick setup, and I've included installation
instructions in the notes. Go ahead and pause me,
and get it all set up. This here is my current Discord. I've got some learning channels set up. Here's the free code camp,
and there's TwilioQuest. There's the coding den, all
great learning communities. If you're looking for
extra places to hang out and learn to code, check
out the teacher's notes. I'm gonna go ahead, I'm gonna make my own brand-new server, by clicking the plus button,
and I am going to say, create a new server and
invite your friends. I'm gonna do that. Let's go ahead, I'm gonna call this exploration, and we can get rid of
this later, totally fine. I'm gonna click create, and it's gonna say, invite your friends. I'm just gonna go ahead and close this. I've got friends, I promise I got friends. What's really nice about each
one of these Discord channels, like this is where you
could come and talk, right? You could talk in these channels. Each one of them has
this little icon here, and because we own the server,
we can edit the webhook. Let's go in here, I'm gonna click on this
integrations, over here on the left, and you'll see here,
there's this webhooks. I'm gonna choose, create
webhook, and let's see, webhooks are a simple way to
post messages from other apps and websites into Discord
using internet magic. I agree, they are pretty
magical, aren't they? Let's make some magic. Oh, and here it came up with a
suggested name, Captain Hook. (chuckles) What a great dad
joke, which if I'm honest, I'm kind of bummed that I didn't think of. Hopefully some more dad jokes pan out. This one kind of, petered out at the end. All right, so I'm gonna change
this to GitHub Notifier. It says careful, you have unsaved changes. I'm gonna click save
changes, 'cause I want that. I want a the thing called,
GitHub Notifier, in general. Again, what's happening here, is that this is building
a webhook handler. When you post to it, it sends a message into
the general channel. Now, this is important to note, this is different from
what we saw at GitHub. GitHub made the request to the handler. This handles the request,
both called webhooks. But therefore, because we
have both sides of this, we should just be able
to connect them, right? In fact, it looks like
the only thing I can do, is just copy this webhook URL. I'm really, that's the
webhook handler URL. I'm gonna go ahead, I'm gonna click this, learn more, up here, because let's assume that we didn't know what we were gonna do. I'm gonna click up at this learn more. It talks about some things
that we could do, and it says, can't really use webhooks,
can use webhooks. Here's GitHub, that's great. I'm gonna make this a little
bit bigger for all of us. It's talking about making a webhook. Oh, look it's changed already. Before it was, it's
under integrations now, so already see these notes have changed a little bit, that's fine. There's the Captain Hook
joke, for GET updates. Let's see, let's keep on scrolling. Well, this looks important, to make a webhook message
display messages properly, it's really, really,
really, really, really, really important, the caps there got me, that you append /github to the end of it. Yes, like five really is important. Okay, it's telling us to go
over to our GitHub settings, like we had done before, and put the /github on there. Let me get back to that, let's get back. Here we are, here is my GitHub repo, and I'm gonna leave this old,
this old webhook in place. Let's go back into our webhooks here, and I'm gonna add a new one. You can have multiple webhooks
doing different things, and let's do that, let's just
explore what that feels like. I'm gonna add a new webhook,
and I'm gonna paste, before I copied, right? I copied from that Discord, I
clicked the copy URL button, so I have that there, except
then I copied the help, so that's not good, let's not use that. Let's go back to the Discord, and I'm gonna do this, copy webhook URL. Now, it says copied in the clipboard. I'm gonna come back over
here, and I am going to paste, and wow, that is a long URL
and I need to do something. I was reminded something
like five times, oh, right. Really, really important
to say /github at the end. There we go. Now, this handler is unique to me, so that you can tell that
this is whatever this is here. Yours is gonna look different than this. This is my specific user,
probably my specific channel, all encoded in there. I've added /github at the end, and the content type in those notes, I saw that it said, application JSON, what's nice about, of course
having two different webhooks, is we can do whatever we want here. I'm gonna click, just send me everything, everything that happens. Let's go ahead and send it, and
I'm gonna click add webhook. Okay, and fingers crossed. I am going to, un-star the event and
then I'm gonna star it. Ooh, I heard a little Discord beep, I think we got, I think we did it. I'm gonna go, oh, that was, that reveal wasn't as exciting
as it could have been, 'cause I wasn't here,
but look, there we go. A new star was added by craigsdennis, and there's that little avatar of mine. It's working, I think it could probably be a little bit more
celebratory, but check us out. We wired up two completely
separate services, (snaps) just like that. Pretty cool, right? We set out to do basically
just what we wanted. When someone stars our repo, everyone in the general channel
there will be able to see it and they can celebrate along. We saw how the nomenclature
was kind of interesting, right? Like we saw how both
services, GitHub and Discord, call it a webhook. One is the pushing side and
the other is the handler side. It's a little confusing, isn't it? But, what Discord is doing, by putting that trailing /github, is specifically formatting
that information that's pushed across from GitHub. It understands what is sent from GitHub, and it has specific
formatting for Discord. I don't know about you,
but I think for stars, I'd like to see it more sparkly. Give me some more emoji's
in there at least, you know, really celebrate. In order to do that, we'll need to handle that
GitHub request ourselves, and turn it into the format
that Discord is expecting. That sounds like a good idea. Let's get ready to write some code. There goes our no-code streak. Why don't you get up? Take a breath of fresh air, give those coding muscles a stretch, and be ready to come back
and dive into some code. We've got our GitHub event notifications broadcasting to our Discord channel. We're feeling pretty good about what we were able to accomplish, with just a little bit of configuration. But, we've decided that
we wanna make things work a little bit differently than the default. This is a very common scenario, and a good look at why sometimes
you can't solve everything with no-code solutions. There are often specific tweaks that your customers would like to make, that aren't necessarily exposed. Let's make our tweak. Let's make it so that when
someone stars our repo, we write out some emojis, and show a big picture
of our code's newest fan. Now, in order to do this,
we'll need to write a handler. I've written the boiler plate, or the beginning common bits
of the code, for us already. It's available in the repo. Before we dive in, I wanna take a quick
moment here to talk about some of the possible challenges
that we might to encounter, as we start developing
on our local machines. In order to get things
up and running here, I'm going to be using a lot of tools. Now, depending on where you
are in your coding journey, some of these tools might
be completely unfamiliar. I wanna assure you that it is okay for it to feel overwhelming,
we've all been there. Setting up these tools
is a one-time thing, but it definitely is a hurdle
that I don't wanna minimize. I've seen this frustrate folks to the point of giving
up their coding journey. Please don't give up. You are doing great and you
will make it through this. Ask for help, and remember, all of us have been through this. I've included instructions
for installation for all of the tools that we'll be using
here shortly, in the notes. Please, remember that you can pause me for as long as you need
to get things working. All right, let's do this. The first thing that
we're gonna need to do, is get this repository from
GitHub onto our local machines. The way you do that is by
clicking this code button. As you can see, there are several ways to
get ahold of this code. You could even download
a ZIP if you wanted to. However, I'm gonna suggest
that we use Git to do this, but like you see here, you don't have to. I'm using a Mac and I'm
going to start my terminal. I'm gonna do that by
pressing command+space, and typing, terminal. On Windows, this will be either your command prompt or your PowerShow. At the command prompt, I'm going make sure that
I have Git installed. I'm gonna type, git --version. There we go, and as long
as something comes back, you're all set. If not, you'll need to install, Git, there are instructions
in the teacher's notes. Git is a powerful
version control software, which lets you and your fellow developers, make and document changes to files. Now, using Git is unfortunately out of the scope of this course, but I highly recommend learning it. I've shared links in the notes, for where to pick up this
crucial collaboration tool. It makes things like we're
about to do, super convenient. I am going to navigate to where
I'd like to store this code. This is of course, a personal decision. I keep a code directory, or folder, right off my home directory, which is represented by
this tilde, in Unix land. I'm gonna change directories,
or CD, into that directory, and it's called, code, and I'm gonna make a new
directory here called, courses. I like to store the tutorials
and courses that I take, the code for them, I store them in a place called, courses. I'm gonna say, make der, mkder courses. Back at GitHub, I'm gonna
choose that I wanna get this using HTTPS. I could use SSH if I wanted
to, but I'm gonna use HTTPS. Typically I do use SSH, this is up to you. If you have it set up, this is something that you need to do, if this is your first time doing it, you won't need to set
anything up to make this work. I'm gonna copy this URL here. I'm gonna click this, I'm
gonna go back to my terminal. I'm gonna say, git clone,
and then I'm going to paste, so we've got that URL there. I'm gonna click this. What this does, is this pulls
a copy of all of the code, and puts it locally on my machine here. Now, that it's here, I'm gonna
change into that directory. CD web, and I'm gonna
press tab, webhooks course. Here we go, and I'm gonna open up this
whole directory in my editor. I use Visual Studio Code, and if you don't yet have an editor, I highly recommend this editor as well. It's pretty great, it's free,
there's tons of plugins. There are installation
instructions in the notes, so I'm gonna type code, and
then I'm gonna press dot. Awesome, here it goes. Let me make this a little bit bigger. The code that I wanna
draw your attention to, is over here in the code directory. I'm gonna click this to open it, and then I'm gonna look
at this express-discorder, this is what we're
gonna work on right now. We're gonna open up
this express-discorder, and in here in this server.js, this has the boiler plate
code that I was talking about. This is using a web
server called, Express. In the handler that we're going to handle, is a post from /github, and
then it will run this code. We'll take a look at this
code here in a second, but basically it means if, you make a post to this web
server, that's running here, this web server, at /github,
it'll run this code here. This code will run when a post happens, but in order to run this, we need to make sure that
we have Node installed. VS Code has a built-in terminal actually, so let's go ahead and use that. We're gonna go to
terminal and new terminal, and you'll see here that in the future, I can use control and then tilde. Nice, and so now it's
put me in the root there, so I'm gonna go into CD code/, and then I'm gonna go into
the express-discorder folder. Awesome, in order to run this server, we'll need to make sure that
you have Node installed. (chuckles) I told you
there were a lot of tools. Node is a JavaScript runtime, that allows you to run
scripts on your local machine. Let's check and see if
you have it already. I'm gonna go ahead and
type node --version. Now, as long as this first part here, this V, whatever, is 10 or greater, the code should work as expected. Now, if not, check the teacher's notes
for how to install Node. Once you have Node installed, you'll also have npm installed. npm is Node's package manager, and you'll find that it stands
for just about anything. I actually have quite a
bunch of fun with that. Let's just go to the page really quick. It stands for, nice paintings, Mondrian. What else does it stand for? Oh, does it not refresh every time? There we go. Nincompoops producing methane,
novelty plastic mustache. Okay, there we go. It stands for, Node Package Manager, but it stands for a lot of things. What I've done already, is I've built this package.json file, and it has in here some dependencies, and the dependencies
will come in and it will, they're gonna be installed
for you when we use npm. Let's install those things. We'll do that with npm install, and that will go and install
packages like Express, you know, the web server. It will also use Axios, which is a library that we can use, to make our own POST requests, 'cause we're gonna post
to, the Discord URL. We need to make POST requests, because we're going to post to
our Discord webhook handler, like right in here. It says, axios.post, and we're gonna post, oh, that reminds me, we're gonna need to store this someplace. 'Cause remember, that
that's private to you. It's your personal link,
and as you're about to see, you don't want anyone
getting their hands on it. If they just post to it, they
could post on your channel, and you don't want that happening. One way of dealing with the security, is to use what's known as
an environment variable, and what the code here is using, this process.env.DISCORD_WEBHOOK_URL, is accessing your environment variables. What I've done, is I've set things up, so that you can define
in a file named, .env, and that's right over here. That's short for environment, and you'll see that you
don't have one right now, 'cause we just check this out, right? What you're gonna do, is you're gonna want to
copy this .env.example, so we're gonna grab this file. We're going to, let's see, I'm gonna copy, and then I'm gonna click this, and I'm gonna click paste, right? I right clicked, or two-finger
clicked on a Mac, to do that. I'm gonna rename this file now, to .env, .env, here we go, and in here you'll see, that you need to get a
hold of your webhook URL. I'm going to go and
grab that from Discord. Back in my settings, remember in the channel
under integrations, under webhooks, I can view this webhook. Here's my GitHub notifier, and I'm gonna copy the webhook URL. I'm gonna come over here, and I am going to paste it and save. Now, I have a .env, and
this is my own private file. What's nice about that is, this code can now be shared, right? It's code that maybe
anybody can run, right? I was able to give this to you, and what made it personal for you, was you put stuff in your
environment variable. This is a common way to share code, but have the private information, like the stuff that's
unique to you, hidden. Okay, with that all set up. I think that we're ready
to spin up this web server. I'm gonna write npm start, and it says that it is
listening at local hosts. It's telling me I can command+click that. Let's go ahead and do
that, and thumbs up indeed. We did it, so we have a local
web server running, awesome. Whew, that was a lot of tools
to install in one video. Now, that we're all set up, we need to make it so that GitHub points to our local web server. Uh-oh, our local web server,
it's not on the internet. How can GitHub possibly see it? Let's take a quick break,
and when you come back, let's explore tunneling, so that webhooks can see our local system. We just got a local web server all set up, and it's ready to handle
events from the GitHub webhook. But, we have a slight problem,
our web server is local. Only we can see it, it's
not on the internet, and this is typically how
you do development, right? You develop locally, you get things working
the way that you want to, and then eventually, you deploy your web server
to a public-facing URL, so that the world can
visit your masterpiece. But, typically you only deploy after you've worked through all your challenges, you don't deploy right away. Now, this makes for an
interesting challenge in creating webhooks. In order for a webhook to work, we need to be able to make a
POST request to a public URL. Now, the good news is,
there are a lot of tools, and yes, I'm gonna have
you install another tool, sorry, but it's just one this time. What this tool does, is it opens up a tunnel
on your local machine, so that your application
can be publicly accessible from the internet. Now, this type of tool is handy also, for like if you wanna see your
application in development. Like, if you wanna look at
your phone or your tablet, instead of just your local machine, it's pretty handy and it's quick to use. All right, let's open up this tunnel. The tool we're going to
install is called, ngrok. The N stands for, network, and to grok something,
means to understand it. It's also a Unix tool that allows you to
understand unstructured data. What ngrok allows you to do, is open up a specific
port on your machine. Now, if you recall, our local server was running on port 3000. What we can do, is open up
that port to the internet. I hope that you'll grok
ngrok here shortly. First things first, get ngrok installed. Now, not be a broken record, but this page is bound to
look different in your future. Check the notes if you have trouble following along at any point. There's a download section,
so let's go in here. Let's go ahead, let's
download it, it's free. I'm gonna download this for Mac OS. I'm sure it'll detect where you're at, and what you get back is a ZIP file that has a command line executable in it. I'm gonna click that and open it up, and it automatically opened
up in my downloads directory. Go ahead and pause me, and try to find where your download went. Mine went into my downloads directory. I'm gonna go in my Visual Studio Code. I'm gonna open up another terminal here. You can do that with
this little plus here. Here's another terminal, and I know that that went
into my downloads directory. I can say, CD, my home
directory, and then downloads. And then, from here, I can say, in this directory run ngrok --help, we can just kind of, see what it does. There's the different
things that it can do. I use ngrok all the time,
so I've put it in my path, and that lets me run it
from wherever I'm at. Check the notes on how to do
this, it's totally optional. I will use the ngrok from
my downloads directory in these videos, but if you wanna add it to your path, 'cause you wanna use it all the time, check the notes and you
can get yourself set up. Okay, so I'm gonna go
back to my other tab. Looks like I have three open,
you can type exit there. I've got, the server is running, and it's running on localhost:3000. In my other terminal here, I'm gonna go ahead and ./ngrok, and then you say what you want to do. I'm gonna open up an HTTP port, right? Hypertext Transfer Protocol, and I wanna open it up on port 3000. If I do this, what happens
is, I get a brand new URL, and if I copy this, I copy this URL. You'll notice that
there's the HTTPS as well, which is pretty awesome. You get a HTTPS for free. I'm gonna go ahead, I'm
gonna copy that one, or actually I could command+click it. Let's do that, we'll command+click it, and it's gonna open up that webpage, and you'll see that this string
of numbers, if I did that, I could also open that up
on my phone or my tablet, and it would be working. I totally had that hairdo, by the way. So, because we can see
this URL, it also means, GitHub can now post its payload
to us and we can process it. Let's jump back, and let's take a little deeper
look at what's happening in that code in the server.js. Let's get back into that code there. See if we can get a little
more real estate over here. I can't, unfortunately, let's see maybe we can go a
little bit lower over there, is that all right? I think that's all right, okay. We are going to get a post to /github, and it's going to, it sets
up a couple of things. We've got this content, and we have this hard-coded avatar URL, and it's gonna post to our webhook URL. It's gonna post the content, which is what we said
here, should say, wave. This is an emoji, and
it should say, hi, Mom! I like to always debug with
my mom, whenever I can. And then, we're gonna
post, and then we'll get, we'll send back a success
message if it worked, and if not, we'll send out an error here. Well, let's run it. I'm gonna copy our
ngrok URL one more time. Just to make sure I've
got that in the clipboard. I'm gonna copy this, and I'm gonna take that over
to our GitHub settings, right? Let's get back. Here's the get GitHub course, I'm gonna go into the settings. Head over to webhooks, and I am going to add a new webhook, oh, and it's making me log in. I'm gonna use, let me
grab my password here. Okay. All right, so we're
gonna add that webhook. Again, I'm gonna copy that,
'cause I copied my password, so I'm gonna copy this
link here, the ngrok.io, and remember that we have a /github that we need to post too. Let's go in here, we're gonna paste. Let's get this (faintly speaking) off, and we'll say, /github. We want it to send JSON, 'cause I think that that's
easier to work with, and let's do, again, let's just select the individual events. We'll do a star, let's uncheck pushes. When you're just interested
in when somebody stars, and we're gonna go ahead and add webhook. Okay. Let's switch back to our Node server. Oh, it said, success. It said, success, does that
mean that we got a post already? Don't switch. Boom, we got it. As soon as you set it up, it
sends one, so there we go. Hi, Mom, and there's Dr. Tyson
amazed by what we just did. We sent a message from
GitHub, through our tunnel, to our local machine, back
out to the webhook handler. Awesome, boom indeed, Dr. Tyson. We got it, well kind of, I mean, we got the starts of it, right? Now, we can iterate our development until we get exactly what we want. Just like we saw with Beeceptor, I can actually use ngrok to
see what was passed to us. Let's go to the ngrok, go back to the ngrok window real quick. If I come, I'm gonna move
this up a little bit here, even a little bit more. I can see that there is, a post was made to our GitHub from GitHub. In here, there's this web interface. If you follow this link by
doing a command+click on it, you will see that this is the information that we got from GitHub. Now, let's go ahead, let's make sure that it's
working when we get a star, 'cause right now that just
worked from the original message. I'm gonna go to webhooks. I'm going to un-star and star. I think we'll get two, yeah, so you get one every time you star and every time you don't star. There was a new star added. That was from one of the bots
that we were pushing before, and then here's this one that we just did from getting a star on the thing, awesome. It's working and if we look
at our ngrok inspector here, we can see that this is
the message that was sent, and it was an action that was created. This is nice, right? We can see exactly what was sent, so we can hang out in here. Now, I realize that GitHub
also shows you this, and we could do this with Beeceptor, but once you get ngrok running, this flow is pretty
much all we need, right? We can see that there's the sender, there's the avatar that
we're gonna need to grab. I'd also like to show the
repository name, right? Let's take a look and see
if we can't find that too. The repository name, oh, this is great. This would be awesome here
to say the name of it. You can either use this name or full name. Those are what we wanna
grab from this JSON that just came in from the post. Let's take a look at that real quick. Since we already have the, in our code, let's back down here, in our code, we already have this
avatar URL defined here. Let's go ahead and let's
grab that from the request. How's that sound? We're gonna get rid of this hard-coded, Dr. Tyson-thing there,
and we're gonna get, from the JavaScript object
that's being passed in here. We have the request that
comes in, and on the request, there is a body and I
have it so that it is reading JSON for us, this boiler
plate is reading the JSON, so it knows about it. That was in .sender, right? At the bottom there. If we look, we were in down here, in sender we have this avatar URL, right? This is who starred it
and this is their avatar. I have this avatar URL, so
I'm gonna use that here. I'm gonna say req.body.sender.avatar,
and it was _url. Now, to make sure I got it, I'm gonna need to start
and stop my server. It's a little annoying, right? This is a little annoying to have to start and stop my server
to make sure that it works, but I will. Control+C, we'll get you out of that, and then I'm gonna do npm
start, to run that again. Now, my code is reloaded, but I don't wanna do that every time. I don't wanna stop, I don't
wanna control+C and do stuff. I know I said only one tool,
and you don't really need this, but I think you're gonna want this. There's a tool called, nodemon, that will watch your JavaScript files, and it will automatically
restart the server for you. It's really nice, and
I want you to have it, although I don't want to keep
on throwing tools at you, but let's, I'm gonna show
you how I install it. You don't have to use it. We're gonna do npm install,
or nodemon -g, for global. After you install this,
you can use it whenever, that's what the -g means there. Now, that this has been installed, we can say, nodemon start, it kind of looks like it says
no demon or like node, mon. Anyway, so here we go. Now, you can see that
if I add this, hi, Mom, and I add some more and I click save, it will restart the server, which is exactly what
we love, want, right? You wanna change, every time you save, you want the server to be
running your latest thing, it's a quick, rapid development thing, that once you get in
the handle, hang of it, you will love it. All right, so the server restarted, and back on the ngrok page, I don't know if you noticed this or not, but this is awesome. There is also, just like
on, there's a replay, so you can replay and you
can actually even edit it. But, I'm gonna go ahead
and click this replay. Ooh, there we go, ba-boop. Okay, so there we go, hi, Mom. There's my avatar coming through. My avatar URL is now there. Now, that's a pretty big
picture, I love that. That feels great, this is like, this is a new person who liked your code. Great, good feeling. We're doing good, and we really say, hi, Mom, now, right? Our change is live. Now, what we need to do, is we need to change the
content variable, okay? We need to change this content, so instead of saying, hi, mom, we need to make this
dynamic about who came in. Let's do this, I'm gonna
write a to-do here. I'm gonna write a to-do, so we'll say, to-do, change the content variable to contain the repository name and, the GitHub, username, and why don't
you add some emoji flares? You can explore, if you want to, in here, you can explore with, you know,
there's like rocket, right? There's a rocket-thing that you can do. If you just type colon
and then the name of it, you can start seeing what it is that you could do with emoji flare. Why don't you pause me, and see if you can complete this to-do? Use the request from
GitHub to do this, right? You can look over at your ngrok, and see what's going on there, and make sure that you
change the content of this. And then, go ahead and do a replay, and see if you can get
that content to be what you're happy with, when
somebody stars your repo. Give it a shot, and when you're done unpause me, and I'll show you how I did it. Remember, to use ngrok to see
what the request looks like, and to replay it, are you ready? Pause me.
(icon beeps) (icon beeps)
How'd you do? I hope it went well, and
don't sweat it, if it didn't, you'll get this. What I'm gonna do is I'm
gonna grab the username, and that was in
req.body.sender.login, okay? And then, I'm also gonna
grab the repo name. I like to pull these things out, just to make sure I got 'em. We'll say, req.body.repository.name. The sender is at the bottom, and the repository was up at
the top there, that request. What we can do is we can use a string template in JavaScript. We can say, one of these
back ticks like this, right? Then, we can say, $(username), just starred $(repoName), and this way you could have other people set up to their repos. You could share like, let's say we're in a
community of everybody who is, write some code together,
we can all run this. Because, this is our
own private Discord URL, you could let other people
run it in there GitHub, in their Discord webhooks,
or they can post to this URL. Awesome, so let's go ahead. I'm gonna save this, it's saved, and the server has restarted,
so fingers crossed. We're gonna go back over to our ngrok, and we're gonna click replay. We heard the little
Discord go, and it says, craigsdennis just starred
the webhooks course. Oh, shoot, I forgot my flair. Let's go back, let's see. I definitely think we need some tacos. I can't have enough
tacos, we got taco, taco. How about, let's definitely do the rocket. That's one of my favorites,
rocket, and I also like, ta-da, ta-da, taco. I will save, and again,
I'm gonna come back, and I am gonna replay. I heard the boop-boop. There we go, oh, beautiful,
so much flair, awesome. Pretty smooth workflow, right? I hope that gave you a
clear feeling of what developing a webhook handler
might feel like in practice. We saw how not only can
ngrok open up a tunnel to your local machine, but it
also provides the ability to review and store what was posted, and it even allows you to replay. It really speeds up your
development process. Now, I'm sure you're probably
wondering, well, great, but does this mean I have to
leave my local machine on? Of course, the answer is, no, but you're gonna need to
deploy your applications, so that GitHub can reach 'em. Now, if you don't have
an existing application, this can definitely seem daunting. You probably don't wanna
spin up a Heroku instance, just to host this single endpoint. That seems like a lot of work. One of the solutions that has
been gaining a lot of ground, is the idea of a cloud function. We'll take a look at
this here in a second, so that you can see how that feels. These make a really good solution for a quick webhook handler. I want you to get a feeling for it, as it's getting more and
more popular in this world. But, before we get there, you, my friend are due for a break. That was a lot of technology
and a smattering of concepts. I want you to take a break
and let it all soak in. I'd love for you to make sure that you can picture in your brain, the request from GitHub
coming to your handler, and your handler doing what it needs. Now, in our case, it's posting to a webhook handler that was already set up by Discord. I'd also like you to take a minute and realize that you can
now run any code at all. When an event that
supports webhooks occurs, you can handle it. That's pretty cool, isn't it? Now, as empowered as I felt
before by the no-code workflows, like IFTTT, these possibilities are actually quite limitless. Now, I could definitely
make my dog light up when I get a star, look, check this out. Just like this, dog star, Keanu would get that one. Okay, so after your break, let's swing back and check out
serverless cloud functions. (upbeat electronic music) Okay, we got our webhook
written and we're happy with it, but in order to run, we need a public URL. While our tunnel solves the problem for development purposes, it's definitely not production ready. Now, we could deploy our web server that we wrote and hosted somewhere. There are lots of providers that do that, and it's definitely getting
easier to deploy a web server, but even the server seems
a little heavy, doesn't it? We're really just taking some values, and quickly doing our thing
for a single request type. It's hardly a web application. Well, we're not loving this feeling. Succinctly, this feeling is,
do we even need a server? Could the project go without
one, could this be serverless? There's a growing movement
called, serverless, and it tackles this problem exactly. You don't need to worry about the server, someone else will handle it for you, and it will scale both
up and down for you. Now, this scaling both directions is referred to as, elasticity. Function-as-a-Service, or FaaS, is the idea at the core of serverless. Basically, you write a function, and you follow the specific parameters. The provider handles all the routing responses and scaling. All of the big cloud players have some sort of version of this, and typically the executions are free, until you hit a certain threshold. Even then, you only pay for
when the function executes. This can lead to tremendous cost savings, also because there's
only ever one function, it makes the code very easy
to read and understand. It's kind of like. ♪ Take me down to the
paradise elasticity ♪ ♪ Where the FaaS is cheap
and the code is pretty ♪ ♪ Oh won't you please
take me home, oh yeah ♪ Is that too much? I really Axl Rose to the occasion there, I guess we can probably just
slash that part out later. Okay, fine no more puns, and roses. I thought you should have a taste of how the serverless development feels. I went ahead and got the solution all coded up and ready to deploy. There are a lot of serverless
providers to choose from, but one of my favorites to get up and running quickly is, Netlify. Now, standard warning is in effect. This flow that we're about to do is bound to look a little bit different. Netlify is always adding functionality. Another thing that I wanna point out here, before we dive in, this
is totally optional. You don't need to do this. I totally won't be offended
if you just watch me do this. I've signed up for a Netlify account, and I used my GitHub account, and I'm gonna head to
their docs really quick. They're right here in the header, docs. Now, what I wanna install is the CLI, or command-line interface, which allows us to run commands from our command line for Netlify. Let's go ahead, let's click this. Let's get started. Here's some great information on it, and we're gonna go ahead and install it, and we're gonna install it with a -g, which makes it go globally, okay? That means that we can use it wherever. I'm gonna come in here and I'm gonna run this right
from the root of the directory. It doesn't matter where we do it, 'cause we're gonna do it globally. This will install the Netlify package. What this will do, is we'll, here shortly, what we'll do is we'll authenticate, and it will allow us to do
actions on Netlify on our behalf. It's super powerful, it's great. You hardly ever actually need to leave your command line anymore. You just hang out in this editor. I think you're gonna love it. Okay, we are all set up here. Again, like I said, I had already started
porting this code over, and first though, let's log in first. If you do Netlify space login, I'm already logged in,
but what will happen, here I'll switch my account, so that you can see that I go through the same thing that you do. I'm gonna say, switch my account, and I am going to log into a new account, and it's gonna pop up
here, and it's gonna say, authorize this application. This is okay to do this,
this is what we wanna do, we wanna authorize that CLI, awesome. Now, we can, you can
also revoke at any time from the screen here inside
of Netlify after a login. All right, here we go. We are logged in to Netlify. I'm gonna take a look
at this directory here. This is the netlify-discorder. Open that up, and under
functions/discorder, there's a file called, discorder.js. This is very, very
similar to the local code that we had just looked
at, the Express code. There's a couple of things that
are a little bit different. The first thing that I wanna point out, is that this function is asynchronous. You can tell that, because it says async. What that allows you to
do, is then later await. You can see here that when this Axios, remember this is what we're
using to post to Discord, this returns, what's known as, a promise. It's a promise that in the
future there'll be a value. We handled this differently, when we were not in an async function. Let's just take a look at that real quick. If I open up the express-discorder
and I look at the server, you'll see that I did axios.post, and then down I used a .then,
and I got the response back, and then I played with
the response, right? This is a function that's
getting the response back. But, this function, when it was declared, is not asynchronous, and it's using a request and
a response, remember that. It's using the request, and we were able to pull
things off of the body before, so we were using req.body, and it was already a blown-up object. Just remember that, it's
a little bit different. Again, this is using a promise, and it's using the then pattern. Where what's different over in Netlify, is we are using an async method, which means that we're able
to do something like this, where we can say, await. Now, instead of it coming
through in a then function. this pauses and waits, and
then it goes here to go rest, so it actually runs synchronously, or it appears to run synchronously, right? What makes this different, is
before we were catching it, we were doing a then, and then we were doing
a catch on the error. Here, we're using a standard
JavaScript try and catch, very similar, just a little
bit different of a pattern. I know that that can hang some people up, so please check the notes, if you'd like to learn more
about asynchronous JavaScript. The other thing I really wanna point out, what's the main difference
that I had to do here, porting these things over, was before remember it
was request and response? This just has event, okay? What's expected is the
response you just returned, so I'm returning an object that
gives a status code of 204, instead of returning a response. That's what Express had expected, and event is basically the
request object, more or less. What you'll see here, is
event.body is a string, and in this case, it's
going to be a JSON string, and we're going to parse it into body. Then, the rest of the code is the same. I just made an object called, body, which is what was on the other request. It's just a little bit different, but pretty much the same code. This code we're gonna go
over into Netlify, Discord, we're gonna go into
code/netlify-discorder/, right? 'Cause, we wanna get our
prompt in the same place here. Now, this is using Axios, and
this also has a packaged JSON, and you'll see that it's got Axios. I'm gonna go ahead, I'm
gonna do an npm install, and there we go. Believe it or not, this
is ready to deploy. Watch this, this is awesome. We're gonna say, Netlify deploy, and we're gonna send this
up to the Netlify server. The way that this works, is anything that's in this
functions folder here, is going to become a serverless
function, let's do it. It's gonna ask, it's not
configured to a site, this folder that we're in right now. We want to create a brand
new site, so with that, that is what we wanna do, and here we go. It says, team Craig Dennis's, everybody with the last letter of S, knows what I'm feeling there. Yes, we do want Craig Dennis's team. All right, so we wanna
make a unique site name. They suggested,
super-cool-site-by-craigsdennis. Let's try gitubstars, 'cause
that's what we're doing, right? You'll have to choose something different, 'cause I'm gonna take it, and somebody else already took it. Don't you hate this though? People end up with like,
githubstars1925, so githubstarred, yes, I got it. I've got, githubstarred, and that's gonna be,
githubstarred.netlify.app. Now, it's asking what
directory do you wanna publish? And, it's that, it looks
like almost like an emoji, but it's a dot there. It says like, this current directory. Yes, that's the directory I
want, and would you believe it? But, we just pushed up to
a server, a live server, there's a function that's
running, and it's running. Let's go, I'm gonna jump in here in the admin side of things,
I'm gonna follow this link. I clicked that logs link
there, here we come. We are up, we are published
today, and let's drop out. Let's go take a look at these functions. It says, one Lambda function
is ready, and it's down here. It's this function. In here, whenever the function would run, this is what the function's name is. This is it here live, whenever this runs, the function log will show any sort of console log that
we have, pretty cool, right? I do have one little bit
of configuration to do. We need to set an environment variable for what our personal Discord
webhook URL is, right? That code, remember, I'm still using the environment
variables in that code. I need to put that
environment variable here, and that's under here, it's under settings, and then
it's under build and deploy. Here we go, environment variables. I'm gonna say, edit variables,
and our variable name, let's just verify we know
what that variable name is. It's inside this discorder file here, and we called it, DISCORD_WEBHOOK_URL. I'm gonna pop that into my
environment variable here, and the value that we want,
you can get that from Discord. Let's go, let's grab that one more time, just to remind ourselves where that's at. We're gonna click the
settings here, integrations, view webhooks, GitHub notifier, and I'm gonna copy the webhook URL, okay? I copied that. Come over to the build,
I'm going paste that. I'm gonna click save. Now, if I come back to my function, let's go ahead and get that URL again. It says that it is running in production. I'm gonna grab that, I'm
gonna head over to our GitHub. I'm gonna go in my webhook course, in the webhook course here under settings, under webhooks, let's go ahead and let's
edit this one, right? This is our local machine. This is the one that we
were doing last time. It's not gonna work, 'cause sometime I'm gonna
shut my computer off. I swear one of these days,
I'm not gonna have it on. All right, I'm gonna grab my password. I paste my password, and I'm gonna make sure that
I have the webhook URL copied. I'm gonna change that to be, that's not right, we don't
want the Discord web app URL. We want the githubstarred.netlify.app,
new site on Netlify. I'm gonna copy that, and I am going to paste
that into my webhook. There we go. Everything is still set, I'm
gonna update the webhook. I am going to get my
Discord into a good state. Here we go, let's star this thing. (computer beeps)
Ooh, I heard it. We get the new star added from here, where is the one from Netlify? What happened? Let's
see if we can debug it. Is this updated? Githubstarred,
netflify-discorder, what's this? This doesn't look like, maybe
we need to update the webhook, maybe it didn't update. Oh, here we go. Here's some failed
ones, let's take a look. What do we get in response? The URL argument must be of
type string, received undefined. Let's see, that's the same thing again, the URL argument must be of
type string, received undefined. Let's see. It doesn't like that
avatar URL, let's see why. We've got the body sender avatar URL, we're parsing the event body. I'm assuming that's what the 500 is. Let's look at our, we can
look at our logs though, too. Let's see if there's anything
that happened in the logs. It just says, that it ran. I didn't get an error there. Let's see, one more time what that said. Let's make sure that it has
a sender with an avatar URL. Sender avatar URL, yeah, it's still there. Sender avatar URL. Let's do a console log,
let's just show that off. I would say, console.logevent.body, and then we'll do afterwards, we'll say, console.log(body), okay? I'm going to, now I made the changes here, so I need to push them up. Publish that directory, and see it's a lot quicker
the second time around. All right, and let's go
replay that from GitHub. We don't want the delete one,
that was the deleted, right? Let's replay the one. Let's do it. (computer beeping) Well, there we go, now it's working. I don't know what that
was, something silly, but I wanted you to see. What you should seem is
that this should update. There we go, so see, I
can use console log here, to look at things. I'm not exactly sure what happened. I think what I'll do, is
I'll go back and watch this, but you don't need to do
the console log bits there, but that is how you deploy
and debug a function, in this one new world. The good news is, is that
this function is free, for a 125,000 executions a month. I don't think I'm gonna
run into that limit, but you never know, this is
a pretty killer repository. Oh, and while debugging with those handy-dandy console log
statements, on the production, might not be your style, and it really shouldn't be your style. You can actually run a local
Netlify dev environment, check the teacher's notes for that. I hope that gave you a good test drive of serverless functions,
pretty neat, right? These functions are especially
handy for webhook handlers and other one-off scripts. You literally could use a
function just like that, to kick off just about
anything that you can imagine. That's a lot of power. Now, remember on top of
being basically free, this will scale both
up and down with load, because that elasticity is at the heart of serverless technology. I've added links in the
notes to other serverless or cloud computing providers. All right, so now I hope
that you're feeling like you've got a pretty
good handle on webhooks. You understand why they're useful, you know what they can accomplish. You can see how you can
do just about anything, and you even understand
when you should use them. Really, that when is any time you wanna get notified
of an external event. Whenever you feel like pulling an API, check to see if they
support webhooks first. Basically, you're a pro, and I realize you might not feel like one, we've been focusing on just one event. Now, there are a couple of other platforms that deeply embrace the
concept of webhooks. I've got something planned that will really stretch
your new webhook muscles, and I hope it should
give you the confidence, and most importantly, the
practice that you need. Take a quick break, and then let's get started on the final project for this course. So far in this course, you've picked up the
essential skills that you need to make use of webhooks
in your applications. I thought we'd apply those
skills in a large project, using completely different
technology than we used thus far. This way, you can see how
your skills are transferable. When it comes to technology
that fully embraces webhooks, it's pretty hard for me
to think of anything else other than Twilio. Now, if you've seen my courses before, you know that I am pretty
obsessed with Twilio. When I saw that they used a video game to educate developers, I was like, I've gotta work at this place. Freeze frame, record scratch, (record scratches) now I'm a Twilion, and I'm in the game, but really I've loved Twilio, ever since I was introduced to it, I was at a JavaScript conference in 2012, and someone had built a scavenger hunt that you could participate
in by just texting a number, and it would respond with different hints. Now, not only was it fun, I was also impressed with how people were using the text messages
to build interactivity. You didn't need to install anything, you just text a number
and you were playing. It's a pretty incredible input device. Text messaging is just
one part of the platform. Really, any sort of
communication or engagement that you wanna have,
Twilio has an API for it. The way most of the products work, is that you buy a phone number and that number is yours immediately. You can use it to make calls and texts, and you can program what happens when people call into it or text it. People build all sorts of fun and creative things on the platform. In addition to a completely
cloud-powered call center, I've seen a video game get modified live through a text message. Somebody built a Smashmouth
hotline, which plays that one. ♪ Somebody once told me ♪ When you call, it was such a
mean trick to give someone, when they ask for your number. There have been crisis lines that keep caller's number anonymous, and routes to an available person who can help in the time of need. I even saw a kid built a
fake snow day alert message, he got in trouble. You can build just about
anything you can imagine, and Twilio does most of
this magic through webhooks. We talked a while back
about lifecycle hooks. This is the concept where
the flow of the application allows you to hook into it and
the control is passed to you. You're responsible to respond with what the application should do next. That's the main concept for
what happens with incoming input to your Twilio number, a call
or a text message, right? The control of the application is passed to you via a webhook. There are a ton of other
webhooks that allow you to control what happens
at different times, when different events occur, continually passing control
back to your webhook handlers. Because, your handler is
any public accessible URL, your code can be in any
programming language. It just needs to respond with what you want Twilio to do next. Twilio's basically a webhooks playground. There are an impressive
amount of them to play with. Here's a couple of reasons for that. First off, Twilio has been
around for a long time so there's been lots of
time to build these events, to hook into, and to perfect that flow. For another reason, remember when we talked about the creator of the webhook
concept, Jeff Lindsay? Well, he was a Twilion, in the very early days of the company. I found that out researching
the history of webhooks, and it all made sense. I figure, what better place to show off your new webhooks skills,
is there than Twilio? First, we'll build a simple
affirmation text app, to get your feet wet. And then, we'll launch
into a larger project that will take ideas from
callers, record them, and text them to us, all with webhooks. All right, let's get started building this webhook-based application. In order to show off the
Twilio webhook basics, let's build a really simple
messaging application. What we'll build is an app that responds to any text message with, you've got this, just to give our texters
a little confidence boost. Turns out those three words go a long way when you really need them. Now, in order to get started, you're gonna need a Twilio account. Now, don't worry, it's totally free. Twilio offers a free trial, and they give you more
than enough free credit to build all of the
applications in this course. If you don't already have an account, go ahead and pause me, and follow the instructions
in the teacher's notes. After you get your free trial all set up, unpause me, ready? Standard word of warning. This is bound to look
a little bit different, as Twilio is always improving things. Check the notes for anything that might
function a little bit different. All right, I've set up a
free-trial account too. We should be having pretty
similar experiences. There are a couple of restrictions
with your trial account, which are listed up here. You can send messages and make
calls to verified numbers, and messages and calls include a note about this coming from
a Twilio trial account. Like, when we send this text message, when you get a text message back, it's gonna say, sent from
your Twilio trial account. Now, if you didn't already
get your free trial number, go ahead and do that. Get a trial number, go ahead, click that. That's gonna give you
one, 203, that's great. I'm just gonna choose this number, and right away, this number is all mine. With a paid account, you could get more, we only need, everything
that we're gonna build here, we just need this one phone number, and it doesn't matter that it has the trial message stuff on it
for what we're gonna build. All right, let's do it. Remember what we're going to do, is we're going to make it
so that if anybody texts this brand new number that we just bought, we're gonna return back
a nice affirmation. To do that, I am gonna
navigate to my numbers. Over here, there's
these little three dots, all products and services, and I'm gonna choose phone numbers here. You'll notice that there's
this little pin icon. If you pin that, it will make it so that
it's part of the menu. When you come back in
here, you can find it. There's a ton of products. I'm gonna pin it right now, let's do that. You'll see here's the menu now, I've this phone numbers thing here. Let's go into our phone numbers. Again, this is our demo one, my demo one, you have a different demo one. I'm gonna click into that, and I'm gonna scroll down
on this configure page. You'll see voice and fax. Yes, you can actually send
faxes, actually comes in handy, I don't know if you have a
fax machine anymore, I don't. I'm gonna scroll down here to messaging, and you'll see it says, messaging. When a message comes in, send it to this webhook via an HTTP post, send it to this webhook. That is supposed to
return the instructions that Twilio is expecting. Now, the format that's expected is TwiML, or Twilio Markup Language. Just like HTML renders your webpage, TwiML renders your application. I'm actually gonna change this
from webhook to TwiML Bin. A TwiML Bin is a handy way
to return these instructions. You don't need to spin up your own server, this is taken care of for you by Twilio. It's a serverless solution,
so here, I'm gonna make one. I'm gonna do that by clicking
this plus button here. I'll say, plus, so I am going to name my TwiML
event so I can find it later. I'm gonna call it, affirmation. Now, TwiML is tag-based
and case-sensitive, so I'm gonna say, and all of
them start with a response, so response, response, okay. We want to add a tag that
sends back a message, and that tag is actually, message. We'll say, you got this! I'm gonna drop a muscly icon in here, just to really get the point across. There we go, and then I'm
gonna close this message tag. Awesome, and you'll see that there's some, it'll tell us whether or
not we've got it good. It says, this is good,
valid messaging TwiML. Let's do it, let's go ahead. We're gonna click create on this, and now you'll see messaging,
when a message comes in. Go to this TwiML event called,
affirmation, return that. Need to remember to save
the number, all right. Now, I'm gonna pull out my phone, and I am going to text my number there. 203-902-5283, and what I expect, whatever I send, right? It immediately, it's gonna
send back, you got this! I'm gonna say, I'm having a hard time with JavaScript, and it says, you got this. You're right, I do got this, thanks. Awesome, okay, so that is basically the "Hello, World!" of TwiML webhooks. That's pretty awesome, right? It's a good use, it's like,
when a message comes in, send it to this webhook. Now remember, this could
be any programming language or tool that returns a valid TwiML string. You can return this
from any web application that you have existing already. And, this TwiML Bin that we used, because we didn't have
a server up and running, it's a serverless solution. Twilio's hosting it for us, and
handling the scaling for us. Like, we don't need to
worry about that at all. More of this in the teacher's notes. Pretty great, right? We now have a way to respond to any incoming message to our number. While we're currently only
using a static solution, we could definitely build a dynamic, a handler that did whatever we wanted. This is like our handler that we used for posting to Discord. This could be whatever you could dream up, and you can respond with
a valid TwiML string to continue the application. We'll get to some more local
development here in a second, but first, I think we should
explore a low-code tool used to build complex
serverless workflows. Okay, my next idea for
an app is a little meta. I would love to have a call-in line, where anyone could call
and describe their ideas for cool webhook implementations. I love hearing all your ideas, and I find that when I
discuss things out loud, it greatly increases the
likelihood that I'll get it done. Let's do that, let's build
a hotline that prompts the caller to record their idea. Once the idea is recorded,
let's transcribe it, and then text it to ourselves. We took a look earlier
at some no-code solutions that were powered under
the covers by webhooks. Well, Twilio provides a
low-code, serverless solution, that allows for rapid development and prototyping of applications. It's called, Studio, and like most no-code or low-code tools, you'll find that you can
build a lot of solutions just by dragging some objects around. Let's build the first part of
an application using Studio. We'll make sure to keep
our eyes out for webhooks. Hey, future you, this is for
sure going to look different. You'll find that almost all
no-code tools rapidly iterate on their UI daily to make
things more quick and clear, and I'm always pleasantly
surprised when I open up Studio. I'll update the notes on any
changes that might've occurred, since right now in my timeline. All right, let's do this. Okay, so we are in our Twilio console. I'm on the phone number page currently, and I'm gonna jump over to Studio. That's this, these three
little dots over here, and I am going to scroll
down, into runtime, and I'm gonna choose Studio. I don't wanna do that
scroll again, so again, I'm gonna pin that, so that
shows up in my little menu here. I'm gonna go to Studio, and I'm going to click
this, create a flow button, 'cause that's what we're going to do. We're gonna create a brand new flow. Let's do that, I wanna call
this flow, idea catcher, and we'll say, next, and you'll see, there's a bunch of
templates that we can use, but let's just start from scratch. We have a pretty straightforward
way of doing this. Let's go ahead, let's just go, next. That looks like the dork
that starred my repo. This here is called, the canvas, and what you do, is you
drag widgets onto it. Let's see, when someone calls, we should tell them what
we're expecting them to do. I am going to grab this, say and play, because I want it to say
what we want them to do. I'm gonna drag this over, and we're gonna drop it right here. Now, that it's out here, I can click it. What will happen is over here,
these properties will change. This say widget allows
us to do text to speech. I could also give it an
audio file if I wanted to, that's in here, I can
make it play a message, but we're gonna have it say a message. We'll do text to speech, so let's see, I want it to say, hello there, I'd love to hear your wonderful idea. Tell me about it after the beep. All right, so these
other fields down here, they are optional, but they're here, might as
well fill 'em out, right? Let's make it English,
and let's choose a voice. I'm gonna choose, Kendra-Neural. This is from Amazon Polly, all these voices are from Amazon Polly, and this is Kendra-Neural. It's kind of got this
fun, those days of like, those robo voices are gone. I remember when, Texas Speech first came out, and it couldn't even say cheeseburger, it was like, chaz-ebbiger. I'm calling, Kendra. I'm gonna leave her there, and we can make a loop a
certain number of times. That is feeling pretty good. I'm gonna click save to update the widget. We want this to be said
when somebody calls. What we're gonna do, is we're
gonna drag from this trigger, note, this is like a webhook, right? We're gonna say, when
an incoming call comes, we're gonna go to this here, awesome. That's probably enough to test, isn't it? Don't you think? The way that these work, is you can see that I made four changes, but I'm gonna go ahead and
I'm gonna click publish here. We're gonna publish the flow. It gives us a little bit
of warning ahead of time. Now, this is ready to use. I'm gonna go into, back to my number, and I am going to come into my number, and I'm gonna scroll down here. Under the voice and fax section, so when a voice call comes
in, when a call comes in, we want to use a Studio flow, and we can choose our flow of
idea catcher and click save. Awesome, now I am going
to call that number, and I'll put it on speakerphone here. - [Man On Phone] You have a trial account. You can remove this message at any time by upgrading to a full account. Press any key to execute your code. (phone beeps) (phone ringing) - Here comes Kendra.
- Hello there, I'd love to hear your wonderful idea. Tell me about it after the beep. - There's Kendra, it's
telling us about the beep. That's awesome, right? We got that up and running, very easily, going through a webhook, and again, that's really rendering
TwiML behind the scenes. It works, so now here's the trick, that flow that we built is
actually a webhook handler. It actually has a URL, that little menu, this little like, select the flow, it's kind of hiding it from you, but it really is just an URL. What's really happening,
is when a call comes in, and Twilio posted this URL,
our flow returns TwiML, in this case, it's the say
TwiML (faintly speaking), which is very similar to
the TwiML that we wrote to send the message. But, the low-code solution
has that hidden away. Now, this is very common in
these low-code solutions. They abstract away the cogeneration and all the webhook handling, okay. Next, we want to record
what our callers say. Let's go back to our flow, so I'm gonna jump back into Studio. I'm gonna click this idea catcher, and get back into our flow here. Now, we want to record, so I'm gonna drag out
this record voicemail. We'll drag this out here. Awesome, and let's take
a look at its setting. If I click onto it, we can see that it will stop
recording after five seconds, or you can make it stop on,
if somebody pressed the key. Ooh, and 3,600, that's 10 minutes. Oh, sorry, that's an hour. 3,600 seconds is an hour,
and that's more than enough, even for chatty folks, who
have very detailed ideas, like myself, very chatty. Okay, cool, so we also can
transcribe the audio to text. We want that for sure. I'm gonna click that on, and look at this, we have a transcription callback URL. I know what that is, that's a webhook. That is a webhook, isn't it? But, what is actually gonna happen, when that transcription comes? I know that I could go up here. I could probably go to this
help here and figure that out. But, if there was only
a tool that we could use that would just allow us to
put some random URL there, so that we could see the results, so we could capture what was sent. Wouldn't that be nice? Wait a second, there was something that we
used earlier, wasn't there? Do you recall what it was? You wanna try and do this yourself? If so, go ahead and pause me, and get a web-based URL in here, that we can use to see what
values are posted to it. Are you ready? You can do this, pause me. (icon beeping) Okay, ready, how'd you do? The tool that I was
thinking of was Beeceptor. I'm gonna head over there really quick, jump over to Beeceptor again. I'm gonna create a new
one called, recording, 'cause that's what
we're looking at, right? We're looking at this
recording thing here, and we have that up and running. Now, we know that we
have this Beeceptor URL. I've got this, I'm gonna copy this, I'm gonna come back over here. In the transcription URL, I'm
gonna paste the recording, and I'm gonna make my own thing up here, we'll say, transcription. Let's see, do we wanna play the beep? Yes, we definitely wanna play a beep, 'cause we said that, right? We also have a recording status callback. I think we just need the
transcription right now, right? We don't really need to have, to know when a recording is available, but look, there's another webhook. All right, so I'm gonna click save, and then I want to connect
these two together. It says, when audio completes,
we want it to go to this one. You can see that there's,
if you had more here, you could choose different
things to happen, when different transitions
happen in each of these widgets. Okay, so an incoming call is gonna come, it's gonna say, hello there. It's gonna record the voicemail, and that voicemail should
be sent to our place. I'm gonna click save, and
I'm gonna click publish, and now I don't need to
go update my number again, 'cause it's already
set to the flow, right? It's already set to this flow. It should be working now. If all is working as planned,
when I call this number again, when I call my number and leave a message, we should see a webhook
kick off here, let's do it. - [Man On Phone] You have a trial account. You can remove this message at any time by upgrading to a full account. Press any key to execute your code. (phone beeps) (phone ringing) - [Kendra-Neural] Hello
there, I'd love to hear your wonderful idea. Tell me about it after the beep. (phone beeps) - Yeah, so I have this idea, where I'd like to set up a call line where people could call
in and record their ideas, that's my idea. Now, hopefully I hung up, and hopefully we should
see here in a second. We should see our message
has been recorded, and it's being transcribed right now. When the transcription's done, we should get pinged over
here, if all is working. I'm trying to be patient. There it is, so we got
to post to transcription. I'm gonna take a look at that. I clicked this and it's in the new format. Let's scroll this down here. We can see we've got a
bunch of stuff that came in. Let's see, I called that number. Ooh, there's my number. Feel free to call, I guess. Here we go, transcription to text, so it says, yeah, so I have an idea where I'd like to set up a
call line where people call and record their ideas,
yeah, that's my idea. That's pretty great, but
that's exactly what I need. I need that transcription-text
field that comes across, that's submitted to my webhook. I need that transcription text,
that's what I need, awesome. Now, that we've got a webhook event, we can write any sort
of handler that we want. We definitely now have the, message has been transcribed, event. We can do whatever we
want with that event. We could very easily send
that text to Discord. Now, to complete our app, we're gonna have to have this
event send a text message. Now, I'm excited to show you this, as it's super common to
want to send a text message from your webhook handler. There are so many, when
this one event occurs, text me about it. All those ideas are out there, and they're just waiting to be fulfilled. Let's develop the solution locally, using the local-development tools that we learned about earlier. We now have a transcription
webhook event that's happening. We saw in Beeceptor what
the format looked like, and we saw what we wanted. We are ready to handle it. We are going to text that
transcription to ourselves. It doesn't seem like that big
of an application does it? Now, I could spin up a whole web server to handle this request, but that sure seems like a lot of work, for a simple, little application. Do you remember this feeling from before? Now, we solved it by using
a serverless function on the Netlify platform. Because, this sort of one-off
handler is very common, Twilio also provides
serverless-function capabilities. What do you say, we get one
of these serverless handlers up and running to send
our text messages out? Guess what? I am going to ask you
to install some tools, but they're super handy
and should be pretty quick. The first thing I'd like for
you install is the Twilio CLI, or command-line interface. This is very much like what
we installed for Netlify. It will let you authenticate
and send commands to Twilio, from the comfort of your own terminal. I love it. If you're a Homebrew user on a Mac, you can install things using Brew, check the teacher's notes for that. We're gonna use npm to install it. We're gonna say npm install, twilio-cli, and we're gonna do this with a -g, which means it's installed globally, and we can run it from wherever we need. Cool, and now we're gonna do,
much like we did with Netlify, we're gonna say Twilio login. This is gonna ask us for our account SID, or string identifier for our account, for our Twilio account. Let's open that up. Let's jump into here, let's go back to the home,
the console dashboard. Your account sits here. There's a little copy button here, so I'm gonna click that and copy that. I'm gonna pop back over to my
terminal, paste that there, and then we will go grab the auth token, which is a secret token that
you should never let out. You can get rid of it, and
I will get rid of it later, in case mine ever ends
up showing to you here, but you don't wanna let that out. That's a secret, secret,
so I pasted, there we go. I am going to call this, I'm gonna call it, my webhook account. I'm gonna call it, webhooks, awesome. The CLI supports plugins, and one of my absolute favorites
is the serverless toolkit. We're going to use it to set
up and deploy our function. Let's go ahead and install it. Now, this is in the notes, if you wanna copy and paste this, but you would do Twilio plugins install, and then @twilio-labs/
and plugin-serverless. If everything is working as planned, you should be able to
write, Twilio serverless, and get some response back, awesome. There are the things that we can do. I am going create, a new Twilio serverless project. In this directory where we're at, up here, so there's this directory called, code. I made one called, Twilio. There's some light changer code in here, that you can look at later. Just kind of, a little
added bonus here for you. Let's go, let's jump into that directory. We're gonna go CD code/twilio, and then inside of this directory here, what we're gonna do, is we're gonna make a
brand new server list, Twilio serverless project. We're gonna use the
serverless plugin to do that. We're gonna say, Twilio serverless:init, and then you name it. Let's call this, idea catcher, right? 'Cause, this is the thing
that we're gonna write to, we're gonna post to this, and then we're gonna make
this thing text to us. We'll do --empty, there's lots of, if you don't specify empty,
like we saw with the Studio, there's lots of templates
that you can use. I think we're gonna start from scratch, 'cause I think it's clearer, in the direction that
we're headed right now. This is preparing a new directory, so it will be all ready for us. Let's go ahead, try to get to the, we're gonna go over into idea catcher now. You'll see up here, there's this Twilio, and we have idea catcher here, and let's take a look at what it added, it added some stuff for us, awesome. You'll see that there's
a folder for functions and there's one for assets. Let's go ahead and let's make a new file in this functions here. I am going to click this
little plus button here to add a new file into this directory, and I'm gonna call it, sendtext.js. All right, this is the
standard boiler plate that you'll need, it's in
the teacher's notes too, if you wanna just copy that. Exports.handler, we're gonna write a function called, handler, and it takes a context, an
event object, and a callback. All right, and we will
make a function there. Callback is how you complete the function, and it's important, because of that asynchronous
nature of JavaScript, you can complete the
function anywhere really. Just to make sure that
we got things working, I'm going to call it. Now, it's a standard-node
callback function. That means that it takes
its first parameter, is any sort of error that occurred. We're not gonna be expecting
any errors with this, and we'll debug, we'll just do my typical, hi, Mom, awesome. The toolkit allows us to run
our own functions locally, so that we can test them,
so let's spin that up. To do that, you do
Twilio serverless start. Awesome, and you'll see that it now says, that there's a function
available on local host 3000. If I go ahead and I click
that, I got, hi, Mom. Hi, Mom, how you doing, Mom? All right, and you'll see in the logs, I've got a 200, and it made
a git request to send test. Excellent, now this server
that we have up and running, is hot reloadable, just like we saw with nodemon or node-mon. This means that you can make a change, and it will be applied without you needing to restart the server. Let's add a little console log here. We'll say, console.log. We're gonna be sending a
text here, sending text. Awesome, so now if I go and
I refresh my mom page again, I did a command+R there,
control+R to do a refresh, and if we look back, we'll see that the console
log popped out here. Again, another 200 (faintly speaking), awesome, without needing to restart. Totally speeds up the development cycle. Speaking of which, let's
get to quickly developing. Okay, so okay, we need
to have our Studio flow post to our server, uh-oh,
our machine is local. We're going to need to
have some way for our flow to be able to see our local server. Do you remember how we did that before? Wanna pause me and see if you can somehow get a public URL for this
function without deploying it? Okay, pause me and see if you can remember how to open up the tunnel. Remember, you can go back, and it's okay if you totally
didn't grok it the first time. Ready? Pause me. (computer beeps) All right, how'd you do? I was talking about ngrok
to open up our tunnel. I'll open up a new terminal
here with the plus, and I'm gonna run that again. That was in my downloads directory, my downloads directory, and
it's ngrok, there we go. ngrok, HTTP 3000, right? That was running on port 3000. There we go, and so now, we'll see that we have
this wild-looking URL. I'm gonna click that, open it up. It's not for that, it's
for a /send-text, right? Isn't it called, send-text? Oh, I wrote, I called it, send-test, but it should be send-text. Let's fix that. If you were following
along, like I hope you were, you probably did that too. You can right-click and choose rename, and you can call this, send-text. I don't know, what happens if
you do that, does it restart? Look at that, it restarted with a new
thing called, send-text. I didn't have to restart
the server, awesome. It's now called, send-text,
and if we're up here, I now have this wonky URL,
ngrok URL that's up and running, That gets the send-text. Now, the Studio flow can see it. I'm gonna grab that URL. I'm gonna go back to the
flow, so over here, Studio. Wanna get back into my idea catcher, and on the record voicemail,
we had left the Beeceptor URL, and now we're gonna paste
our ngrok URL there, awesome. I'm gonna click save, and I'm going to publish, and we'll call. - [Man On Phone] You have a trial account. - I sure do.
- You can remove this message at any time by upgrading
to a full account. Press any key to execute your code. (phone beeps) (phone ringing) - [Kendra-Neural] Hello there, I'd love to hear your wonderful idea. Tell me about it after the beep. (phone beeps) - Here's my idea. I wanna build an app that
gathers ideas from people, and then texts it to me. Awesome, so let's jump over now. I've hung up, let's jump
over and watch it come in. We should see a post to send-text here, in a second, as that
transcription happens. Boom, there it is, awesome. If we go over to our ngrok, we should be able to open that up, and see that the message came through. All right, so what we were looking for, is transcription text, here we go. Here's my idea. I wanna build an app that
gathers ideas from people, and then texts it to me (chuckles). That's pretty good, isn't it? Pretty cool, okay so, let's make sure that we can access that. In our code, where we're sending the text, the way that those values come across, is they're on this second
object here called, event. We'll say, let's do one of
these, we'll say, transcription. That was event.TranscriptionText. Now, do you wanna hear me call back? Do you want me to take
that time to call back, or is there some other way I can do that? This is the awesome flow
that happens, right? I'm gonna go back now. I'm just gonna replay this, and we sent that text again, and now we should see in
my console log, right? If I switch back over to my console log, we see there's the transcription
thing, and there it is, we did it. Awesome, we got the Twilio
CLI installed and all set up. This'll let us interact with our account, and it also has a plugin that allows us to quickly build serverless functions. We got our local server all up and running and opened up a tunnel using ngrok. We're now able to handle the
incoming webhook request. We were able to get
access to the information and now we can also replay those requests. That was quite a bit of work. Nice job, recalling how to get all those things working together. Now this, what we just did, is a very common flow that you'll be doing the more that you develop webhooks. It'll only get more
familiar, as you progress. Why don't we both take a real quick break. I know I need some water. When you come back, we'll wrap up the
handler side of the code, and then we'll deploy this
function to the cloud. So, we don't need to
keep our local machines running all the time. Enjoy your well-deserved break. You're doing great, see you soon. (bright electronic music) Okay, let's write our handler bit. We're gonna write some code that texts you the
transcriptions when they arrive. Let's do this. All right, so I am able
to get the transcription that's being passed, being
published from that webhook. We're able to get the transcription back. Now, we want to text it. The context object here is very handy. It has a handy way to get access to the JavaScript helper library. What that does, is gives
you an authenticated client. We're gonna say, const client
= context.getTwilioClient. Now, here's the thing we need
to be authenticated locally. We're going to need to
provide the toolkit, or official account set and auth token. I'm gonna jump into this .env file here, so see it's this file label .env. We have two things here in this already, and I'm gonna just gonna
grab, again from the console, I'm gonna grab my account SID. You'll see, and it starts with AC, and this of course might
look a little bit different, as the flow goes, check the notes, and I'm gonna go and grab my auth token. I'm gonna come in here,
and I'm gonna paste it, and I'm going to make myself
a note to cancel that, because I just showed you my auth token. That is dangerous, 'cause now you could log
into my account here, and do things on my behalf, because you know what that auth token is. This magic .env file in the
serverless-toolkit world, what this is, is our
environment variables. They will be exposed, actually
on that context object, that we were seeing. We're going to need a couple of things. We're going to need my
actual phone number, right? My phone number that I wanted it text, which is, 1-503-461-0234, please don't call me too late at night. All right, so there's that, and I'm gonna put in my Twilio number, this Twilio number that I have here. Again, what is my Twilio number? My Twilio number is right
here, this is my trial number, I'm gonna grab this, and
paste that here, awesome. I'm gonna save my .env file,
and now we can use those. I'm gonna jump back into the send-text, and we're gonna, under this
sending text, what we'll say is, well, let's move this back up too. All right, so the client, it has access to all the resources, so we can do client.messages. And then, what we wanna do, is we wanna create a new message. What we'll do, is we
will pass in some values. We're gonna send a message
to me or to you, right? Whatever we put in there for phone number, that's what we're gonna do. Then, we're gonna text that
from our trial number, right? Let's say, context, .trial_number, now, or .TWILIO_NUMBER. The reason why this is working, is that number should be verified, right? That phone number that we
put in, I'm in trial mode, I verified with my phone number, so that's why it will be able to text it. We have two from, and we have bodies. These helper messages are
a little intense sometimes. The body that we want, is we wanna say, that there was a new
idea that came in, right? Then, we just want to kind
of, grab what we did before, where we got the
transcription text, right? Here's the new idea. That's the body of the
message, seems pretty good. Maybe, you know what we should do? We should also just drop
one of those in there, I'm gonna pop a bulb in there. I like that my burrito
is a commonly used emoji. All right, awesome, it's
time to, I think we're good. I don't think we need to
say, hi to mom anymore. We'll be sending the text. Now, because we didn't put our
personal information in here, we could share this file with people, and they could just copy
it and paste it, right? Like we could put this up on GitHub, and somebody could just use it. In fact, this is in the notes, and you can just use this code
without changing anything, except for your personal
environment number. Your phone number and your Twilio account, and your Twilio number, are
gonna be different than mine, but the code is the same. That's the power of environment variables. We have the same code in
different environments. Now, there's something tricky that we need to be really
careful about here. This create call here off of messages, this is asynchronous. We saw this before, it's promise-based, which means it provides functions
to return values or errors that will be called when a value
arrives or an error occurs, which is a mouthful, I realize. What we wanna do, is we
want to call the callback, only after the message has been sent. Otherwise, it will just
be over right away, right? 'Cause this'll just,
finish will be right over. We need to put the callback
inside of the then. So, what we're gonna do
is we're gonna chain off of the promise that's returned. When we say .then, and that's gonna return a function, and it's gonna return a
function that could just say, it will be the message, right? The message that was created,
if it was successful. What we'll do here, is
we'll do the callback, and we'll, there was no
problems and we will return. We can return a message,
we say, sent message. That message object that comes back, has an identifier as well. Let's put this on a separate line. Let's make that a little
bit more friendly. You can do that all in one line like that. Let's see, so we're gonna have a function, the then is gonna return,
the then is going to, expects a function that takes
whatever the return value was, if it was successful, and then
it will run this function. That's when we want the function to end. We don't want it to end beforehand. That's, again, this is
that asynchronous behavior. We'll put a semi-colon here at the end, and then we are going to come
and we're gonna catch this. The catch also expects, if there is an error, let's, the catch expects if there is an error, that you say something about it. That this is a great
place to do the callback, and just pass the error into it. Okay, so let's walk this one more time. We're gonna use the context again, an authenticated Twilio client, and it's gonna use values
from our environment, our account SID and our auth token, to make sure that we are
authenticated properly. And then, it's going to, for
this authenticated client, it's going to make a new message. It's going to create a brand new message, and it's gonna send it to a
phone number, our phone number, the mobile number that
you registered with. It's going to send it from
our trial number, right? That's the trial number
that we have in there. It's going to pass across
the transcription text. That was on the event that
came from the request, and if that were successful, we're going to say the function is over and no error happened. And then, we'll just write something else, it's not expecting anything. If there is a catch,
if there is a problem, we are going to call that
callback with the error. We could put some logging in
here too, why don't we do that? We'll say, console.log, and we'll say, we'll just do a sent message,
and we'll do a message.sid. Again, that's a string identifier. If there is an error, we'll do console.error,
and we'll say, uh-oh! Then, we'll output that error, cool, or at least the string version
of that error, awesome. Okay, I am going to
clear things down here. I have that saved. Let's run this locally first, since we were just doing
our development thing there, I had stopped my server. Again, that's Twilio server. Let's start, so that will
start the local server here. Looks like I was in the wrong directory. That's what that means, so I need to get in my
idea catcher directory, and I will run that again. That was the up and down arrows to get back to the previous commands, Twilio serverless start. All right, here we go. This is what was running before, I still have my ngrok running, and my flow is still pointing to things. That means I should able to go back to my ngrok, and just go ahead and do another replay. I should receive a text message, and look at that, sent from
my Twilio trial account. There's a new idea, and it
gathers ideas from people, and texts it to me, awesome, cool. We have the text working, we have done our local development flow, and now we wanna be able to not have to run this on
our computers, right? We don't wanna keep our computer up and running all the time,
so we're gonna deploy it. The way that we do that
is very, very easily, we say, Twilio, swerverless,
serverless deploy. It's building up everything we need here. You'll notice that what it's gonna do, is it's gonna take the name of our project and put some extra stuff at
the end to make it unique. It's got this little four-digit number, and it's got this .dev, 'cause that's the
environment that you are in. By default, it puts you in
the development environment. Let's go ahead. It's deployed, believe it or
not, this is up and running. We could actually hit that,
but I'm just gonna grab this. I'm gonna pop back over to my flow, and jump back in here. You feelin' my flow? I'm gonna go into record voicemail, and I am going to, now the
transcription URL is an actual, real-live hosted, elastic in case I get
a whole bunch of ideas, which I hope that I do. I'm gonna click save, and
that is publicly accessible. It's now running on the server. The final test, let's go ahead
and give our number a call. - [Man On Phone] You have a trial account. You can remove this message at any time, by upgrading to a full account. Press any key to execute your code. (phone beeps) (phone ringing) - [Kendra-Neural] Hello there, I'd love to hear your wonderful idea. Tell me about it after the beep. (phone beeps) - Yeah, I have an idea to
make my dog lamp light up in Morse code, whenever
I receive a new idea, that gets transcribed. Wouldn't that be great? I should just about any second now, I should get a message with a
very strange idea (chuckles) about sending Morse code over a dog lamp. I think I might actually
write that, oh, there, got it. It transcribed it exactly right, awesome. We got it deployed, and now
we can shut our computers off. Now, you might have noticed
that this was deployed to dev. I know that we talked about that, you can also deploy to dev or staging, and then you can deploy to production. That way you can develop
as a team in one place, if you needed to. There's more on that in the notes, if you're interested in it, but they're just different environments. Just keep that in mind, you can have different
environments hosted up there. With that, we did it. That is awesome. Did you see how the webhook
skills that you've picked up are fairly universal? It's pretty neat, right? I hope you're feeling
confident in your ability. First, we were able to provide a handler for the lifecycle
hook of an incoming text message to our number. We did this with a static TwiML Bit, but remember, this is a webhook. As long as we returned valid
TwiML, we could do anything. We didn't end up using the
body of the text message, that was sent to us, but
we definitely could have. Like for instance, I could make it so that if
someone texted my number, a color, it could change
the dog color light. Like for instance, if I type blue. There we go, it responds
to the incoming message. I deployed that, it's a
simple, serverless function. It's in the notes, and it responds to an
incoming text message. We also used a no-code solution to answer an incoming
call and record a message. What the tool did for us was to deploy and return the necessary TwiML code to render the application. As more and more of
these no-code solutions start popping up, look for how they're
making use of webhooks. You can impress your friends
like, you can be like, well, actually that's just a webhook. Actually, never say that. Never say, well, actually,
it's not a good look. We saw how the debugging tools,
like Beeceptor and ngrok, work to capture what was
posted from the webhook. The replay feature saves a ton of time. I'm glad that you've got
that in your tool belt. We also got to use another
serverless function. Those things are awesome. Little snippets of code that
you don't need to manage. They're elastic, meaning they scale up and down automatically, and almost all of the serverless providers give a very generous free tier. Until your application gets
very popular, which it will, you don't need to pay anything at all. These are great for
little one-off scripts, like webhook handlers. You did it, made it to
the end of this course. Nice work, I hope you enjoyed yourself. I know I did. I hope you now have a ton of ideas, that you can't wait to
implement with webhooks. Remember if you run out of ideas, go explore some no-code automation sites, like IFTTT or Zapier. There are tons of great ideas there. I can't wait to see what you build. Make sure to let me know about it. I've spun up a number, that's similar to what we built together. I'll use it to capture your
feedback on this course. I use the transcription webhook, to add your feedback to
a Google spreadsheet. I hope that you're proud
of your new skills. Ooh, that reminds me. - Send him in. (intense music) - I have something pretty
important to talk with you about, something serious, the power
that you wield is needed. Now, more than ever, we are living in some dark, dark times. Most of our time is spent
online in virtual worlds. Worlds that are governed
by the laws of code. Somebody writes that code,
you're gonna write that code. You know, a kid's uncle
once famously said, "with great power, comes
great responsibility." I guess that's just
really a roundabout way of me asking you, is
the code that you write, gonna be used for good or not? It's your choice, really. I'm asking you to take a vow. I want you to write
code that unlocks hope, power, and freedom for all of humanity. I'm asking you to become an operator. I want you to join our quest. I need your help to, line? - Save the cloud. - Of course, we need your help to save the cloud. Thank you, thank you very much. - [Woman] Thank you. - When should I? - Oh, oh, no need to
call us, we'll call you. - Oh, right, right. I'm still waiting for
them to call me back. They got tired of me calling and calling, to see if I landed it. Those Hollywood folks should
stick to their principles. I hope I get it, 'cause I
love that TwilioQuest game. Have you played it yet? It's super addicting. It has awesome content for
those just getting started, and those who have been
there for a long time. It has a built-in dev
environment, fun side quests, like contributing to open source. It covers JavaScript, PHP, and Python. There are new updates all of the time, and OMG, the original soundtrack, also, I've got a serious
robo-crush on Cedric, he's super adorable. I can't recommend it enough. Finally, if you enjoyed this course, please let others know about it. I'm sure they'll thank
you for hooking them up. Thanks for hanging out and
we'll see you real soon. (upbeat electronic music)