diff --git a/en-US/2023-08-25-chat-apis/1-project-overview.txt b/en-US/2023-08-25-chat-apis/1-project-overview.txt index 6f91137d..2a2475ba 100755 --- a/en-US/2023-08-25-chat-apis/1-project-overview.txt +++ b/en-US/2023-08-25-chat-apis/1-project-overview.txt @@ -1,5 +1,5 @@ [00:00:00] ->> What we're gonna build today is we're gonna build a custom bot for slack. That custom bot is going to feature a slash command, which will allow someone to say I have a request and that that request is going to take user input and save that user input to notion. +>> What we're gonna build today is we're gonna build a custom bot for slack. That custom bot is going to feature a slash command, which will allow someone to say I have a request and that request is going to take user input and save that user input to notion. [00:00:16] We're also gonna have a context shortcut so the little three dots on a message. Where you can drop that down and then click a process reminder so that the bot will tell somebody like, hey, this looks like it's a request. If you want us to measure this, you've got to put it into the request form, here's the slash command to make that happen. @@ -26,7 +26,7 @@ This is one of the things that gets really challenging when you start building w And have it up on a production URL for testing which makes it so slow and so frustrating, so instead what we're gonna do is we're gonna use a live tunneling service. That will allow us to keep up a local development environment running, but also give it a live URL so that we can test as we go. [00:02:41] -We're gonna use serverless functions to power our command so that we can keep it free. Our bot does not need to be constantly running. Our bot is all based on incoming requests. So you're gonna run a slash command which says, hey bot, that'll wake the bot up. You've got the cron job, which is gonna be running on a regular schedule, so that'll wake the bot up, and each of these things is something that is on a like a poll basis. +We're gonna use serverless functions to power our command so that we can keep it free. Our bot does not need to be constantly running. Our bot is all based on incoming requests. So you're gonna run a slash command which says, hey bot, that'll wake the bot up. You've got the cron job, which is gonna be running on a regular schedule, so that'll wake the bot up, and each of these things is something that is on a like a pull basis. [00:03:05] We don't need the on a push basis, sorry. We don't need the command to be listening or reading every message or anything like that, it's so we'll use a serverless function, keep it free. Cron jobs are gonna be used to handle our weekly reminders and, this is gonna be based on a few accounts so the first thing is we're gonna be working from a GitHub repo. @@ -47,16 +47,16 @@ Again, everything that we're using today is gonna be on free tier, so no paid ac Again, you could use ngrok and then any serverless functions provider that you wish, this is not a workshop that's like tied to this specific account. This is just the way that I found that is the fastest and least painful to get things set up. The free tier of these services are gonna be all you need, again, just as a reminder, tools that you gonna need, you gonna need git on your computer. [00:05:13] -You gonna need Node v16 higher, the Netlify CLI is how we're gonna set up that live tunnel, so y'all gonna need that. You'll need permission to clone repos and run third-party code to your computer before you get started, make sure that you have permission to clone, and push to GitHub repos. +You gonna need Node v16 higher, the Netlify CLI is how we're gonna set up that live tunnel, so y'all gonna need that. I will walk you through in setting up that part. You'll need permission to clone repos and run third-party code on your computer. If you are on a work computer that can sometimes be an issue if your computer is really locked down. So, double check that before you get started, make sure that you have permission to clone, and push to GitHub repos. [00:05:38] -So a few things that I'll be using that aren't required for this but just to give some context on on the stack that I use. VS code is what I'll be using is both my code editor and as my terminal I like it, you can use whatever you want. +So a few things that I'll be using that aren't required for this but just to give some context on the stack that I use. VS code is what I'll be using is both my code editor and as my terminal I like it, you can use whatever you want. [00:05:52] -GitHub CLI, I use this for managing repos, it's delightful to use, i love it, you don't need it, but that's what I'll be using whenever you see the GH command, that's the GitHub CLI. And again, these are my preferences they're not requirements you can work with or without these of you if you wish. +GitHub CLI, I use this for managing repos, it's delightful to use, i love it, you don't need it, but that's what I'll be using whenever you see the GH command, that's the GitHub CLI. And again, these are my preferences they're not requirements you can work with or without these if you wish. [00:06:11] -Some assume knowledge, what I assume you're gonna know as I go through this workshop, some intermediate knowledge of JavaScript, so, nothing super in-depth. This isn't gonna be like an algorithms whiteboard interview or anything. But what I will be assuming is that you understand the basic grammar of the language, you know, how to set up, how to create variables, how to create functions, how to do a loop and things like that. +Some assumed knowledge, what I assume you're gonna know as I go through this workshop, some intermediate knowledge of JavaScript, so, nothing super in-depth. This isn't gonna be like an algorithms whiteboard interview or anything. But what I will be assuming is that you understand the basic grammar of the language, you know, how to set up, how to create variables, how to create functions, how to do a loop and things like that. [00:06:33] It just, we won't do like an intro to JavaScript as part of this workshop. We'll be sending and receiving data via API, and I'm not gonna go deep into the specifics of that, so we'll be using the Fetch API. If you've never used the Fetch API, the docs are on the Mozilla developer network, the MDN docs, so go check those out, but you won't need the depth of it. diff --git a/en-US/2023-08-25-chat-apis/1-project-overview.vtt b/en-US/2023-08-25-chat-apis/1-project-overview.vtt index 236f39ae..a9a52fe4 100755 --- a/en-US/2023-08-25-chat-apis/1-project-overview.vtt +++ b/en-US/2023-08-25-chat-apis/1-project-overview.vtt @@ -17,7 +17,7 @@ to say I have a request and 4 00:00:10.865 --> 00:00:16.244 -that that request is going to take user +that request is going to take user input and save that user input to notion. 5 @@ -268,7 +268,7 @@ schedule, so that'll wake the bot up, 56 00:03:01.897 --> 00:03:05.969 and each of these things is something -that is on a like a poll basis. +that is on a like a pull basis. 57 00:03:05.969 --> 00:03:08.473 @@ -444,16 +444,16 @@ the Netlify CLI is how we're 92 00:05:18.098 --> 00:05:22.441 gonna set up that live tunnel, -so y'all gonna need that. +so y'all gonna need that. I will walk you through in setting up that part. 93 -00:05:22.441 --> 00:05:26.306 +00:05:22.441 --> 00:05:26 You'll need permission to clone repos and 94 00:05:26.306 --> 00:05:32.102 -run third-party code to your -computer before you get started, +run third-party code on your +computer. If you are on a work computer that can sometimes be an issue if your computer is really locked down. So, double check that before you get started, 95 00:05:32.102 --> 00:05:38.563 @@ -468,7 +468,7 @@ that aren't required for this but 97 00:05:42.353 --> 00:05:45.224 just to give some context -on on the stack that I use. +on the stack that I use. 98 00:05:45.224 --> 00:05:48.876 @@ -501,11 +501,11 @@ they're not requirements you can work with 104 00:06:10.026 --> 00:06:11.913 -or without these of you if you wish. +or without these if you wish. 105 00:06:11.913 --> 00:06:15.590 -Some assume knowledge, what I assume +Some assumed knowledge, what I assume you're gonna know as I go through this 106 diff --git a/en-US/2023-08-25-chat-apis/10-handling-a-shortcut.txt b/en-US/2023-08-25-chat-apis/10-handling-a-shortcut.txt index e6c6a73a..8f7894d5 100755 --- a/en-US/2023-08-25-chat-apis/10-handling-a-shortcut.txt +++ b/en-US/2023-08-25-chat-apis/10-handling-a-shortcut.txt @@ -1,5 +1,5 @@ [00:00:00] ->> So now that we've got the the bot responding to the slash command and kind of putting the details from the payload from the user input back into chat, we wanna do one more thing before we start dealing with saving that input. Which is, if somebody's not following our process, which is pretty common on teams that I've been on, it's it's pretty standard for somebody to kind of fly in from a meeting and say, hey, I don't really like chocolate. +>> So now that we've got the bot responding to the slash command and kind of putting the details from the payload from the user input back into chat, we wanna do one more thing before we start dealing with saving that input. Which is, if somebody's not following our process, which is pretty common on teams that I've been on, it's pretty standard for somebody to kind of fly in from a meeting and say, hey, I don't really like chocolate. [00:00:27] If I can type. And in this case, they're starting a food fight but in a work context, they would be saying, hey, we need x or y. We need your help with this. We were working on x launch. And the message flies into Slack, and then who's responsible for keeping up on that, right? @@ -14,13 +14,13 @@ But doing it this way it's a tiny conflict even if it's not actually that tense And that drains energy, it uses up some of your spoons and leaves you with less in the tank to do your job. So a better way to do this is to let a robot do it for us. So we are going to add a context menu shortcut, so that we can ask people without having to type anything to them. [00:01:42] -We just wanna be able, instead of having to do it this way. We wanna open up this menu here, and then ask them to do a thing. So, to handle that, we're going to go back to the browser. And we're gonna get into our interactivity in shortcuts menu again, and we're gonna create a new one. +We just wanna be able, instead of having to do it this way. We wanna open up this menu here, and then ask them to do a thing. So, to handle that, we're going to go back to the browser. And we're gonna get into our interactivity and shortcuts menu again, and we're gonna create a new one. [00:02:02] Now to create a new one, we want this to work on messages. So there's an option globally to just hit that little lightning bolt icon and it'll give you options of things you wanna do. But in our case, we're responding directly to a message, so we want this to be on Messages. [00:02:15] -So we're gonna hit that hit next and then we are going to give it some details. So the details that we want to include our request to food fight and that's gonna be what shows up in the menu. And then we wanna have a short description and this is going to be something that just kind of gives some details on on why you would use this context menu. +So we're gonna hit that hit next and then we are going to give it some details. So the details that we want to include our request to food fight and that's gonna be what shows up in the menu. And then we wanna have a short description and this is going to be something that just kind of gives some details on why you would use this context menu. [00:02:38] So, did your coworker just offend your food sensibilities? Ask them to start a food fight so you can lay into them for eating incorrectly. And then as a callback ID, this can be anything you want as long as it's unique, and I'm gonna call this one start food fight nudge. @@ -38,28 +38,28 @@ Then we can collapse these so that we can focus on just the piece that we're wor Next, we wanna know who was the person that needs to be nudged because we're gonna tag them. So user id, and that's gonna come out of the payload user id. Then we need to know what the thread is that we're in because what we're doing is we're going to send this as a response to their message in a thread as opposed to a public channel, which it's just a little bit more subtle than like publicly blasting somebody for not following the process. [00:04:27] -We do want it to be public so that people can see that there is a process and it needs to be followed. But we don't need to do the the main channel, at user put them on blast kind of thing. So we're gonna grab the thread time stamp and there are two places that can come from. +We do want it to be public so that people can see that there is a process and it needs to be followed. But we don't need to do the main channel, at user put them on blast kind of thing. So we're gonna grab the thread timestamp and there are two places that can come from. [00:04:43] -If you are already in a thread, there's gonna be the the parent thread timestamp, and if you are replying to a message with its first reply, you're just gonna use the message timestamp itself. So we're gonna check if it's in a thread first, that's payload message thread timestamp. +If you are already in a thread, there's gonna be the parent thread timestamp, and if you are replying to a message with its first reply, you're just gonna use the message timestamp itself. So we're gonna check if it's in a thread first, that's payload message thread timestamp. [00:04:59] -And if that doesn't exist, we're gonna get the payload message timestamp. With those details, we can send our message, so we're gonna await slack API. We're gonna use the chat.postMessage, and what we wanna send is the channel, so that's where it's going, the thread ts, so that it goes into the right reply, and then we need to set up our text. +And if that doesn't exist, we're gonna get the payload message timestamp. With those details, we can send our message, so we're gonna await Slack API. We're gonna use the chat.postMessage, and what we wanna send is the channel, so that's where it's going, the thread ts, so that it goes into the right reply, and then we need to set up our text. [00:05:22] -And so this is going to be just a nudge to remind somebody that like, hey, you should use the process. So we'll say, hey and tag them and that's their user id. And again, these pointy boys are a way of slack letting you link in a not markdown, but they call it markdown way. +And so this is going to be just a nudge to remind somebody that like, hey, you should use the process. So we'll say, hey and tag them and that's their user id. And again, these pointy boys are a way of Slack letting you link in a not markdown, but they call it markdown way. [00:05:45] And we can say an opinion like this one deserves a heated public debate. Run the and then we wanna use some backticks here so we're gonna escape them and we'll say slash food fight. Wanna make this wrap. Food fight slash command in a main channel to start one. [00:06:13] -And I call out main channel because slash commands don't work in threads, which is a little bit of a pain. And it's a bit confusing because like the Jiffy command does work in threads, but that's a special case that Slack. They just decided that that was the way things were gonna be. +And I call out main channel because slash commands don't work in threads, which is a little bit of a pain. And it's a bit confusing because like the "giphy" command does work in threads, but that's a special case that Slack. They just decided that that was the way things were gonna be. [00:06:28] There's no way to make your app work in a thread so you just have to nudge people to go back to the main thread. If they do try to use it in a thread, it will tell them that. So it's not a big deal, it's just a thing to be aware of. [00:06:40] -So I'm gonna save this, And now if I go back out to the slack instance, I'm gonna refresh by hitting Cmd+R, because sometimes it takes a second for this to load. I have two of these for reasons I don't understand. But the one that we just added is the top one here, and that is going to show our message. +So I'm gonna save this, And now if I go back out to the Slack instance, I'm gonna refresh by hitting Cmd+R, because sometimes it takes a second for this to load. I have two of these for reasons I don't understand. But the one that we just added is the top one here, and that is going to show our message. [00:07:05] So it created a thread, it tagged the person who made the request, and it gives them a next step. So this is a nice little process nudge that gives people a clue of what they should be doing next, right? So again, you're just trying to take that mental burden, that emotional burden off of somebody of having to go in and be the process cop. diff --git a/en-US/2023-08-25-chat-apis/10-handling-a-shortcut.vtt b/en-US/2023-08-25-chat-apis/10-handling-a-shortcut.vtt index 71d9cf20..72de4c7c 100755 --- a/en-US/2023-08-25-chat-apis/10-handling-a-shortcut.vtt +++ b/en-US/2023-08-25-chat-apis/10-handling-a-shortcut.vtt @@ -2,7 +2,7 @@ WEBVTT 1 00:00:00.140 --> 00:00:04.533 -So now that we've got the the bot +So now that we've got the bot responding to the slash command and kind 2 @@ -22,7 +22,7 @@ process, which is pretty common on teams 5 00:00:17.676 --> 00:00:21.109 -that I've been on, it's it's pretty +that I've been on, it's pretty standard for somebody to kind of 6 @@ -146,7 +146,7 @@ we're going to go back to the browser. 31 00:01:56.470 --> 00:01:59.901 And we're gonna get into our interactivity -in shortcuts menu again, and +and shortcuts menu again, and 32 00:01:59.901 --> 00:02:02.160 @@ -197,7 +197,7 @@ and this is going to be something that 42 00:02:33.484 --> 00:02:38.120 -just kind of gives some details on on +just kind of gives some details on why you would use this context menu. 43 @@ -344,7 +344,7 @@ it needs to be followed. 73 00:04:32.133 --> 00:04:35.122 But we don't need to do -the the main channel, +the main channel, 74 00:04:35.122 --> 00:04:37.727 @@ -353,7 +353,7 @@ at user put them on blast kind of thing. 75 00:04:37.727 --> 00:04:40.644 So we're gonna grab -the thread time stamp and +the thread timestamp and 76 00:04:40.644 --> 00:04:43.259 @@ -362,7 +362,7 @@ there are two places that can come from. 77 00:04:43.259 --> 00:04:47.912 If you are already in a thread, there's -gonna be the the parent thread timestamp, +gonna be the parent thread timestamp, 78 00:04:47.912 --> 00:04:51.101 @@ -391,7 +391,7 @@ get the payload message timestamp. 83 00:05:06.973 --> 00:05:11.220 With those details, we can send our -message, so we're gonna await slack API. +message, so we're gonna await Slack API. 84 00:05:11.220 --> 00:05:13.757 @@ -424,7 +424,7 @@ that's their user id. 90 00:05:36.270 --> 00:05:41.255 And again, these pointy boys -are a way of slack letting you +are a way of Slack letting you 91 00:05:41.255 --> 00:05:45.954 @@ -467,7 +467,7 @@ which is a little bit of a pain. 99 00:06:19.110 --> 00:06:23.966 And it's a bit confusing because like -the Jiffy command does work in threads, +the "giphy" command does work in threads, 100 00:06:23.966 --> 00:06:26.406 @@ -501,7 +501,7 @@ it's just a thing to be aware of. 106 00:06:40.760 --> 00:06:46.626 So I'm gonna save this, And now if I -go back out to the slack instance, +go back out to the Slack instance, 107 00:06:46.626 --> 00:06:49.321 diff --git a/en-US/2023-08-25-chat-apis/12-getting-items-from-notion.txt b/en-US/2023-08-25-chat-apis/12-getting-items-from-notion.txt index 1e03397e..98486a4d 100755 --- a/en-US/2023-08-25-chat-apis/12-getting-items-from-notion.txt +++ b/en-US/2023-08-25-chat-apis/12-getting-items-from-notion.txt @@ -2,19 +2,19 @@ >> So next let's create a function that's gonna let us get the new item. So anything in our database that has it, it's in the the new column the to do items. So we can check how that's gonna work. It's gonna return a promise. And that promise is going to have a new item in it. [00:00:19] -And that's gonna be an array. And that, just to show what we're actually trying to do here, if we close this one and open up this one, we are looking at this column. We want to run a query that will only give us back these fields. We don't care about stuff that's in progress because that means it's been assigned to somebody or is otherwise in motion and we don't care about stuff is complete. +And that's gonna be an array. And that, just to show what we're actually trying to do here, if we close this one and open up this one, we are looking at this column. We want to run a query that will only give us back these fields. We don't care about stuff that's in progress because that means it's been assigned to somebody or is otherwise in motion and we don't care about stuff that's complete. [00:00:45] We only care about things that need action. So things in the to do column are the things that need someone to actually triage them, look through them, make sure that they're valid, so on and so forth. So then we can go into our code again and let's actually write out that filter. [00:01:06] -So for this one, we are going to use notion data that is going to be an await notion Api. And we're going to send databases and then our database ID NOTION_DATABASE-ID and query. So we're running a query against the database. And this looks a little more like the Slack API has those chat.postMessage, which makes it look very fancy. +So for this one, we are going to use notion data that is going to be an await notion Api. And we're going to send databases and then our database ID NOTION_DATABASE_ID and query. So we're running a query against the database. And this looks a little more like the Slack API has those chat.postMessage, which makes it look very fancy. [00:01:44] -But that is just the URL. Whereas with these notion ones, they look a little more familiar URL endpoints. Then we're gonna pass in our filter. And so this is, one of a few things you can also pass in salt and a few other pieces, but what we care about is specifically the filter, because that's gonna allow us to limit down what we're getting to just the stuff we need. +But that is just the URL. Whereas with these notion ones, they look a little more familiar URL endpoints. Then we're gonna pass in our filter. And so this is, one of a few things you can also pass in sort and a few other pieces, but what we care about is specifically the filter, because that's gonna allow us to limit down what we're getting to just the stuff we need. [00:02:06] -So we're gonna go with property status. And that is aligned to these properties here. So when you're looking, you can see the status spice level submitter. And the reason that these are written like they are, not with spaces and stuff is because knowshon doesn't have a differentiation between what displays on the screen and how you run these filters. +So we're gonna go with property status. And that is aligned to these properties here. So when you're looking, you can see the status spice level submitter. And the reason that these are written like they are, not with spaces and stuff is because Notion doesn't have a differentiation between what displays on the screen and how you run these filters. [00:02:30] So if you want something like spice level in your code then you would also set spice level here otherwise you're gonna have like quoted string keys with spaces in them and stuff it's your call on how you wanna manage that. It doesn't really matter one way or the other. @@ -35,7 +35,7 @@ Then you get to destructure that because it's an array. Then you get your text, But it does mean that these accessors here get a little intense. And what you would probably wanna do is in a more mission-critical application. Maybe look into some kind of runtime validation of the input that's coming in like Zod to make sure that you don't, as you're drilling into these items, if something is misplaced, if somebody updates the notion database without telling you there are a lot of things that could get weird here. [00:05:01] -But in our case, we have control over it. We know how it's working and so we can kinda just dive in and be happy. So I'm gonna get the spice level as well. That spice level is item.properties.spiceLevel.select.name, and then our status Is item.properties.status, capital.status.name. And then we can return our open items. +But in our case, we have control over it. We know how it's working and so we can kinda just dive in and be happy. So I'm gonna get the spice level as well. That spice level is item.properties.spiceLevel.select.name, and then our status Is item.properties.Status.status.name. And then we can return our open items. [00:05:40] Okay, so that is one helper piece ready to go we're happy about that. diff --git a/en-US/2023-08-25-chat-apis/12-getting-items-from-notion.vtt b/en-US/2023-08-25-chat-apis/12-getting-items-from-notion.vtt index 4dce4c1e..b8ffdbe9 100755 --- a/en-US/2023-08-25-chat-apis/12-getting-items-from-notion.vtt +++ b/en-US/2023-08-25-chat-apis/12-getting-items-from-notion.vtt @@ -58,7 +58,7 @@ is otherwise in motion and 13 00:00:44.022 --> 00:00:45.760 -we don't care about stuff is complete. +we don't care about stuff that's complete. 14 00:00:45.760 --> 00:00:47.630 @@ -99,7 +99,7 @@ And we're going to send databases and 22 00:01:22.366 --> 00:01:31.920 then our database -ID NOTION_DATABASE-ID and query. +ID NOTION_DATABASE_ID and query. 23 00:01:31.920 --> 00:01:34.390 @@ -132,7 +132,7 @@ Then we're gonna pass in our filter. 29 00:01:53.130 --> 00:01:56.824 And so this is, one of a few things -you can also pass in salt and +you can also pass in sort and 30 00:01:56.824 --> 00:02:01.678 @@ -165,7 +165,7 @@ like they are, not with spaces and 36 00:02:23.358 --> 00:02:28.058 -stuff is because knowshon doesn't have +stuff is because Notion doesn't have a differentiation between what displays on 37 @@ -369,11 +369,11 @@ and 79 00:05:22.302 --> 00:05:29.670 -then our status Is item.properties.status, +then our status Is item.properties.Status 80 00:05:29.670 --> 00:05:33.811 -capital.status.name. +.status.name. 81 00:05:33.811 --> 00:05:37.525 diff --git a/en-US/2023-08-25-chat-apis/14-creating-a-reminder.txt b/en-US/2023-08-25-chat-apis/14-creating-a-reminder.txt index d4a58303..9ecbd290 100755 --- a/en-US/2023-08-25-chat-apis/14-creating-a-reminder.txt +++ b/en-US/2023-08-25-chat-apis/14-creating-a-reminder.txt @@ -5,7 +5,7 @@ And inside reminder, we're going to set up a new handler that is a type though, so we can make that a type. And then I also want schedule, which is the way that Netlify functions handle cron jobs. I'm also going to import get new items from the notion, and I'm gonna import blocks, and the Slack API helper from the Slack utils. [00:01:06] -Then we're gonna create a new function called postnewNotionItemsToSlack. Nice descriptive function name there. And that's gonna be an async function that is going to grab the items by a weight, getNewItems. So now we've got the items from Notion in this items variable and we can send them off to Slack. +Then we're gonna create a new function called postnewNotionItemsToSlack. Nice descriptive function name there. And that's gonna be an async function that is going to grab the items by await getNewItems(). So now we've got the items from Notion in this items variable and we can send them off to Slack. [00:01:32] So we're gonna await Slack API and use the chat.postMessage, send it to our general channel, which I'm going to grab out of here. So click on the channel itself, go down to the bottom, grab that channel. We could have put that into the environment. No real reason that I didn't other than I didn't think about it until just now. @@ -29,7 +29,7 @@ So I can just add a pipe and then the text I want it to be, and Notion will turn So then we can join the whole thing using a newline character. And that way what we get is a multi-paragraph chunk of text that gets sent to the browser or into the the Slack channel. So we can save that. And then underneath it, we're going to return statusCode of 200. [00:04:29] -Now cron jobs don't need anybody, so you don't have to send one back. And to actually set up the cron part of this, we're gonna export a const called handler, and then we imported that schedule function. So the first argument here is gonna be the cron, and then the second piece is gonna be the function that gets called. +Now cron jobs don't need any body, so you don't have to send one back. And to actually set up the cron part of this, we're gonna export a const called handler, and then we imported that schedule function. So the first argument here is gonna be the cron, and then the second piece is gonna be the function that gets called. [00:04:51] So I'm gonna use, I could just guess at what one of these is, but instead, I'm gonna use a really cool tool called crontab.guru. And what this does is, it lets you kind of do this a little more human readably. So if you come in here and you say, we'll just set this to be like this, every minute it would run our cron job. @@ -50,5 +50,5 @@ So now this is running. And if I go out to my browser, only in testing, you can We're running on This version. So I can replace the hash there and hit it. And it says, you perform an HTTP request for the reminder, which is a scheduled function. You can do it to test locally, but it won't work in production. Now assuming that did what we wanted, hey, here we go. [00:07:28] -We've got a reminder from our Food Fight app that says, what all of the open items are, and then has a link to follow through and see them all in notion. +We've got a reminder from our Food Fight app that says, what all of the open items are, and then has a link to follow through and see them all in Notion. diff --git a/en-US/2023-08-25-chat-apis/14-creating-a-reminder.vtt b/en-US/2023-08-25-chat-apis/14-creating-a-reminder.vtt index c7bd5f21..65c9f5a7 100755 --- a/en-US/2023-08-25-chat-apis/14-creating-a-reminder.vtt +++ b/en-US/2023-08-25-chat-apis/14-creating-a-reminder.vtt @@ -78,7 +78,7 @@ function that is going to 18 00:01:22.114 --> 00:01:25.883 -grab the items by a weight, getNewItems. +grab the items by await getNewItems(). 19 00:01:25.883 --> 00:01:30.335 @@ -278,7 +278,7 @@ we're going to return statusCode of 200. 61 00:04:29.352 --> 00:04:33.708 -Now cron jobs don't need anybody, +Now cron jobs don't need any body, so you don't have to send one back. 62 @@ -472,5 +472,5 @@ app that says, what all of the open 102 00:07:33.943 --> 00:07:38.933 items are, and then has a link to follow -through and see them all in notion. +through and see them all in Notion. diff --git a/en-US/2023-08-25-chat-apis/15-deploying-to-netlify.txt b/en-US/2023-08-25-chat-apis/15-deploying-to-netlify.txt index 34d062d2..0c190443 100755 --- a/en-US/2023-08-25-chat-apis/15-deploying-to-netlify.txt +++ b/en-US/2023-08-25-chat-apis/15-deploying-to-netlify.txt @@ -1,5 +1,5 @@ [00:00:00] ->> So the only thing that we have left to do here is actually deploy it, which will give us the ability to see this chron job running. So I'm gonna stop here and I'm going to see all these things that I've got, commit everything. Git commit, let me check out a new branch actually. +>> So the only thing that we have left to do here is actually deploy it, which will give us the ability to see this cron job running. So I'm gonna stop here and I'm going to see all these things that I've got, commit everything. Git commit, let me check out a new branch actually. [00:00:23] We'll call this a workshop. Okay, then I'm gonna git commit everything and say working chatops flow. We're gonna git push origin and workshop. Okay, so this is pushed up to my particular branch here. And then if I go into Netlify and look at my app, I've just deployed. diff --git a/en-US/2023-08-25-chat-apis/15-deploying-to-netlify.vtt b/en-US/2023-08-25-chat-apis/15-deploying-to-netlify.vtt index 10bf7bfd..4c84c6b0 100755 --- a/en-US/2023-08-25-chat-apis/15-deploying-to-netlify.vtt +++ b/en-US/2023-08-25-chat-apis/15-deploying-to-netlify.vtt @@ -8,7 +8,7 @@ to do here is actually deploy it, 2 00:00:05.472 --> 00:00:10.474 which will give us the ability -to see this chron job running. +to see this cron job running. 3 00:00:10.474 --> 00:00:12.492 diff --git a/en-US/2023-08-25-chat-apis/16-wrapping-up.txt b/en-US/2023-08-25-chat-apis/16-wrapping-up.txt index 1cbc24dd..83767dfa 100755 --- a/en-US/2023-08-25-chat-apis/16-wrapping-up.txt +++ b/en-US/2023-08-25-chat-apis/16-wrapping-up.txt @@ -2,7 +2,7 @@ >> The app we built today was built from a standpoint of kind of showing an intentionally silly example so that we didn't get too hung up on the details of how your team should handle incoming requests. But the functionality that we've gone through here is applicable to Slack, it's applicable to Discord, it'll work in any chat app that gives you API access. [00:00:22] -And you don't have to use notion, you can use any project management tool that your team prefers that has API access. So Jira, Linear, Trello, GitHub Issues, anything you can think of, right? And that is a really powerful workflow that will let you hopefully simplify your processes, give your team more control over how they do work, and eliminate some of that just admin overhead. +And you don't have to use Notion, you can use any project management tool that your team prefers that has API access. So Jira, Linear, Trello, GitHub Issues, anything you can think of, right? And that is a really powerful workflow that will let you hopefully simplify your processes, give your team more control over how they do work, and eliminate some of that just admin overhead. [00:00:48] You don't have somebody who's gotta monitor the channel to make sure that things don't get dropped. You've got the ability to gently nudge your co-workers without that, even that small conflict of having to tell somebody that the way they did something isn't the preferred way. And as you can probably imagine, there are a lot of things that you can do with this that let you take this so much further. @@ -14,7 +14,7 @@ So a couple of things that you might use this for that aren't directly process r You could create an intake fossa, what we did creating an intake process for cross functional requests. So if a team that's not your team needs some help, they use this modal to ask for the help and clarify what they need and why. You could create a quick capture process for new ideas. [00:01:47] -If you are on a team like a lot of the teams I've been on, everybody's coming up with really fun ideas that you can't prioritize it right now, but it is something you wanna do since you don't wanna lose track. So having an idea/command that puts it in to list for the next time you are ready to start prioritizing work, that's a great way to make sure that people's ideas don't get lost. +If you are on a team like a lot of the teams I've been on, everybody's coming up with really fun ideas that you can't prioritize it right now, but it is something you wanna do since you don't wanna lose track. So having an "idea" slash command that puts it in to list for the next time you are ready to start prioritizing work, that's a great way to make sure that people's ideas don't get lost. [00:02:07] And that you don't lose some of those great ideas that could be excellent to work on once you finished your account workload. And you could also do something like having a way to relay customer feedback or customer requests. If you're the support team, if you're a developer experience team, if you're out with your customers and they have something that they wish existed or something that they don't like. diff --git a/en-US/2023-08-25-chat-apis/16-wrapping-up.vtt b/en-US/2023-08-25-chat-apis/16-wrapping-up.vtt index 98c51a4f..64ba827b 100755 --- a/en-US/2023-08-25-chat-apis/16-wrapping-up.vtt +++ b/en-US/2023-08-25-chat-apis/16-wrapping-up.vtt @@ -27,7 +27,7 @@ any chat app that gives you API access. 6 00:00:22.374 --> 00:00:26.804 -And you don't have to use notion, you can +And you don't have to use Notion, you can use any project management tool that your 7 @@ -156,7 +156,7 @@ since you don't wanna lose track. 33 00:01:59.006 --> 00:02:01.624 -So having an idea/command +So having an "idea" slash command that puts it in to list for 34 diff --git a/en-US/2023-08-25-chat-apis/2-creating-a-netlify-tunnel.txt b/en-US/2023-08-25-chat-apis/2-creating-a-netlify-tunnel.txt index 917a4fa5..82cc8b6a 100755 --- a/en-US/2023-08-25-chat-apis/2-creating-a-netlify-tunnel.txt +++ b/en-US/2023-08-25-chat-apis/2-creating-a-netlify-tunnel.txt @@ -1,5 +1,5 @@ [00:00:00] ->> We are going to clone the start branch of the Learn with JSON chat ops Frontend Masters repo. To clone this repo, we're going to run GitHub repo clone learn with Jason, and then chatops-frontend-masters. And then I'm gonna run a-- to get us out of the GitHub CLI and into just plain old git commands. +>> We are going to clone the start branch of the Learn with Jason chat ops Frontend Masters repo. To clone this repo, we're going to run GitHub repo clone learn with Jason, and then chatops-frontend-masters. And then I'm gonna run a -- to get us out of the GitHub CLI and into just plain old git commands. [00:00:21] And I wanna clone this start repo, so -b for branch and start. So, this is gonna give us the start branch, and when I move into this, I can see that I'm on the start branch. So, here we have the pieces that we're gonna need, and there's not a lot in here. @@ -23,7 +23,7 @@ And this is going to give me a copy of this repo in my personal account, and I d So the reason we're gonna do this again is because we need to have a live tunnel, because Slack bots operate by sending requests to a live URL that we set up. So, similar to a webhook if you've ever set one up. And the way that a webhook works is that it's a URL available somewhere publicly on the web. [00:02:37] -And whenever the app that you've added a webhook to has something for your particular command, it sends that payload to that live URL. So for us to test a Slack bot, we need to have that live URL, which won't work with local development. So, the Netlify CLI has this built-in feature to add a live tunnel into our local development box, which means that we can use the web hook public URL field on Slack with our local development box. +And whenever the app that you've added a webhook to has something for your particular command, it sends that payload to that live URL. So for us to test a Slack bot, we need to have that live URL, which won't work with local development. So, the Netlify CLI has this built-in feature to add a live tunnel into our local development box, which means that we can use the webhook public URL field on Slack with our local development box. [00:03:10] Which it's gonna make such a huge difference for the speed of development. Cuz our only alternative would be to actually deploy this every time we make a change to test it and see if it works, which is it's slow. It's frustrating. And it just tends to take, it takes me out of it if I have to wait five minutes between trying things. @@ -38,7 +38,7 @@ So, we're running Netlify CLI version 15.2.0. Then I'm going to make sure I'm lo So, I want to authorize that. Great, I can close this window. So I'm gonna close this one down and then back here. I'm now logged in. And if I run Netlify status, it will show me who I am and all that. But it says here, I'm not in a folder that's linked to a site, and that's expected cuz we haven't set one up yet. [00:04:43] -So, we're going to set up that site by running Netlify in it, And we're going to connect, let's say we want to create and configure a new site. This is a brand new one that we wanna ship. So, I'm gonna put it on my team, and we can call it whatever we want, but because we're going to have to update this name in a few places, I'm gonna give it a name that I can remember. +So, we're going to set up that site by running Netlify init, And we're going to connect, let's say we want to create and configure a new site. This is a brand new one that we wanna ship. So, I'm gonna put it on my team, and we can call it whatever we want, but because we're going to have to update this name in a few places, I'm gonna give it a name that I can remember. [00:05:06] So I'll just go with like a short name like that, and then we don't have a build command, we can keep the defaults there, it's gonna set all that up for us. Good, and now we're happy. So next, we can start this thing in live mode. So, the Netlify dev command will start a local dev server, it'll auto detect what's going on, because in this case we're using serverless functions, which we'll talk about in a moment. @@ -50,10 +50,10 @@ Netlify is gonna auto detect all of that. But what we want to add is this live f Because it's gonna use the name of the project, and just a few other things to actually make this function. So, this is now a live running instance of our development box, which is available on the web. So, if I go in here and I look at our function here, this is our function for the Slack, and right now it doesn't do anything other than return a 200 status. [00:06:17] -And the body handles Slack interactivity. So, if I head back out, open that in the bigger window here, and I head over to API Slack, we've got, that's running in the web. And anybody who wants to can hit this if you go to the chatops-fem-22e106.netlify.live/.api/.slack, that is going to run on your computer right now for as long as my development instance is running. +And the body handles Slack interactivity. So, if I head back out, open that in the bigger window here, and I head over to API Slack, we've got, that's running in the web. And anybody who wants to can hit this if you go to the chatops-fem-22e106.netlify.live/api/slack, that is going to run on your computer right now for as long as my development instance is running. [00:06:52] -And the reason this is exciting is it means that I can now use this. And whenever I make a change, That change is also available through that live URL instantly. And so that means that my local development will be reflected in the Slack/command on Save, instead of requiring me to deploy the serverless function every time. +And the reason this is exciting is it means that I can now use this. And whenever I make a change, That change is also available through that live URL instantly. And so that means that my local development will be reflected in the Slack's "/" command on Save, instead of requiring me to deploy the serverless function every time. [00:07:15] And even if it only takes a few seconds, it just takes you out of your flow. So, this is a big reason, it's why the inconvenience of having to get that site deployed and set up in Netlify CLI, it's why it's worth it because you get this extra interactivity. diff --git a/en-US/2023-08-25-chat-apis/2-creating-a-netlify-tunnel.vtt b/en-US/2023-08-25-chat-apis/2-creating-a-netlify-tunnel.vtt index 970aee2f..61131c9a 100755 --- a/en-US/2023-08-25-chat-apis/2-creating-a-netlify-tunnel.vtt +++ b/en-US/2023-08-25-chat-apis/2-creating-a-netlify-tunnel.vtt @@ -3,7 +3,7 @@ WEBVTT 1 00:00:00.070 --> 00:00:04.909 We are going to clone the start -branch of the Learn with JSON chat +branch of the Learn with Jason chat 2 00:00:04.909 --> 00:00:07.115 @@ -20,7 +20,7 @@ and then chatops-frontend-masters. 5 00:00:15.963 --> 00:00:19.486 -And then I'm gonna run a-- to +And then I'm gonna run a -- to get us out of the GitHub CLI and 6 @@ -229,7 +229,7 @@ which means that we can 48 00:03:03.950 --> 00:03:10.392 -use the web hook public URL field on +use the webhook public URL field on Slack with our local development box. 49 @@ -353,7 +353,7 @@ haven't set one up yet. 74 00:04:43.231 --> 00:04:48.932 So, we're going to set up that -site by running Netlify in it, And +site by running Netlify init, And 75 00:04:48.932 --> 00:04:53.685 @@ -487,11 +487,11 @@ can hit this if you go 102 00:06:40.707 --> 00:06:45.313 to the -chatops-fem-22e106.netlify.live/.api/.sl- +chatops-fem-22e106.netlify.live/api/slack 103 00:06:45.313 --> 00:06:49.002 -ack, that is going to run on +that is going to run on your computer right now for 104 @@ -520,7 +520,7 @@ development will be reflected in 109 00:07:09.078 --> 00:07:10.982 -the Slack/command on Save, +the Slack's "/" command on Save, 110 00:07:10.982 --> 00:07:15.566 diff --git a/en-US/2023-08-25-chat-apis/3-slack-app-setup.txt b/en-US/2023-08-25-chat-apis/3-slack-app-setup.txt index 6c809411..a354d0a3 100755 --- a/en-US/2023-08-25-chat-apis/3-slack-app-setup.txt +++ b/en-US/2023-08-25-chat-apis/3-slack-app-setup.txt @@ -26,10 +26,10 @@ So, the app that we're building for this one is not like task management specifi I think it should be it should be something that you talk to your team about. What information do you need, why are you capturing it? How does it get managed? What are the intervals for it? So we're intentionally going a little bit silly with this app, to get away from the idea that I'm telling you this is exactly how you should build the app. [00:03:10] -And more, these are the mechanics of building the app and you should adapt it to your team. So once we have set that up, let's save it. And then we can go over to this slash commands section. So the place we're going to spend the most time in this app is in this slash commands and interactivity and shortcuts here. +And more, these are the mechanics of building the app and you should adapt it to your team. So once we have set that up, let's save it. And then we can go over to this "Slash commands" section. So the place we're going to spend the most time in this app is in this "Slash commands" and interactivity and shortcuts here. [00:03:30] -So you'll see me go back to these quite a bit. So inside the slash commands, we're going to create a new one and we're going to call this one Foodfight and the request URL is going to be our nullify live URL. So I'm going to copy this, and head back in. +So you'll see me go back to these quite a bit. So inside the "Slash commands", we're going to create a new one and we're going to call this one Foodfight and the request URL is going to be our Netlify live URL. So I'm going to copy this, and head back in. [00:03:50] And now there's a caveat to be made here. And it's important because it can get annoying, but to me, it's less annoying than having to deploy every time. Anytime you stop and restart your dev server, it is going to change this URL. This little hash here is going to change every time we stop and start the dev server. @@ -53,7 +53,7 @@ Now they can just do slash request, can you help me build XYZ right? So again, c Those are really powerful ways to help your team know how to work with you and feel confident that the way they're working with you is going to actually work. So once we've done that, we can save. And then I'm going to minimize this and I'm going to open up Slack. [00:06:19] -So this is a Slack workspace and what I'm gonna do is just go, let's just clear this out a little bit. So this is a cleared, [LAUGH] very high-tech clearing of the Slack channel here. But what we can do now is we can actually run our FoodFight command after we've added the app. +So this is a Slack workspace and what I'm gonna do is just, let's just clear this out a little bit. So this is a cleared, [LAUGH] very high-tech clearing of the Slack channel here. But what we can do now is we can actually run our FoodFight command after we've added the app. [00:06:47] So we need to make the app available, right now it's not here. So you can see if I start typing just FoodFight, it's not there and I need to add the app to a channel in order to make it work, so the first thing is going into the OAuth and permissions here. @@ -65,13 +65,13 @@ Why don't we make sure that it's got all the right scopes? So, this first scope And we do want it to be able to do that, so before we install it, because every time you change permissions, you have to install it. Let's add chat, right? And that is gonna be everything that this one needs. So we can, we can save that. And then now let's install it to the workspace. [00:07:40] -Doesn't have a bot user to install. I know what it is. Nevermind. Let's, so here on the add display name. So it's on App Home. Scroll down to your app's presence in Slack, and here we have to add actual bot information. So we're going to name this bot food-fight, and we're going to give it a default username of food-fight and add. +Doesn't have a bot user to install. I know what it is. Nevermind. Let's, so here on the add display name. So it's on App Home. Scroll down to your app's presence in Slack, and here we have to add actual bot information. So we're going to name this bot Food Fight, and we're going to give it a default username of foodfight and add. [00:08:12] -And then we can show it as always online. That's a nice easy thing to do if people want to see whether or not the bot is working. And so up here now it says bot user added. So now that we've added that bot user, we can go back to this OAuth and permissions and we can install the workspace. +And then we can show it as always online. That's a nice easy thing to do if people want to see whether or not the bot is working. And so up here now it says bot user added. So now that we've added that bot user, we can go back to this OAuth and permissions and we can install to workspace. [00:08:33] -And now it's saying that it can do things. It can send messages as food-fight, and it can add shortcuts or slash commands that people can use. And that's what we wanted to be able to do, so we're gonna hit allow. Good, good. And next we're going to minimize this window here, start typing Foodfight. +And now it's saying that it can do things. It can send messages as foodfight, and it can add shortcuts or slash commands that people can use. And that's what we wanted to be able to do, so we're gonna hit allow. Good, good. And next we're going to minimize this window here, start typing Foodfight. [00:09:01] And now we've got Food Fight here. And you can see that whatever we give it as the body of our command is what will show up in the output here. But note that it's only visible to you, and that's because we can give feedback to the user who ran the command using the body of what we returned from the slash command. diff --git a/en-US/2023-08-25-chat-apis/3-slack-app-setup.vtt b/en-US/2023-08-25-chat-apis/3-slack-app-setup.vtt index b5a00610..c853a7ad 100755 --- a/en-US/2023-08-25-chat-apis/3-slack-app-setup.vtt +++ b/en-US/2023-08-25-chat-apis/3-slack-app-setup.vtt @@ -250,12 +250,12 @@ let's save it. 54 00:03:20.220 --> 00:03:25.370 And then we can go over to -this slash commands section. +this "Slash commands" section. 55 00:03:25.370 --> 00:03:28.475 So the place we're going to spend the most -time in this app is in this slash commands +time in this app is in this "Slash commands" 56 00:03:28.475 --> 00:03:30.350 @@ -268,7 +268,7 @@ to these quite a bit. 58 00:03:34.100 --> 00:03:39.339 -So inside the slash commands, +So inside the "Slash commands", we're going to create a new one and 59 @@ -278,7 +278,7 @@ we're going to call this one Foodfight and 60 00:03:42.769 --> 00:03:46.878 the request URL is going -to be our nullify live URL. +to be our Netlify live URL. 61 00:03:46.878 --> 00:03:50.370 @@ -469,7 +469,7 @@ So this is a Slack workspace and 101 00:06:23.437 --> 00:06:27.600 -what I'm gonna do is just go, +what I'm gonna do is just, 102 00:06:27.600 --> 00:06:33.270 @@ -598,12 +598,12 @@ actual bot information. 129 00:08:04.570 --> 00:08:07.273 So we're going to name -this bot food-fight, +this bot Food Fight, 130 00:08:07.273 --> 00:08:12.130 and we're going to give it a default -username of food-fight and add. +username of foodfight and add. 131 00:08:12.130 --> 00:08:13.930 @@ -630,7 +630,7 @@ we can go back to this OAuth and 136 00:08:26.243 --> 00:08:29.620 permissions and -we can install the workspace. +we can install to workspace. 137 00:08:33.273 --> 00:08:36.090 @@ -638,7 +638,7 @@ And now it's saying that it can do things. 138 00:08:36.090 --> 00:08:40.032 -It can send messages as food-fight, +It can send messages as foodfight, and it can add shortcuts or 139 diff --git a/en-US/2023-08-25-chat-apis/4-api-credentials.txt b/en-US/2023-08-25-chat-apis/4-api-credentials.txt index 0a4ddea7..81977b4e 100755 --- a/en-US/2023-08-25-chat-apis/4-api-credentials.txt +++ b/en-US/2023-08-25-chat-apis/4-api-credentials.txt @@ -11,7 +11,7 @@ So create a new file called .env, and we're going to set SLACK_BOT_OATH_TOKEN an Which is in basic information. And we have the signing secret. So I'm going to copy this and head back, paste it in there, and save it, and we can close that down for now. Next, we're gonna restart this app locally, and so we'll have to update the bot command, and so cuz we need to pick up those environment variables. [00:02:00] -Now, Netlify is smart enough that it knows to check environment files. So it just grabs that .env value, and we'll put that in our environment force, so I can shrink this down. And then what I need to do is grab, The new live hash which is this little set here, oops. +Now, Netlify is smart enough that it knows to check environment files. So it just grabs that .env value, and will put that in our environment for us, so I can shrink this down. And then what I need to do is grab, The new live hash which is this little set here, oops. [00:02:30] Grab this new hash here. Why are you doing that, just copy it, there we go. Shrink this back down. And then we're gonna head into the slash commands, and just update that hash one more time. Okay, so now we've got a command that can actually send messages to the chat as our bot user. @@ -23,10 +23,10 @@ So we're going to head into our terminal here. I'm actually gonna minimize this The Slack API is fairly full-featured, you can do quite a bit with it. We're only gonna get into the bits around sending messages and then using the blocks API. There's a lot more you can do. You can get pretty in-depth with what types of feedback or interactivity you wanna put into your ChatOps workflow. [00:03:46] -What we are gonna do is we're going to open up this util.slack.ts, or util/slack.ts, and inside of it, we are going to create a function that lets us talk to the Slack API. So, export function slackApi(), and that is going to accept two arguments. The first one is going to be the endpoint, and that is a slackApiEndpoint. +What we are gonna do is we're going to open up this util.slack.ts, or util/slack.ts, and inside of it, we are going to create a function that lets us talk to the Slack API. So, export function slackApi(), and that is going to accept two arguments. The first one is going to be the endpoint, and that is a SlackApiEndpoint. [00:04:13] -This is out of the, Types folder that is predefined for us. And so that just gives us the ones that we're actually gonna use, chat.postmessage and views.open. Then we're going to have a body, and that body has a slackApiRequestBody. And those are gonna be the two inputs. And what this means is we're gonna be able to now send requests to the Slack API using kind of a unified flow instead of having to redeclare our fetch API call. +This is out of the, Types folder that is predefined for us. And so that just gives us the ones that we're actually gonna use, chat.postmessage and views.open. Then we're going to have a body, and that body has a SlackApiRequestBody. And those are gonna be the two inputs. And what this means is we're gonna be able to now send requests to the Slack API using kind of a unified flow instead of having to redeclare our fetch API call. [00:04:44] And set the token and all the things that we need in order to make these requests. We can just do it in this command and have a lot of the stuff set up for us ready to go. So, this will return a fetch command, and that is going to go to the Slack API, so slack.com/api. diff --git a/en-US/2023-08-25-chat-apis/4-api-credentials.vtt b/en-US/2023-08-25-chat-apis/4-api-credentials.vtt index 16617c61..8217ebfb 100755 --- a/en-US/2023-08-25-chat-apis/4-api-credentials.vtt +++ b/en-US/2023-08-25-chat-apis/4-api-credentials.vtt @@ -124,7 +124,7 @@ So it just grabs that .env value, and 28 00:02:08.343 --> 00:02:13.431 -we'll put that in our environment force, +will put that in our environment for us, so I can shrink this down. 29 @@ -241,7 +241,7 @@ that is going to accept two arguments. 53 00:04:08.840 --> 00:04:13.799 The first one is going to be the endpoint, -and that is a slackApiEndpoint. +and that is a SlackApiEndpoint. 54 00:04:13.799 --> 00:04:20.360 @@ -260,7 +260,7 @@ chat.postmessage and views.open. 57 00:04:26.180 --> 00:04:31.880 Then we're going to have a body, and -that body has a slackApiRequestBody. +that body has a SlackApiRequestBody. 58 00:04:31.880 --> 00:04:35.539 diff --git a/en-US/2023-08-25-chat-apis/5-sending-a-command.txt b/en-US/2023-08-25-chat-apis/5-sending-a-command.txt index 0d0f7328..53406222 100755 --- a/en-US/2023-08-25-chat-apis/5-sending-a-command.txt +++ b/en-US/2023-08-25-chat-apis/5-sending-a-command.txt @@ -1,8 +1,8 @@ [00:00:00] ->> The next thing that we're gonna do is we are going to send a command here. So let's get into the Slack utility, and we will import first parse from query string. Because query string allows us to get a form-encoded body, or what exactly, I can't remember what it's called. +>> The next thing that we're gonna do is we are going to send a command here. So let's get into the Slack utility, and we will import first "parse" from "querystring". Because "querystring" allows us to get a form-encoded body, or what exactly, I can't remember what it's called. [00:00:26] -But it's where the the key is that with an equal sign and then the value after that. And so this is gonna allow us to parse that out and actually use those values. Then we're going to import our slackApi command from the util that we just created. And we're gonna create a new function in here called handleSlashCommand, slash command, not slack. +But it's where the key is set with an equal sign and then the value after that. And so this is gonna allow us to parse that out and actually use those values. Then we're going to import our slackApi command from the util that we just created. And we're gonna create a new function in here called handleSlashCommand, slash command, not slack. [00:00:57] My goodness, slash command. And that's gonna accept a payload, and the payload is a SlackSlashCommandPayload. And again, that's there so that we get autocomplete, not for any other real reason. So the way that I want this to work is to keep this kind of easy to debug later on we're putting the slash command logic into this function. @@ -80,5 +80,5 @@ But for now if I go and use this, anytime you run this it's going to give you a You can take a little bit of time to put together one of these slash commands and just say status, and have it print that screenshot right there for you. Or give you the top stats for whatever thing, find out who's on call. Whatever the things are that you find yourself checking frequently in your team, you're able to do that with a slash command very quickly. [00:10:44] -And this is the power of that workflow, is you can really cut down on the amount of time you spend context switching to grab information that's available via api anyways. +And this is the power of that ChatOps workflow, is you can really cut down on the amount of time you spend context switching to grab information that's available via api anyways. diff --git a/en-US/2023-08-25-chat-apis/5-sending-a-command.vtt b/en-US/2023-08-25-chat-apis/5-sending-a-command.vtt index 6b256a8b..bb4fd240 100755 --- a/en-US/2023-08-25-chat-apis/5-sending-a-command.vtt +++ b/en-US/2023-08-25-chat-apis/5-sending-a-command.vtt @@ -12,11 +12,11 @@ So let's get into the Slack utility, and 3 00:00:11.647 --> 00:00:17.221 we will import first -parse from query string. +"parse" from "querystring". 4 00:00:17.221 --> 00:00:22.122 -Because query string allows us +Because "querystring" allows us to get a form-encoded body, 5 @@ -26,7 +26,7 @@ I can't remember what it's called. 6 00:00:26.646 --> 00:00:33.056 -But it's where the the key is that with an +But it's where the key is set with an equal sign and then the value after that. 7 @@ -734,7 +734,7 @@ a slash command very quickly. 154 00:10:44.720 --> 00:10:47.200 -And this is the power of that workflow, +And this is the power of that ChatOps workflow, 155 00:10:47.200 --> 00:10:51.168 diff --git a/en-US/2023-08-25-chat-apis/6-securing-the-application.txt b/en-US/2023-08-25-chat-apis/6-securing-the-application.txt index 62915bc2..f8fe6116 100755 --- a/en-US/2023-08-25-chat-apis/6-securing-the-application.txt +++ b/en-US/2023-08-25-chat-apis/6-securing-the-application.txt @@ -20,7 +20,7 @@ So stick with me and we will step through it once the code is written. So next w Looks like I forgot an s on this one, so we'll fix that. Then, I'm gonna do now because we need the current time, so we're gonna run math floor of date.now. And then we're gonna divide by 1,000 because the precision of a slack timestamp is lower than the precision of date.now. [00:02:47] -So it's a thousand microseconds, milliseconds, I'm not sure which. But by dividing by a thousand we get to the same number, and by running Math.floor, it hits the same number there. So then, just to make sure that nothing funky is up, we're gonna run a Math.abs and do a now- timestamp. +So it's a thousand microseconds, milliseconds, I'm not sure which. But by dividing by a thousand we get to the same number, and by running Math.floor, it hits the same number there. So then, just to make sure that nothing funky is up, we're gonna run a Math.abs and do a now - timestamp. [00:03:13] And if that is greater than 300, meaning the timestamp is more than five minutes off what our server thinks now is, we're just gonna return false. We're gonna assume something's funky, this is an invalid request, so we'll just throw it. Next, we need to generate a hash of our message. @@ -29,7 +29,7 @@ And if that is greater than 300, meaning the timestamp is more than five minutes So we're gonna create Hmac and we're gonna use the sha256 algorithm and pass in the secret. So this is the signing secret that we'll use to generate the hash. We wanna update the value with v0, this is a format that slack defines the timestamp of the message. And then we're gonna use the request body unencoded just as it was sent. [00:04:05] -And finally we're going to digest that to get out the hex value. So we want a hex value, which is a hash of this string using our signing secret and the sha256 algorithm. And finally, we're going to check whether or not these zero. And the hash. Is the same as our signature. +And finally we're going to digest that to get out the hex value. So we want a hex value, which is a hash of this string using our signing secret and the sha256 algorithm. And finally, we're going to check whether or not v0. And the hash. Is the same as our signature. [00:04:36] Okay, so a lot happens in here, so let's talk through how this works and why it's important. So, when you're dealing with a request, you wanna make sure that that request is authentic. And there are a lot of ways that you can do this, but this idea of sending a signature is one of the ways that is. @@ -38,7 +38,7 @@ Okay, so a lot happens in here, so let's talk through how this works and why it' It's still kinda hard to understand, but is at least, I don't know, it makes sense to me and I'm not a cryptographer. So what we're doing is we're saying, Slack has a secret password that it shares with us, the signing secret. This is the key that we will use to generate these hashes, that key is not sent with the messages. [00:05:16] -But what is done is slack uses that site signing secret to create a hash of the request body and the timestamp that it uses to say if your request matches what we generated at the time that we sent this, then it's valid. So we're able to say we have the secret nobody else does. +But what is done is slack uses that signing secret to create a hash of the request body and the timestamp that it uses to say if your request matches what we generated at the time that we sent this, then it's valid. So we're able to say we have the secret nobody else does. [00:05:38] And Slack has a secret. so when we check that something that's hashed using our signing secret matches the same input value, so the v0, the timestamp and the request body. If those two things come out the same, that means that whoever sent it has the signing secret, and we can assume that it's valid. diff --git a/en-US/2023-08-25-chat-apis/6-securing-the-application.vtt b/en-US/2023-08-25-chat-apis/6-securing-the-application.vtt index 07133435..b494b68c 100755 --- a/en-US/2023-08-25-chat-apis/6-securing-the-application.vtt +++ b/en-US/2023-08-25-chat-apis/6-securing-the-application.vtt @@ -201,7 +201,7 @@ that nothing funky is up, 42 00:03:07.518 --> 00:03:13.015 we're gonna run a Math.abs and -do a now- timestamp. +do a now - timestamp. 43 00:03:13.015 --> 00:03:17.822 @@ -274,7 +274,7 @@ the sha256 algorithm. 57 00:04:19.960 --> 00:04:26.125 And finally, we're going to -check whether or not these zero. +check whether or not v0. 58 00:04:28.127 --> 00:04:30.143 @@ -343,7 +343,7 @@ that key is not sent with the messages. 72 00:05:16.960 --> 00:05:22.325 But what is done is slack uses that -site signing secret to create a hash +signing secret to create a hash 73 00:05:22.325 --> 00:05:27.782 diff --git a/en-US/2023-08-25-chat-apis/7-slack-block-kit.txt b/en-US/2023-08-25-chat-apis/7-slack-block-kit.txt index 8381de00..af139e9f 100755 --- a/en-US/2023-08-25-chat-apis/7-slack-block-kit.txt +++ b/en-US/2023-08-25-chat-apis/7-slack-block-kit.txt @@ -17,13 +17,13 @@ So I like being a little more terse with the utility. You can make a choice, you This is gonna be called blocks. And it's gonna be an object that is full of the blocks that we want to create. So we're using a subset here, you won't need to use all of these. So I'm gonna create one for sections. I'm gonna create one for an input. [00:02:15] -And I believe we need to select And that's all we're gonna use today. Like I said, there are a lot of blocks. So as you kind of build out your own chat ops, you might need to expand this to accommodate more things, but this is what we're doing for the demo. +And I believe we need a select And that's all we're gonna use today. Like I said, there are a lot of blocks. So as you kind of build out your own chat ops, you might need to expand this to accommodate more things, but this is what we're doing for the demo. [00:02:37] -So we'll keep it nice and tight as much as we can. So that's gonna accept text and we're gonna call this a sectionBlockArgs so that we get some autocomplete there and that is going to return a Slack block section And it says, yeah, because we're not returning anything yet, it says that it's invalid. +So we'll keep it nice and tight as much as we can. So that's gonna accept text and we're gonna call this a SectionBlockArgs so that we get some autocomplete there and that is going to return a SlackblockSection. And it says, yeah, because we're not returning anything yet, it says that it's invalid. [00:03:04] -So we need to actually return and we can say it's gonna be a type of section. And we're gonna have text of type, we'll use Markdown. Now, Slack their mikdan isn't Markdown, it's a specific dialect that they've created to give Markdown-like capabilities, which I think is why they spell this differently. +So we need to actually return and we can say it's gonna be a type of section. And we're gonna have text of type, we'll use Markdown. Now, Slack their markdown isn't Markdown, it's a specific dialect that they've created to give Markdown-like capabilities, which I think is why they spell this differently. [00:03:28] I'm not sure, but for whatever reason, they don't like vowels. And then we pass in this text. And now that we've satisfied the conditions of a SlackBlockSection, we don't have that red squiggly anymore, and that will give us a valid Slack block. Next, we're gonna do the same thing, but for the input and the select, these are both a little more in depth. @@ -56,13 +56,13 @@ And that's going to, again, be the id_block. I'll show you why I use this naming We're gonna set a type of input. We will use a label. That label is going to be exactly the same as this one, so I'm gonna copy paste it. And then we want an element. That element is going to have an action_id of id. The type is going to be a static_select this time. [00:07:36] -And for the placeholder, now this is inside the element. So the placeholder goes here, that's going to have a type of plain_text and a text of placeholder. If you wanna use emojis and stuff you can also set emoji to true in these, but we're we're not using them so you can leave it or not doesn't really matter. +And for the placeholder, now this is inside the element. So the placeholder goes here, that's going to have a type of plain_text and a text of placeholder. If you wanna use emojis and stuff you can also set emoji to true in these, we're not using them so you can leave it or not doesn't really matter. [00:08:02] For options, we are going to map over the options that were given. And we are going to know that these have a label and a value, because that is what we've defined them to have. And for each one, we're gonna return text, and it has a type of plain_text. [00:08:24] -It has the text value itself of label. And we can set emoji to true if we want And then the last thing we want is the value. So this is how we actually get options into it ,so we can save that. And now we have these little helpers that we'll be able to use to make our lives easier as we're building out our modal. +It has the text value itself of label. And we can set emoji to true if we want And then the last thing we want is the value. So this is how we actually get options into it, so we can save that. And now we have these little helpers that we'll be able to use to make our lives easier as we're building out our modal. [00:08:54] Because what we wanna do next is actually create from the slash command. We wanna pop up a modal window that asks a couple questions that we need in order to respond to the request. And we keep it simple, when I was building this for a previous team, we had three questions. @@ -71,7 +71,7 @@ Because what we wanna do next is actually create from the slash command. We wann It was, what do you need? When do you need it by? Because if it doesn't have a deadline, is it actually important, right? And how urgent is this? What's the risk if we don't get this done? It's nice to have, it's a must have it's a critical blocker, making sure that we have an understanding of what the level of urgency is for the thing. [00:09:34] -And then an optional input for, are there any other details that we need links to stuff etc. And by keeping it small, because the arg is always gather all of the information but what I found is, if you give people one or two fields to fill out, they'll do it. +And then an optional input for, are there any other details that we need, links to stuff etc. And by keeping it small, because the urge is always gather all of the information but what I found is, if you give people one or two fields to fill out, they'll do it. [00:09:49] If you give them ten fields, they won't, or they'll start kind of short-cutting those fields and then they become less information. So you want the absolute minimum number of inputs that you can to actually do your job. Anything else can be in an additional context box so that people can help out there. diff --git a/en-US/2023-08-25-chat-apis/7-slack-block-kit.vtt b/en-US/2023-08-25-chat-apis/7-slack-block-kit.vtt index 1d0e5493..2ae60736 100755 --- a/en-US/2023-08-25-chat-apis/7-slack-block-kit.vtt +++ b/en-US/2023-08-25-chat-apis/7-slack-block-kit.vtt @@ -155,7 +155,7 @@ I'm gonna create one for an input. 33 00:02:15.836 --> 00:02:25.674 -And I believe we need to select And +And I believe we need a select And that's all we're gonna use today. 34 @@ -180,7 +180,7 @@ tight as much as we can. 38 00:02:41.900 --> 00:02:48.565 So that's gonna accept text and we're -gonna call this a sectionBlockArgs so +gonna call this a SectionBlockArgs so 39 00:02:48.565 --> 00:02:53.896 @@ -189,7 +189,7 @@ that is going to return 40 00:02:53.896 --> 00:03:00.475 -a Slack block section And +a SlackblockSection. And 41 00:03:00.475 --> 00:03:04.800 @@ -208,7 +208,7 @@ we'll use Markdown. 44 00:03:14.527 --> 00:03:19.791 -Now, Slack their mikdan isn't Markdown, +Now, Slack their markdown isn't Markdown, it's a specific dialect 45 @@ -523,7 +523,7 @@ can also set emoji to true in these, but 111 00:07:58.021 --> 00:08:02.720 -we're we're not using them so you can +we're not using them so you can leave it or not doesn't really matter. 112 @@ -562,7 +562,7 @@ we want is the value. 119 00:08:39.722 --> 00:08:44.219 So this is how we actually get -options into it ,so we can save that. +options into it, so we can save that. 120 00:08:44.219 --> 00:08:49.283 @@ -635,7 +635,7 @@ And then an optional input for, 135 00:09:35.937 --> 00:09:39.630 are there any other details that -we need links to stuff etc. +we need, links to stuff etc. 136 00:09:39.630 --> 00:09:41.130 @@ -643,7 +643,7 @@ And by keeping it small, 137 00:09:41.130 --> 00:09:45.630 -because the arg is always gather all +because the urge is always gather all of the information but what I found is, 138 diff --git a/en-US/2023-08-25-chat-apis/8-generating-a-modal.txt b/en-US/2023-08-25-chat-apis/8-generating-a-modal.txt index fce15fdc..7c94b256 100755 --- a/en-US/2023-08-25-chat-apis/8-generating-a-modal.txt +++ b/en-US/2023-08-25-chat-apis/8-generating-a-modal.txt @@ -32,7 +32,7 @@ That's a real food opinion held by a real person that's not me, initial value, w And then as a hint so that we can have something that doesn't disappear when you start typing, you can say what do you believe about food that, add an extra space in here, what do you believe about food that people find appalling, say it with your chest. And then we're gonna add in our select here. [00:05:06] -So, let me locks dot select and we're gonna set an ID. This is gonna be our spice level so we're gonna let people kind of identify how spicy their opinion is, set the label of how spicy is this opinion, and then we will set up a placeholder. And for a select, it's kind of like what shows when the select hasn't been used. +So, let me blocks dot select and we're gonna set an ID. This is gonna be our spice level so we're gonna let people kind of identify how spicy their opinion is, set the label of how spicy is this opinion, and then we will set up a placeholder. And for a select, it's kind of like what shows when the select hasn't been used. [00:05:36] So, we're just gonna make it an instruction, select a spice level. And then for the options, we have an array and it's gonna be label. And the value, and these are the same, we probably could have simplified our utility, but I thought in a lot of cases you're gonna have a different value from what the label might be, so it was worth not making it the same. diff --git a/en-US/2023-08-25-chat-apis/8-generating-a-modal.vtt b/en-US/2023-08-25-chat-apis/8-generating-a-modal.vtt index 41908bdd..294d1729 100755 --- a/en-US/2023-08-25-chat-apis/8-generating-a-modal.vtt +++ b/en-US/2023-08-25-chat-apis/8-generating-a-modal.vtt @@ -288,7 +288,7 @@ add in our select here. 60 00:05:06.750 --> 00:05:14.220 -So, let me locks dot select and +So, let me blocks dot select and we're gonna set an ID. 61 diff --git a/en-US/2023-08-25-chat-apis/9-handling-user-input.txt b/en-US/2023-08-25-chat-apis/9-handling-user-input.txt index 2a6e2df9..10ee1aa8 100755 --- a/en-US/2023-08-25-chat-apis/9-handling-user-input.txt +++ b/en-US/2023-08-25-chat-apis/9-handling-user-input.txt @@ -20,13 +20,13 @@ So, the way that interactivity works is there are a lot of things that slack can Because the commands you have to add a URL for each one, and that's useful for separation of complex stuff. But in our case, it's kinda nice that it all just goes to one place because we've got the switch commands to handle it. So we're just gonna use the exact same URL here, actually. [00:02:16] -So I can let's see you. Have this somewhere in here. Grab this, drop it in here with the /api/slack. And we can save. Okay, what we're doing now is we're sending it we can see these requests coming in as I submit. Probably a little easier to see if I make this bigger. +So I can let's see. I have this somewhere in here. Grab this, drop it in here with the /api/slack. And we can save. Okay, what we're doing now is we're sending it we can see these requests coming in as I submit. Probably a little easier to see if I make this bigger. [00:02:51] -That we've got all these happening here. So submit, there's another one, there's another one. And so we're sending these responses, but because we're not actually handling the interactivity, nothing is actually happening. So to do that, we are going to head back into the function here and we're gonna create a new function underneath our handle slash command. +That we've got all these happening here. So submit, there's another one, there's another one. And so we're sending these responses, but because we're not actually handling the interactivity, nothing is actually happening. So to do that, we are going to head back into the function here and we're gonna create a new function underneath our handleSlashCommand. [00:03:18] -And this one's gonna be called Handle interactivity. And this one also takes a payload and that's gonna be the slack modal payload. And this one, we're gonna grab out the callback id because we need that. And that's gonna be the payload, callback id or the payload.view, callback id. +And this one's gonna be called handleInteractivity. And this one also takes a payload and that's gonna be the slack modal payload. And this one, we're gonna grab out the callback id because we need that. And that's gonna be the payload, callback id or the payload.view, callback id. [00:03:47] And the reason that we're checking both is that depending on whether or not we're sending a shortcut or a modal, it changes a little bit. So this is just a quick fallback. That means we're not gonna have to remember to change this later when we add additional pieces. @@ -44,10 +44,10 @@ So to get these we are gonna use this data. So data.opinion_ block. Remember I s And I don't know if they need to be unique. So I just, or they do need to be unique because otherwise they would, you'd end up with kind of a mess. So this is the simplest way I found to do it. You can come up with whatever naming convention you like, if you would like. [00:05:22] -So, then we've got the spice level block, the spice level itself, what the selected option is, and then the value of that. And finally, for the submitter, that's not part of the form, that's part of the original payload. So, we can get the user and their name. And what you could do if you were if your team is all under like a single domain name, and you all sign into Slack with your work email, and you all sign into notion or GitHub or whatever it is with your work emails, you can map these where you can do a lookup for the user in the service that you're searching for. +So, then we've got the spice level block, the spice level itself, what the selected option is, and then the value of that. And finally, for the submitter, that's not part of the form, that's part of the original payload. So, we can get the user and their name. And what you could do if you were if your team is all under like a single domain name, and you all sign into Slack with your work email, and you all sign into Notion or GitHub or whatever it is with your work emails, you can map these where you can do a lookup for the user in the service that you're searching for. [00:06:01] -We're not gonna do that today because it's this is not like a work instance. And so, if somebody else joined and they're using a Gmail account, we're not going to find their their email, because there's no guarantee that they signed up for slack with the same email that they signed up for notion with, right? +We're not gonna do that today because it's this is not like a work instance. And so, if somebody else joined and they're using a Gmail account, we're not going to find their their email, because there's no guarantee that they signed up for Slack with the same email that they signed up for Notion with, right? [00:06:20] But it is an option. It's what I did on a previous team because everybody needed their at companyname.com. And that allowed me to even have people get updates in Notion for something they'd created in Slack. It was a really nice workflow. But now that we've got this, we will eventually save these, but for now we are going to just send the details back to Slack. @@ -74,7 +74,7 @@ We're gonna break under that. So, that is our basic setup here. And then if we w So that it shows up oops, so that this shows up on the screen for the person who posted it because again if something's wrong like that you do want it to show up. And then finally, down below our switch case, we're gonna return a status code of 200, just like we did in the other one with an empty body so that Slack knows that we did, in fact, respond to this request. [00:09:56] -Then to use it, we are going to come down in here. And we're gonna check to see if there's a body payload. And if there is, we're gonna parse that. And this is sent as JSON, so we'll do a JSON.parse and get a body.payload. And then return handleInteractivity and parse in that payload. +Then to use it, we are going to come down in here. And we're gonna check to see if there's a body payload. And if there is, we're gonna parse that. And this is sent as JSON, so we'll do a JSON.parse and get a body.payload. And then return handleInteractivity and pass in that payload. [00:10:25] So let's give this a try. Let's see how it's doing. So I'm gonna run my foodfight command. And then I wanna also show, because we're checking for text, we can add the take right in here. So let's just say, Raisins are a garbage snack. So that'll get picked up and automatically filled into that input, which is a nice way to do it. diff --git a/en-US/2023-08-25-chat-apis/9-handling-user-input.vtt b/en-US/2023-08-25-chat-apis/9-handling-user-input.vtt index 4e145edd..75e19af9 100755 --- a/en-US/2023-08-25-chat-apis/9-handling-user-input.vtt +++ b/en-US/2023-08-25-chat-apis/9-handling-user-input.vtt @@ -177,11 +177,11 @@ same URL here, actually. 38 00:02:16.282 --> 00:02:20.036 -So I can let's see you. +So I can let's see. 39 00:02:20.036 --> 00:02:22.010 -Have this somewhere in here. +I have this somewhere in here. 40 00:02:26.884 --> 00:02:33.945 @@ -233,12 +233,12 @@ back into the function here and 50 00:03:11.638 --> 00:03:18.637 we're gonna create a new function -underneath our handle slash command. +underneath our handleSlashCommand. 51 00:03:18.637 --> 00:03:23.331 And this one's gonna be -called Handle interactivity. +called handleInteractivity. 52 00:03:26.432 --> 00:03:31.762 @@ -435,7 +435,7 @@ Slack with your work email, and 93 00:05:48.627 --> 00:05:54.377 -you all sign into notion or GitHub or +you all sign into Notion or GitHub or whatever it is with your work emails, 94 @@ -465,8 +465,8 @@ there's no guarantee that they signed up 99 00:06:16.418 --> 00:06:20.426 -for slack with the same email that -they signed up for notion with, right? +for Slack with the same email that +they signed up for Notion with, right? 100 00:06:20.426 --> 00:06:21.921 @@ -710,7 +710,7 @@ get a body.payload. 151 00:10:18.600 --> 00:10:25.061 And then return handleInteractivity and -parse in that payload. +pass in that payload. 152 00:10:25.061 --> 00:10:26.200