Full transcript
Introduction
0:00Hey, welcome to the most comprehensive
0:01NAD building master class. This is over
0:03eight hours of pure live automation
0:05builds and my goal is to take you from a
0:07pure beginner and turn you into somebody
0:08who can build professionalgrade AI
0:10workflows that a business is willing to
0:11pay thousands of dollars for. This is
0:13your first time here. I'm Nick. I scaled
0:15my own AI automation agency to 72K a
0:17month. And I now run the biggest paid AI
0:19automation community with around 3,000
0:20AI automation freelancers and AI agency
0:22owners. Most of them land their first
0:24paying client within 2 to 3 weeks of
0:26joining thanks to our daily
0:27accountability program and our proven
0:28frameworks. So, I don't just want this
0:30to be another cookie cutter NAND
0:31tutorial. There are millions of those.
0:33My goal instead is for this to be a
0:34comprehensive guide to real building. In
0:37particular, I'm going to be creating
0:38eight high value NADN workflows that you
0:40guys can start selling immediately. What
0:42that means, I'm not just going to show
0:43you a pretty finished product. In many
0:44cases, I'm actually going to build this
0:45entire thing alongside you live as if I
0:47have no idea what I'm putting together,
0:49and I'm going to do it while narrating
0:50my thought process out loud cuz I think
0:51it's much more instructive for people to
0:53see what a real build process looks like
0:55versus just the shiny finished product
0:57at the end. So, we're going to cover
0:58everything from the absolute foundations
1:00here to advanced systems that can
1:02command $3,000 to $10,000 per
1:04implementation. I've also added
1:05timestamps for every section in the
1:06description, meaning you guys can just
1:08jump around to what you need most and
1:09then come back for the rest. And also,
1:10just make sure to bookmark this video so
1:12you can reference the workflows again
1:13and again as you build and scale your
1:15automation company. Okay, whether you're
1:17looking to automate your own business or
1:18start an automation agency or maybe just
1:20add some highv value skills to your
1:21freelancing toolkit, welcome to the
1:23complete nadn building masterass. Before
1:25we start, this master class is all about
1:26live builds. The purpose is to show you,
1:28as I mentioned, what a real live build
1:29process looks like. And then I want you
1:31to internalize the parts of automation
1:32that you can't really learn by reading,
1:34only by watching somebody who knows what
1:36they're doing do it. So to make sure
1:38everybody's on the same page, this first
1:39section is going to include an
1:40introductory course on the foundations
1:42of NAD. I'm going to include content on
1:43simple logic, workflows, some basic
1:46nodes, and maybe some more. I have this
1:47elsewhere on my channel, so if you guys
1:49have already seen all of this stuff, you
1:50can jump right to the next section. The
1:52key here is to build a solid foundation
1:53that will support everything else we do
1:54later. Because when we start building
1:55those $5,000 plus automation systems,
1:58you do need to understand some core
1:59fundamentals inside and out before you
2:01can get to the good stuff. Let's now
n8n Foundations
2:03dive into the NAN foundations that are
2:05going to make everything else possible.
2:06So, if you guys have seen some of the
2:07other videos on my channel, you'll know
2:08that I put a very big emphasis on
2:10building things practically. I don't
2:11really care much for the academic side
2:13of things. I prefer we just dive right
2:14in and then teach some of these concepts
2:16by actually putting nodes together,
2:17making workflows that you could sell for
2:19business purposes or implement into your
2:20own companies. And that's what we're
2:22going to be doing today. We can't really
2:23get away from doing some of the academic
2:26stuff with JSON just because, you know,
2:27if you don't know JavaScript object
2:29notation, you are going to have to learn
2:30some things like types and objects and
2:32what variables are and stuff like that.
2:34But for the most part, we're going to be
2:35learning all of these concepts down here
2:37by building two workflows. The first
2:39workflow is up here. And essentially
2:41what this does is it feeds in a bunch of
2:43lead data to artificial
2:46intelligence. This is the Google sheet
2:48containing four leads with a bunch of
2:50information here. So we're going to feed
2:51in this information to AI. Then what
2:53we're going to do is we're going to have
2:54AI generate a subject line for an email,
2:56an icebreaker for an email, an elevator
2:58pitch for an email, a call to action,
3:00and then a post script little PS sign.
3:02The idea here is this is a real workflow
3:04that people pay me for. And so these are
3:06the ones that I want to I want to start
3:07with. Essentially, this will allow you
3:09to customize email outreach that it
3:10seems as if you've done a lot of
3:12research into the person, uh, which is
3:13very, very valuable in a business
3:15setting. The second workflow is a little
3:17bit more peculiar, I guess. There's this
3:19service out there called source of
3:20sources. It used to be called helper
3:22reporter at Haro. Basically, the way
3:23that it works is this lovely gentleman
3:25here, Peter, will send you uh a bunch of
3:28information basically where journalists
3:30are looking for professionals in a
3:32certain industry to weigh in on some
3:35developments. And then if you're a
3:37professional in the industry and you
3:38give the journalist some good info, they
3:40can actually tag you and then like use
3:41you in an article, it's a quick and easy
3:43way to basically get listed in a
3:44magazine or some very authoritative data
3:46source. And what this system does is it
3:49basically gets an email like this. Then
3:51it pumps in the titles into AI, does
3:53some cool processing, and then we
3:54actually write a draft of that email as
3:56if we were an expert in that field,
3:58which all you need to do is just like
3:59quickly review, give a once over, edit a
4:01little bit, and then send off to
4:02journalists. There's another system that
4:03I've sold a number of times. And so I
4:05want the videos that I create on NAND to
4:07be practical in nature. I want them to
4:09be on things that you're probably going
4:10to be using for business purposes. So
4:11these are the two systems that uh we're
4:13going to be building. They're cool
4:14systems and all, but you know, for the
4:15purpose of this video, I kind of want to
4:16build them from scratch. So why don't we
4:17just exit out of that puppy? That's the
4:19prompt that we're going to be using for
4:20AI. And for the rest of this, we'll just
4:23get rid of that. Okay. The very first
4:25concept I want to cover are fixed fields
4:27and expression fields. I'm going to be
4:28basically convincing you to just use
4:30expressions all the time. And I'm also
4:31going to show you how to map different
4:32field inputs because the last time that
4:33we jumped around Nadn, we built a couple
4:36of workflows, but I was sort of glancing
4:37over at some of the nuance behind fields
4:39and stuff like that. So, for the
4:40purposes of demonstration, it's going to
4:41be pretty easy. We're just going to
4:43build the first system out by clicking a
4:44button that is going to get a bunch of
4:47data from our Google sheet and then
4:49we're just going to pass all of that
4:50data in kind of rowby row into AI.
4:53Pretty simple, pretty straightforward,
4:54but ultimately something that is very
4:55useful and you'll find yourself doing
4:56quite a bit if you do cold outreach. So,
4:58first things first, I'm just going to
4:59press tab. That's going to open up this
5:01trigger thing on the lefth hand side.
5:02And then, you know, if you type trigger
5:04here, there'll be if you type trig, I
5:06should say, you'll see a ton of options
5:08here. Um, you could either do that or
5:09you could just scroll down to the bottom
5:10where it says add another trigger and
5:11then press trigger manually. Either is
5:13fine, but for the purpose of this demo,
5:15I'm just going to do that. And basically
5:17what I want to do is the second that I
5:19run this trigger, when I click on test
5:20workflow, um, I want to, uh, get all of
5:23the rows and all the data in my Google
5:24sheet. So, I'm going to go up here to
5:25nodes. I'm just going to type in sheet.
5:27We're going to get Google Sheets. Now,
5:29what I'm going to do is if you scroll
5:31down here, you'll see that there's this
5:32one node called get rows and sheets.
5:34That's what I'm going to click on. Now,
5:36I've already done a connection before.
5:38Um, what you're going to have to do if
5:39you want to connect to your Google
5:40Sheets account is go to create new
5:42connection. Now, because I'm on the
5:43cloud hosted offering, and keep in mind
5:45if you're not on the cloud hosted
5:46offering, um, these sorts of connections
5:47are a little bit more difficult. You
5:49have to go to Google Cloud Console and
5:50get set up there. But because I'm on the
5:52cloud hosted offering, all I need to do
5:53is click sign in with Google over here.
5:55And I'll actually go connect to my email
5:58account and then it'll create a
5:59credential for me, which is pretty
6:01handy. So you can see it's saying it's
6:03already has some access just because
6:04I've already done this connection. But
6:05for the purpose of this demo, I just
6:06wanted to show you guys what that looks
6:08like. And then I'm just going to save
6:10this connection here with a name so that
6:11it's just nice and organized. Okay. And
6:13what we want to do is we just want to
6:14grab this Google sheet up here, right?
6:16So, in NADM, there are a variety of ways
6:19to do this, but I'm just going to I'm
6:21going to be looking for a document.
6:23Sorry, a sheet within a document. My
6:24bad. The document we're going to want to
6:26select is from the list. And we're
6:27actually going to go down. We're going
6:28to choose this one called leads, comma
6:30space, January 27th, 2025. So, as you
6:34can see, we've already manually found
6:35that. Okay. And then the specific
6:38subshet that we want is this sheet one
6:41because I guess that's the only one that
6:42we have here. So, I'm just going to
6:43click on this. It's going to actually do
6:45an API call to Google Sheets. It's going
6:47to find that there's only sheet one
6:48here. Then I can give it a click and
6:49then voila. Let me just run test step
6:52and let's see what happens when I click
6:54test. Okay, great. So, I've offiscated
6:56this data. This data is not um actually
6:58one for one whoever this this person is.
7:00I've gone through and I've like renamed
7:02them and stuff like that just for
7:03privacy purposes. But as we see on the
7:05right hand side here, we we have a bunch
7:06of output. And we can see the output in
7:08a variety of ways. Tabular, JSON,
7:10schema. most people in and they like the
7:12schema look because it just kind of
7:14compresses the information nicely. It's
7:15a little bit easier for them to see. I'm
7:17a little zoomed in here too. Um but uh
7:19yeah, you know, normally like you see
7:21most of the node variables which is
7:23pretty handy. But this JSON one over
7:26here, this is really intimidating for a
7:28lot of people. And so we're we're going
7:29to cover this in detail. I'm going to
7:30show you exactly how you read JSON, what
7:32all those things mean. But just I just
7:33want you guys to know that for the
7:34remainder of this course, I'm going to
7:35be using primarily the JSON and the
7:37schema view. But I'm actually going to
7:38tend towards JSON. And the reason why
7:40I'm going to be tending towards Jason is
7:41because like JSON says all the same
7:44stuff that the schema view does anyway.
7:46But unfortunately part of the way you
7:47learn JSON is just by kind of staring at
7:49it a lot and squinting at it and kind of
7:50inherently and intuitively understanding
7:52the formatting. If we're going to be
7:53looking at outputs all day anyway, we
7:55might as well kind of get, you know,
7:56kill two birds with one stone. All of
7:57the same data in JSON is represented in
8:00schema anyway. It's just instead of like
8:02the quotes around key names and stuff,
8:03you just have sort of this light gray
8:05box alongside like a type sign here. So,
8:07I guess the point I'm making is we might
8:09as well double up and just learn how
8:10JSON looks while we're proceeding with
8:12the course. Um, and that's why I'm going
8:13to be using this. Even if it looks a
8:14little bit more intimidating, don't
8:15worry too much about it. Okay. So, I
8:16said that I'd talk about fields, right?
8:18So, fields in N&M just as I was covering
8:20on the previous video are stuff like
8:22this, right? We have this sort of center
8:24node config option here for our Google
8:26Sheets node. Um, you know, one of the
8:28fields we selected was this YouTube
8:31credential to connect with. Another one
8:33was this resource sheet within document
8:35operation document sheet. But I want you
8:37to know that these are actually all
8:39representable in code as well. So as you
8:43see over here, we have two different
8:44types of fields. One's called fixed and
8:46the other is called expression. So by
8:48default, just to keep your life easy and
8:50to not like freak you the hell out,
8:52especially if you're like a newbie and
8:53an um they're going to keep all the
8:55fields to the fixed type. But if you
8:57click on
8:58expression, you'll see that things are
9:00now a little bit different.
9:02Notice how when I went to fixed, we had
9:05like a nice little, you know, it said um
9:07leads January 27, 2025. And then when I
9:09jump over to expression, now we have
9:10some big long ID. So what is this? Why
9:13is it structured that way? And what
9:15exactly does any of this mean? Well, if
9:18we pay close attention, this ID field
9:20here, 1 lowerase o t r r r r r r r r r r
9:23r r r r r r r r r r r a t 4 C capital C
9:25and then the rest of this big long ID
9:27string over here. If we go to our Google
9:29sheet, what you'll see is that that ID
9:31string actually matches the URL of our
9:33Google sheet
9:35exactly. This takes me to a wider point.
9:37Most of the time, sorry about that. Most
9:39of the time, anytime you're accessing a
9:40resource on some API or even just on the
9:43internet, they will store the ID of the
9:45resource, which is sort of like a hidden
9:47representation of it, in the URL. So,
9:51you know, one of the examples that I
9:52provided the other day was I went over
9:53to ClickUp, right? And inside of
9:56ClickUp, I like searched around for some
9:58record. I'm just going to click on this
9:59here. This is this was my old content
10:00calendar. Um, how to send 1,000 cold
10:03Instagram DMs per day. That was one of
10:04the things I wanted to do. This right up
10:06here is the ID of the record.
10:1086B27A7Zm, right? If I wanted to do
10:13something with this through their API,
10:14this is the ID of the record that I
10:16would be calling. So, I want you to know
10:18that like ClickUp, uh, Monday, uh, like
10:20even Gmail, basically every service out
10:22there, they will store the ID of the
10:24thing you want to modify or update or
10:26whatever just in the URL. So if ever a
10:29field asks for an ID, you can almost
10:31always just go to the URL of the thing
10:33on the actual user um you know on the
10:35actual app like the user interface, then
10:37you can find that URL thing. You just
10:39hardcode it in here. Okay, so that's
10:41just a just a brief look at some of the
10:43differences between fixed and
10:45expression. Basically fix a lot of the
10:46time just to to keep you guys um to make
10:49sure that like we're on the same page
10:50here. Fix is just the simpler version.
10:53Then expression is sort of what's
10:54actually going on under the hood. So,
10:56you know, um, NAN just defaults to fix
10:58like it just did here because it doesn't
11:00really want to scare you away. But in
11:02order to really unlock the value of NAN,
11:05we have to go to the expression, um,
11:07field. And I'm going to show you here
11:08why, you know, I basically just use
11:09expression for everything at this point.
11:12Okay. So, looking at the output here,
11:14what we have is we have we clicked and
11:16then we got a click event that was
11:17counted as one item. And so, N8 actually
11:19shows you the number of items that are
11:20passed on. Then we pumped that click
11:23event into Google Sheets and then that
11:25click event outputed four items. So now
11:26we actually we're working off of array
11:28data or tabular data which I'll cover um
11:30in a moment. But essentially with these
11:32four items now what we want to do is we
11:34want to pass each of these items into
11:36artificial intelligence and we want to
11:37have AI tell us something about it
11:39before um writing some cold email copy
11:42for us to insert into an email or maybe
11:43we could just send a Gmail directly or
11:45something. So what I'm going to do is
11:46I'm going to click on this button. I
11:48zoom out a little bit. What we want is
11:50we want um if you go down advanced AI,
11:53we want is we want this open AI node.
11:55And specifically what I want is I want
11:57the message a model. So if you've seen
11:59me connect this in the previous video,
12:01you'll notice that you know in order to
12:02create a new credential, you actually
12:03have to go and you have to find the API
12:05key from OpenAI in order to do this.
12:07This is pretty simple to do. You just
12:08type
12:10platform.openai.com/ I think it's like
12:11account/appi or something. You'll have
12:13to click on this button here to open the
12:15documentation to tell you more. But
12:17anyway, you can basically just create an
12:18API key for Nadn. Um, it's very simple
12:21and very straightforward to do so. And
12:22I've already done this and I've called
12:24it YouTube. So, I'm just going to use
12:25that credential just so I don't have to
12:27like leak another API key. Now, again,
12:29we have a ton. We have a ton of fields.
12:31We have resource text operation message
12:33and model from list choose. Keep in mind
12:36the fields are again fixed, right? It's
12:38trying to make it really easy for us to
12:39select GPT40. So I'm just going to go
12:41down here, type
12:42GPT and four. And then I'm just going to
12:46click 4 O. And now we actually enter in
12:48the text that we're interested in. Okay.
12:51And this is really where you're going to
12:52start learning the differences between
12:54the fixed and the expression. So fixed
12:56again, fixed is just I mean it's what
12:57the name implies. It's fixed. It's text.
12:59You can't make this dynamic. You can't
13:01add variables to it. It's the simplest
13:02way to get up and running with a node,
13:04which is why nad will default to fixed.
13:07Um, but over the course of the next few
13:08minutes, I'm going to convince you to
13:09basically always just use expression.
13:12Okay. So, I I saved my prompt somewhere
13:14else. The first thing I'm going to do is
13:15I'm going to add a system prompt. So,
13:16I'm going to go down here to system.
13:17I'll just say you are a helpful
13:19intelligent writing assistant. Usually,
13:21the way that you will do um AI calls is
13:23you will have a system prompt first.
13:26Then you'll have a user prompt after.
13:28And the user prompt is where you
13:29actually give it the instructions you
13:30want it to do. So, you know, in our
13:32case, it's going to be like, hey, I want
13:33you to write a bunch of fields that are
13:34templates that we're going to insert
13:35into a cold email later. And then after
13:36you have the choice to provide a bunch
13:37of examples. So you could provide an
13:38assistant prompt and then you could do
13:40another user prompt. Assistant prompt.
13:41User prompt. Assistant prompt. You can
13:43do that however many times you want just
13:44to show it how things work. For the
13:46purpose of this example, I'm just going
13:47to be providing a single user prompt.
13:48And what I'm going to be doing here is
13:50I'm just going to copy over my prompt
13:52below. Let me paste that in. And let's
13:55just read through this together. Your
13:57task is to personalize an email. You'll
13:59do this by taking as input a prospect
14:01LinkedIn profile. Then editing five
14:03templates for different sections of the
14:05email. Subject line, icebreaker,
14:07elevator pitch, call to action, and a PS
14:09or postcript field. If you're unfamiliar
14:11with postcript, you know, at the bottom
14:12of an email, it'll just say PS, I really
14:15miss you. Can't wait to see you. That's
14:17what a postcript field is. We basically
14:18want AI to automate that for us because
14:20there's a lot of value in making those
14:22postcript fields seem human written.
14:25Anyway, now we're offering it some
14:26templates. subject line. Hey, name I
14:29think I have something for you. Re and
14:31then cool thing about them that we
14:33discovered. Let's just go unique thing
14:35about them or their company. Icebreaker,
14:39I know you're doing thing and I've been
14:41following related thing for a while, so
14:43I figured it made sense to chat. Next
14:45elevator pitch the TLDDR. I think I can
14:47add 5K a month to their paraphrase
14:50business with a few automated systems.
14:52And then there's a call to action. I
14:54just did this for a very similar
14:55industry company and we had 28,350 in a
14:58few months. They do related things. So
14:59I'm very confident I can duplicate this
15:01at minimum. Would be 100% risk-f free. I
15:04guarantee at least 20 appointments
15:05booked or you wouldn't have to pay.
15:07Pretty neat, huh? So then I give it a
15:09bunch of guidelines. And feel free to
15:10pause the video if you want to take a
15:11look at it. The last thing that I do is
15:13then I say respond in JSON using this
15:17format. And if you've at all used AI
15:19before, you'll see this JSON thing come
15:20up again. JSON. JSON. JSON. We're going
15:22to cover that in just a few minutes, so
15:24buckle up. Okay, great. So, we've given
15:26it a ton of uh instructions in the first
15:28user prompt. So, what I do next is I
15:30just give it a user prompt with the
15:33actual body of the input that I want to
15:35give. And if you think back here um you
15:38know what this Google sheet is just just
15:39so you guys um are all on the same page
15:41as me is I've basically gone and I've
15:42scraped a bunch of data about random
15:44people on the internet that fulfill some
15:46criteria that I have. So, chief
15:47executive officer, director of demand
15:49generation, director of marketing,
15:50business development, manager, some
15:52dentistry person or something. Okay. And
15:54then I have a bunch of fields here. One
15:56of the fields I have is I have a summary
15:57field where people basically write their
15:58own summary of who they are and what
16:00they care about. We have a ton of other
16:01fields as well. We have company
16:02location. We have a description of their
16:05title. We have um I don't know their
16:07their industry. And the cool part about
16:09AI is you could just feed this into a
16:10large language model and have it have it
16:11automate something for you. Have it have
16:13it write something customized. And so
16:15that's what we're going to be doing
16:16here. The thing is though, right, how do
16:19I get dynamic data into this? So, I
16:22don't know, let's say um one of the
16:24things I want is I want to feed the AI
16:25the person's full name. Notice how this
16:28is fixed here, right? If I just typed
16:29Amy Wabby, then that means that every
16:32time I do an API call that includes
16:35their full name, I'm going to have it
16:36say Amy Wabby. This is fixed. It's the
16:38same thing every time. If you want to
16:40make this dynamic, what you have to do,
16:42there are variety of ways to do this,
16:43but I'm going to use the expression
16:44field, is you have to click
16:45expression and then you drag the field
16:48that you want and then you drop it. And
16:51you'll see that when I do that, we've
16:53now just inserted a little bit of code.
16:56This is in N8N's
16:59um code format, the equivalent of the
17:02variable that we just pulled from our
17:04pinned data or our our data from the uh
17:06input. And what you see down here is
17:08this is separated into two halves. The
17:10top half is the code representation. We
17:13said full name just in like regular
17:14characters. And I can manipulate this
17:16how I want. Then a colon, then a space.
17:18And then there's uh curly bracket curly
17:20bracket space dollar sign Js N. FU L N A
17:26M E space. And then right curly bracket
17:28right curly bracket. Up here you have
17:30the code representation. And then notice
17:31that underneath here we have result. It
17:33actually shows us what the data that
17:34we're pulling in is from the input,
17:37which was right over here. Now, I'm
17:39going to be feeding it a bunch of data
17:41in order to have this personalized. I'm
17:42going to be feeding in their full name.
17:43I'm going to be feeding in the summary.
17:44I'm going to be feeding in the title.
17:45But I just want you guys to to notice
17:47how these these variables change between
17:50the full name, between the summary,
17:52between the title. And you're going to
17:53notice that there's kind of a pattern
17:54there. Okay. So, full name was that
17:57we'll go title. I'm just going to drag
17:59this
18:00in. Paste it in. Notice how the first
18:03one was jso nf full name. Second one was
18:06jso n.title.
18:08Right. Let's see what the third one is.
18:11Let's go down here to
18:13company. Company. If I drag and drop
18:15this, it now says JSON. Company. You
18:18know that the C is capitalized. That
18:19looks a little bit new, but for the most
18:20part, it's still pretty
18:22self-explanatory. It seems to me if I
18:25were an alien staring at this and
18:26looking to try and figure out what the
18:28pattern here is. It seems to me that
18:29every single time I drag and drop one of
18:31these fields in there, it says dollar
18:32sign jso n dot and then the name of the
18:36variable. And the name of the variable
18:37tends to be whatever I'm looking at on
18:39the left hand side here. So what if
18:41hypothetically instead of me doing this
18:43drag and drop what if I were
18:46to actually just try and write this
18:48myself? Well, let's see what happens. If
18:50I zoom in a little bit, just so we could
18:52all see. If I go curly bracket curly
18:54bracket, you'll see that I'm now
18:57entering sort of the next level up in
18:59NN. I'm now manipulating like code or
19:02JavaScript, their version of JavaScript,
19:03the JMSE path I believe it's called,
19:05directly in the expression editor. And
19:07this is where N gets really powerful
19:09because you also have a ton of built-in
19:10methods and built-in ways you can
19:12manipulate this data with literally one
19:14click, one little button tap without
19:15having to drag and drop all these
19:16modules everywhere. You can just do so
19:17in the convenience of your own field
19:20editor. Okay, so the very first thing
19:21that pops up is it says suggested JSON,
19:23if I just type that and then I press
19:24enter, you'll see that now I have access
19:26to all of the fields that I had access
19:29to earlier. So instead of me dragging
19:31and dropping all this stuff, what if I
19:33just wanted to write the word summary
19:34here to grab this. If I just type
19:36summary, notice how this now turned
19:38green. And we've added all of that
19:39information down here to the results
19:41tab. All that information is here. How
19:44cool is that? So now, you know, if I
19:47want to continue on, I'll go industry.
19:49I'll go dollar sign JSON industry.
19:52Voila. Next, we're going to go company
19:54location. I'm going to go um JSON.co
19:57company location. Voila. Notice how it's
20:00trying to autofill this for me, right?
20:02I'll go title description, dollar sign
20:04JSON dot to ital description. Voila. And
20:09I basically have the ability to do this
20:11um infinitely depending on how nested
20:13the data is in the JSON structure of the
20:15input. I I'll run through how to do all
20:17of that um in a moment, but I just want
20:18you guys to sort of pattern match look
20:20from the outside in. How am I actually
20:21referencing all these variables from
20:23from previous
20:24calls? Okay, great. So, to me, you know,
20:26as somebody that does this sort of
20:28personalization all the time, if we
20:29click on this little button here, we can
20:30actually open up we can see all of the
20:32um code and all of the text. To me,
20:34somebody that does this all the time,
20:35this looks like sufficient amount of
20:36information for us to personalize an
20:38email off of. So, I'm actually just
20:39going to call it there, and we're
20:40actually going to just run this puppy.
20:41But basically what's going to happen is
20:42we're just going to be feeding in all of
20:44this stuff to artificial intelligence
20:46and we're going to be saying, "Hey man,
20:47based off of all of Amy's info, I want
20:49you to tell me something about her and
20:51then I want you to write an email um
20:53based off of the template that I
20:54provided you earlier." The last thing
20:56I'm going to do is I'm going to go down
20:57here and press output content as Jason.
20:58Give this a click. And then I'm not
21:01going to modify any of the options here
21:02either. Um but I'm just going to click
21:04test
21:05step. Okay. Okay, so what just happened
21:07or what is occurring as we speak is I'm
21:09feeding in four items to open AI. I'm
21:11basically Blitz going item one, item
21:14two, item three, item four, and it's
21:16happening all at once before they show
21:18us the output of each of these. So
21:20that's why it takes a little bit longer
21:21than usual. Um, but this is more or less
21:23what's happening under the hood. Okay,
21:25great. And we just received an output.
21:27Um, so what I'm going to do is I'm just
21:28going to zoom out a little bit just so
21:29we could see this in completeness. And
21:32I'll use schema for now just to make it
21:33easier for you guys. You don't have to
21:35like scroll all the way to the right to
21:36see it, but let's take a look. Um, the
21:38output was content, subject line,
21:41icebreaker, elevator pitch, call to
21:43action, PS. So, it actually went it
21:44outputed five fields for us and we can
21:47use those fields in future nodes very
21:50easily. The first thing in the subject
21:52line was, "Hey Amy, think I have
21:54something for you regarding boosting
21:55online strategies." The icebreaker was,
21:57"I know you're leading creative web
21:58solutions and net directives and been
21:59following innovative marketing
22:00strategies for a while, so I figured it
22:01made sense to chat." The TLDDR, I think
22:03you can add 5K a month to your client
22:05focused internet marketing efforts with
22:06a few automated systems. The call to
22:08action, I just did this for a very
22:10similar IT consulting company. We hit
22:12this amount. They do e-commerce and
22:13marketing, too. How cool is that? So,
22:15I'm very confident I can duplicate this
22:16at minimum. Would be 100% risk-f free.
22:18I'd guarantee at least 20 appointments
22:19booked. You wouldn't pay. P.S., even if
22:22we just chat, I'd love to hear about
22:23what you're doing with video marketing.
22:25That sounds pretty cool to me, right? If
22:26I were to receive an email like this,
22:28you know, aside from the subject line,
22:29which is a little bit vague, boosting
22:31online strategies, but you can't fault
22:33the AI for not being perfect 100% of the
22:34time. Um, you know, even if I were to
22:37get something like this, it would seem
22:38as if, uh, you know, like the person
22:40that's reaching out to me did their did
22:42their research at minimum and is
22:43reaching out to me sort of in a
22:44personalized customized way as opposed
22:46to just like blasting me a big sequence.
22:48So, uh, what else do I want to do with
22:50this? Well, if you guys, you know,
22:51remember back to the beginning of the
22:52video, the there weren't just two or
22:53three nodes here. there was um there was
22:55a note that updated the Google sheet.
22:56So, I'm going to show you how to update
22:57the Google sheet. And what we're
22:58actually going to do is we're going to
22:59take this one step further and I'm
23:01actually going to draft some emails to
23:02send to Amy and the rest of the people
23:04here. So, actually the first thing I'm
23:06going to do is I'm just going to go over
23:07here and pin this output. The reason why
23:09is because if you think about it, me
23:11calling um OpenAI there, that was a
23:13little bit like computationally
23:13expensive. It took me a little bit of
23:15time. I don't actually want to have to
23:16rerun that over and over and over again.
23:18pinning the data just allows me to
23:20capture that, cache it, and now I can
23:22just like test all subsequent nodes
23:23using that, which is very
23:25straightforward. Okay. So, what I want
23:27to do, I want to update this Google
23:28sheet. So, I'm going to click here,
23:29search nodes. I'll type sheets. And what
23:31I want to do is I want to um update row
23:34and
23:35sheet. I'm going to select my
23:37credentials again, YouTube. The resource
23:39will be sheet within document. The
23:40operation will be update row. Let's
23:42instead of using the fix, let's actually
23:44just use the expression so I could show
23:45you how this works. Just going to grab
23:47the ID of this field or of this sheet.
23:50Paste that in there. Voila. Then the
23:52sheet that I'm going to be picking, it's
23:53just going to be sheet one. So notice
23:55that the top here we use the expression
23:57field view and then down here we just
23:59use the fix. So it actually use the
24:00expression field view to do an API call
24:02to their backend to discover that sheet
24:04one was the only sheet and then we
24:06selected it there. We can also just feed
24:07in an expression. And as you see when
24:09you go from fix to expression for the
24:11specific sheet type, it just says G
24:13equals Z. G equals Z just refers to the
24:15first sheet. um basically here. So we're
24:17we're always going to be selecting the
24:19first sheet. But anyway, for this I'm
24:21actually going to go from list and then
24:22I'll just go sheet one. Keep this
24:24simpler. Okay. Now it's going to be
24:25fetching a bunch of columns for us. And
24:27basically in order to do this update,
24:29what we have to do is um we have to grab
24:32the data from the previous nodes and
24:33then we have to update every single
24:35column here with that data. If I were
24:37just to, you know, scroll all the way
24:39down and update the columns that I care
24:41about like subject, icebreaker,
24:43elevator, pitch, call to action,
24:44postcript, it would just leave the rest
24:46of these blank, which is kind of
24:47annoying if I'm being honest. But I
24:49don't want the rest of these to be blank
24:50and these to be filled. I want all of
24:51this data because I'm just going to
24:52import this into some cold email tool
24:53later, right? So, what we have to do is
24:56now, this is kind of the initial idea
24:58behind this system. I'm going to go
25:00through and I'm going to update every
25:01single one of these um using the
25:03expression tab and then I'm going to be
25:04pulling data in. But I'm not going to be
25:06pulling data in from here. I'm going to
25:07be pulling data in from one node behind
25:08it. So you guys could see what it looks
25:10like in code basically. Okay. So first
25:12thing we have to do is we just need a
25:13column to match on. In order for the
25:15automation to know which row should be
25:18updated, we have to find data that
25:20includes that email. So I'm going to go
25:22email. Then the first thing I'm going to
25:24do is I'm going to scroll down here to
25:26the previous node, not the OpenAI node,
25:28but the Google Sheets node, the one that
25:29like first listed us the data. I'm going
25:31to drag this feed that in there. And
25:34you'll notice that the format now looks
25:36different than it did before. Previously
25:38we had a dollar sign JSON dot item.
25:40Right now we have a dollar sign and then
25:43a bracket single quote sign the name of
25:45the node another single quote sign and
25:48then another bracket and then we go do
25:50item.json.e. So when you when you access
25:52node data from more than one node back
25:54you have to use this new format here
25:56which is kind of annoying but you'll see
25:58how easy it is when we just like kind of
25:59copy paste and spam our way through. So,
26:03uh, how about this civility? I'm going
26:04to go to expression. I'm going to paste
26:05this in. Then, instead of email, I'm
26:07just going to go
26:09civility. How about this first name?
26:12Let's paste that in there. We'll go
26:13first name. How about this first name
26:16suggestion? Paste that in there. Go
26:18expression. Go first name
26:21suggestion. How about the last name? I'm
26:24going to paste this in there. Go last
26:26name. How about the full name? I'm going
26:29to paste that in there. Go expression.
26:31We'll go full name. How about the title?
26:33I'm going to paste this in there. I'll
26:35go title, profile URL. So, you can see,
26:38you know, we're picking up the pace a
26:39little bit. It's getting a little bit
26:40faster and faster.
26:43Company, company, illegal
26:48name, company
26:51phone. And I'm just going to go ahead
26:52and um cut to me having actually filled
26:55all this stuff out just for brevity.
26:56Okay. Okay. Elevator pitch, call to
26:59action. Looking good. And then last but
27:03not least, we'll do um I think it was
27:05just PS or was it postcript? Yeah,
27:07sorry. It was just PS for that. This is
27:09the one situation which uh the column
27:11name is a little bit different from the
27:12variable name down here. Okay. Now that
27:14we're done with that, let's just quickly
27:16cover um just some little differences
27:18here in the formatting just so we can
27:20get a runup on the JSON which I'm about
27:21to teach you. You scroll all the way up
27:23here. You'll see that some of these or
27:25actually most of these followed this
27:26format. It was oops sorry about that.
27:30Let's go over here. It was um curly
27:33brace curly brace dollar sign the name
27:36of the node in single quotes dot
27:39item.json dot whatever the value was
27:41dots summary. In this case this one was
27:44regular company URL. This one down here
27:46wasvm ID. You'll notice that a few of
27:48these are actually a little bit
27:49different. A few of these in particular
27:51the variable names with spaces. They
27:52weren't just dot, you know, the the
27:54name. It was square bracket single quote
27:58and then the name of the variable that
28:00we're referencing. The reason why we had
28:02to do this instead of just doing the dot
28:05and then the variable name is because
28:08JSON in JavaScript object notation, you
28:11can't query I mean the technical term is
28:12you can't query a key that has spaces
28:15basically just because spaces aren't
28:16really represented. So, you know, if we
28:18scroll down here to some of these
28:20variable names, first space name space
28:22suggestion, there's a bunch of spaces in
28:23there, right? So, the way that you get
28:25around this in uh Nad's formatting is
28:28instead of calling, let me get that
28:30specific example, company legal name or
28:32was it uh first name suggestion. So, the
28:36way that you get around this is you
28:37can't just go first name suggestion cuz
28:40that kind of breaks the formatting here,
28:41right? The way you can get around this
28:43is two things. one, you can make it so
28:44that the input data aka the columns in
28:46your Google sheet are all just one word.
28:48So if instead it was first name
28:50suggestion, this would be fine. You
28:52could also do something like first name
28:54suggestion. Some people do that format.
28:55I don't really like that. I don't know
28:57why. What I do is um called camelc case.
29:00It's kind of like a programming
29:02convention. And here we can get into
29:03like a a lifelong mutually assured
29:06destructive battle where some people
29:07prefer camel case, other people prefer
29:09underlining. Um, but I'm team camel
29:11case. So, go team camel case. Um,
29:13instead, you know, if we want to
29:15represent the spaces, what we have to do
29:16is we have to go brackets here. Um,
29:18single colon first name suggestion,
29:21another col uh another quote sign, and
29:23then another square bracket. So, don't
29:25don't sweat the small little formatting
29:27stuff too much. I just wanted to give
29:28you guys like the best way that I found
29:30to learn this is literally just to like
29:31spam a bunch of examples. Um, that's
29:33what I did when I was picking this stuff
29:34up. I didn't read a bunch of books on
29:37JavaScript object notation or
29:38expressions or whatever. I just spammed
29:40a bunch of examples. And the human brain
29:42is such that if you squint at it long
29:43enough, you'll sort of figure it out
29:45intuitively. Uh, okay, great. So, now
29:46that we've mapped all these, let's
29:47actually go and let's, um, let's update
29:49this data, right? That's the whole point
29:50of this. So, uh, now that we've mapped
29:52all the data, if I click test step, then
29:53I go over here to my Google sheet,
29:55scroll all the way to the right, you
29:57see, and it just took us a second, but
29:58you see that we just, boom, we just
29:59updated all four of these
30:00simultaneously. Uh, we got the subject
30:02line for Amy, subject line for Joe,
30:04subject line for Mercedes, subject line
30:05for Susan. Same thing with all the
30:07elevator pitches, call to actions,
30:09postcripts. You'll see that the the the
30:11copy of the email is pretty similar, but
30:13um it it changes. So, this one's, I know
30:15you're leading creative web solutions. I
30:17know you're le into leveraging customer
30:18voices. I know you're focused on
30:19building relationships. I know you're
30:20advancing digital dentistry. These are
30:22all basically like reframing or
30:25paraphrasing
30:26um the things that they said in their
30:28profile which ultimately uh you know is
30:30meant to make them go like oh okay this
30:31person did their research they read a
30:32little bit about me. So that's pretty
30:34cool. Um why don't we take this one step
30:36further now. Why don't we pin this and
30:37then I'm actually going to create a
30:39Gmail draft in my inbox just so we can
30:41see what's going on here. So I'm type
30:43draft create a draft. I'll connect with
30:46my Gmail credential and this is before I
30:48did the naming convention so it was
30:49probably number three. We're just going
30:51to create a draft. The subject line is
30:54going to be, let's just go to fix now
30:55that we know how to do this. It's going
30:57to be JSON dot uh subject right
31:02here. And then the actual message. It's
31:05going to be pretty interesting, but I'll
31:06show you I'll show you how we put it
31:07together. First thing we're going to do
31:08is we're going to go JSON dot. And then
31:10what I want to do is I want an
31:12icebreaker.
31:14Uh, sorry, I don't want an icebreaker. I
31:17want to go hi. And then I want to grab
31:19the person's name. So I'll go Jason
31:21first name right
31:23here. So hi
31:26Amy, then we have the the JSON
31:28icebreaker. Next up, I want to go JSON
31:30dot uh sorry, dollar sign JSON dot and
31:33then what were we doing here? Was it the
31:35elevator pitch? Yeah, it was the
31:36elevator pitch. Paste that in there.
31:39Then we want to go dollar sign JSON dot
31:41what's the next one? Call to action.
31:44Beautiful. And we also want to go dollar
31:47sign JSON dot and I'm sure you guys can
31:48guess what the last one is, but very
31:50quickly make sure you do make sure you
31:52know u postcript. Now if we open up this
31:55thing in the bigger example window,
31:57you'll see the email says, "Hi Amy, I
31:59know you've been leading creative web
32:00solutions and net directives. Been
32:01following innovative marketing
32:02strategies for a while, so I figured it
32:03made sense to chat. The TLDDR, I think I
32:04can add 5K a month to your client
32:06focused internet marketing efforts with
32:07a few automated systems. I just did this
32:08for and even if we just chat, I'd love
32:10to hear about what you're doing with
32:11video marketing." I guess I actually
32:13need to add a PS sign here. And it looks
32:14like none of these have periods.
32:16Actually, I think this last one has a
32:17period, but not all of these do. So,
32:19just because I was a little bit um fast
32:21in kind of designing this and I didn't
32:23put periods over, I'm actually just
32:24going to add the periods directly into
32:25the expression editor. I'm going go PS
32:28here. Okay. And now, if we open it up,
32:30this is what it looks like. We got
32:32periods everywhere. Cool. Wonderful. And
32:34then we have a little PS sign here. Even
32:36if we just chat, I'd love to hear what
32:37we were doing with video marketing.
32:38Very, very cool. Awesome. Awesome. So,
32:40now that we have that pinned data, um,
32:42why don't we just draft these emails?
32:44So, I'm going to, uh, create a draft.
32:45I'm not actually going to send this cuz
32:46I don't just want to spam a bunch of
32:48these people. I've also changed the
32:49email addresses and stuff, so I'd get a
32:50bunch of bounces. We're just going to
32:52test step. It's executing. We just
32:55executed four nodes. So, now if I go
32:56over here, go to
32:58drafts, you'll see here that we have,
33:01"Hey, Susan, think I have something for
33:02you. Red digital dentistry." Oh, gez,
33:04I'm realizing I didn't put the um email
33:05address in actually. Yeah, I did not put
33:08the email address in. I just did the
33:10draft. U in options, you have to go to
33:12email. And then what we want to do is we
33:13just want to drag that back here. JSON
33:15email to get that address. Let's create
33:17four more drafts just for shits and
33:19gigs. Why don't I just delete the ones
33:21that I just generated uh right over
33:25here. Going to just discard
33:27these. And then you see that the four
33:30that I just did now have just popped up.
33:31And they also have the email addresses
33:34there. So yeah, that's that with that
33:36example. Um, I think at this point you
33:38guys probably have an intuitive
33:39understanding of how these fields work.
33:41And hopefully I've made a case for why
33:43you should just always use expression.
33:44Like there's no real need to do fixed
33:46because if you think about it, like you
33:47could just write the same fixed thing.
33:49Like if I wanted to type, hey, think I
33:50have something for you regarding
33:51marketing strategies. And I just wanted
33:52to send the same thing every time. I
33:54could do so with the expression view of
33:56the field, right? Like same thing. It's
33:58just here I also have the ability to u
34:01modify uh code a little bit and like do
34:03something if I wanted to. So, I
34:06personally am always going to be using
34:07this moving forward. And the reason why,
34:10sorry, it can be kind of a lot to see if
34:12you muck around with. Just always put a
34:13dollar sign first if you're referencing
34:14data from the previous node. Uh, and the
34:16reason why is it's just going to be the
34:18easiest for me. Um, you know, you get
34:20all the variables up here anyway. It's
34:21no big deal. So, we're doing subject.
34:23Stick that in there. We got the subject
34:24line. We are good to
34:26go. So, uh, I think we probably learned
34:28a fair amount about the fixed fields and
34:30expression fields at this point. Um, the
34:32last thing I wanted to cover, I say
34:33mapping different field inputs here.
34:34Last thing I wanted to cover was uh if
34:37we go back to Gmail
34:39here and if we scroll down to actually
34:43this is a bad example. Why don't we go
34:45back to open
34:46AI? You see here how um I selected the
34:50RO field and it was fixed and then I
34:52selected from a dropown user assistant
34:54system whatever. Well, I can actually
34:55just go expression and what you see here
34:57is this is just text that we are feeding
35:00this API the uh the node. We're actually
35:02just writing user. So instead of writing
35:04users, you could also write a system.
35:05This fix stuff. This is just made to
35:07make our life a little bit easier. But
35:08anytime you want to get the actual data
35:10representation, just move over to
35:11expression. So what are some examples of
35:13that? Well, like you see these simplify
35:15output and output content is JSON
35:16fields. We go to expression. You'll see
35:18that what we're actually passing is
35:20we're passing this true value. We're
35:22literally just writing true. Um output
35:25content is JS. If we move it to
35:26expression, you can see we're actually
35:27just passing true here for output
35:29content is JSON. The point that I'm
35:31making is um all of this is basically
35:33just um you know if we just strip away
35:35all of the basic simple stuff. You can
35:37start getting into what's actually going
35:39on behind the scenes. How we're actually
35:41communicating with these nodes. The way
35:42that we're actually communicating with
35:43these nodes in practice is we're sending
35:45the term true. Now the reason why this
35:47one has quotes around it I believe is
35:50because um true is a special case. It's
35:52called a boolean which I'm I'm about to
35:54cover right now. Um so I believe you
35:55need these quotes just for NAN to like
35:57not bug out at you. um just one of those
35:59unfortunate peculiarities of the
36:01platform. But that's that for fixed
36:03fields and expression fields. Okay, next
36:05up, let's talk more about JavaScript
36:07object notation. And if you guys already
36:09know JSON, if you've already
36:10experimented and and understand the
36:12various formatting types available here,
36:14feel free to skip on until we move on to
36:16how data in N8 is represented. Um should
36:18be about 15ish minutes or so. Uh but for
36:20everybody in the audience that doesn't
36:21understand JavaScript object notation, I
36:23just want to go real deep into it and I
36:25want to make sure you understand
36:26everything about JSON because ultimately
36:28as opposed to a lot of other no code
36:30platforms, NAD it doesn't ignore code or
36:33try and shove code away. It actually
36:35embraces code. So understanding a little
36:36bit of some of the um code types like
36:39JSON for instance makes you way more
36:41powerful. This is really what like
36:42everybody that makes money with this
36:44platform uses. We just use JSON to send
36:46data back and forth. Um, and you know,
36:48if you don't know JSON, everything's
36:49going to be a little bit trickier for
36:50you. Okay. So, what's the best way to um
36:54intuitively understand JSON? Well, what
36:56I'm going to do next is I'm going to
36:57walk you through the various data types
36:58in JSON. Uh, I'm going to give you just
37:00like a a brief little um structure and
37:02format, and then we can actually just
37:03walk through JSON kind of step by step
37:06depending on different variables and
37:07stuff like that. So, I'm just going to
37:08go and type in JSON formatter. This is
37:10just the simplest and
37:13freesting platform I found online. As
37:15you can see, we got tons of ads in the
37:16middle here. you don't pay anything to
37:17use it. But basically what's happening
37:19under the scenes is behind the scenes is
37:21it's running um with every time you
37:23press a keystroke it's just double
37:25checking to see if it's a valid JSON.
37:26This is actually pretty useful for us
37:28because we can we can verify if
37:29something is indeed JSON or not just by
37:31looking at it. This isn't the only way
37:32to do it. Obviously we could do a ton of
37:34different things. We could I could open
37:35up like a code platform like VS Code or
37:37something and do the same thing. But I
37:38just wanted to keep this thing
37:39accessible for all of us. All right. All
37:41right. So, zooming way in here, um, just
37:44so I don't get ads in my face 24/7. So,
37:47what is JavaScript object notation?
37:49Basically, JSON um is just a way to
37:54represent data in a structured and
37:58standardized
37:59format that minimizes the number of
38:02characters and it also minimizes the
38:04ambiguity so that when we send data to
38:07and from some API or something, we could
38:09do so as efficiently as possible.
38:12So the way that JSON works, the way that
38:15you send and receive data is based off
38:17of two um two concepts. The first
38:20concept is a key. So I'm going to write
38:22a key here. This key is going to involve
38:24my name. The first name is going to be
38:27sorry um the the key name is going to be
38:28called first name. So the key is just
38:31you can think of it as like the name of
38:32a variable. So the variable is called
38:35first name, but what the variable equals
38:38is a whole different matter. And that's
38:40where the value comes
38:42in. So first name I'm going to set to
38:46Nick. So this here is proper or well
38:49formatted JSON. It's not yelling at us
38:51or anything like that. It's it's it's
38:53actually good, which is nice. So this is
38:54an example of one of the simplest
38:56JavaScript objects that you could build.
38:59It is a onekey uh one value object. The
39:02key being first name and the value being
39:04neck. You've undoubtedly seen examples
39:07of this before if you tried working with
39:08any noode or coding platform um you know
39:12nadn included. The thing is in JSON
39:16there are a few simple but consistent
39:18formatting quirks that you just have to
39:20pay attention to. So the first is there
39:23are variety of different data types. Now
39:25as you can see here what I've done is I
39:27have this open curly bracket and then
39:28close curly bracket. I have the key name
39:31over here, a a colon, that's just these
39:33two dots, and then I have the
39:35value, but what I've done is I've
39:37wrapped everything in these double quote
39:39signs here. So, first name, double
39:41quote, Nick, double quote. The reason
39:43why is because the data type that I'm
39:45going with here is called a string. It's
39:47actually a particular data type. A
39:48string is just like written text. Okay?
39:52So, this is if if instead of first name,
39:54I say ID. This here, this is a string
39:57data type, but it's not like you don't
40:00only have strings available to you.
40:01Although a lot of platforms prefer
40:02strings, you also have a variety of
40:03other data types. Here's another data
40:05type we have access to. This is a number
40:08data type. It's numeric. So, in order to
40:11um you know send and receive numbers,
40:13you don't actually have to wrap them in
40:14quotes. This red here just corresponds
40:17to it being linted or formatted or
40:19whatever by this JSON formatter as a
40:21number data type. So this is still valid
40:23JSON even though we don't have the
40:24quotes around this. Okay, this is not
40:28valid JSON, right? This does not mean
40:31anything because we're using string
40:33characters uh and we're inserting it in
40:35something that the software that we're
40:37going to be using NN is going to be
40:39expecting to be a number. So basic rules
40:42of thumb are uh you can't just write a
40:44string without wrapping it in
40:46quotes. And the unfortunate reality is
40:49numbers can be both numbers and strings.
40:52So three ways to do X. Maybe we call
40:55this titles, right? The three here, this
40:56is a number, right? But we are still
40:58wrapping this within the quotes of a
41:00string. However, this is different from
41:04this. And so in practice, the reason I
41:06harp on this is because in practice,
41:09this usually doesn't matter that much.
41:10No code platforms will take care of like
41:12the type conversion for you between
41:13number to string. Um, if you're using a
41:15number, if you're sending it as like
41:17just the three without the quotes around
41:18it, um, for the most part, that's that's
41:20okay. you'll be able to use this as a
41:21string later on. But in like pure
41:23JavaScript and a couple of programming
41:25languages, you can't actually just like
41:26if you wanted to, I don't know, run a
41:28function after this that added a number.
41:31Um, you know, maybe it was like here,
41:34let me show you number of things, then
41:38title template.
41:40Let's say I had some function where I
41:42wanted to add the number of things to
41:44the beginning of the title template so
41:45that it said three ways to create NAN
41:48flows, five ways to create N inflows, 15
41:50ways to create NAN flows. Some
41:52programming languages wouldn't let you
41:54do that in which case you'd have to
41:55convert this to um you know a string and
41:57then you could just go number of things
41:58plus title template equals 15 ways to
42:00create NAN
42:01flows. Okay, great. So we've covered
42:04numbers. We've also covered uh and
42:06numbers I believe they have some fancy
42:07name int or or technically they could be
42:09floats. It could be a number of things,
42:10but um in our case, we're just going to
42:12go numbers. Next up, I want to cover a
42:14couple of additional data types. So, one
42:17of the data types is called bool. So, a
42:20bool stands for boolean. Boolean just
42:22means zero or one, true or false. So,
42:25true. See how this just turned into
42:26orange instead of gray. Um true is an
42:29accepted bool. And you don't actually
42:30need to wrap uh quotes around this true
42:32in order for it to technically be valid
42:34JSON. Now, for the most part, I will
42:36always just wrap quotes around all this
42:37stuff anyway because, as I mentioned,
42:38they do type conversions and it doesn't
42:39really matter to me too much. But I just
42:41wanted you guys to sort of explain why
42:43sometimes you see stuff that is not
42:45wrapped in quotes. And that's one of
42:46them. You also have a few higher level
42:48data types. And one of the higher level
42:50data types um that I'm going to show you
42:51guys, I'm going to show you two. The
42:53first is I'm going to show you an array.
42:54An array looks like this. It's with
42:55square brackets. So, you have a left
42:57square bracket and then a right square
42:58bracket. And the other is another
43:01JavaScript object. And the really cool
43:03part about JSON is you can infinitely ne
43:06nest different data types within the
43:08values of uh of a key. So I could
43:13theoretically wrap an array which is
43:16just a number of things and then inside
43:18of that
43:19array I could wrap a number of other
43:23JavaScript objects that go infinitely
43:25deep. And I'll show you guys how to do
43:27this in practice, but maybe we'll just
43:29go items. Then here we'll go first name
43:32Nick. Here we'll go first name and we'll
43:35go Sally. Then here uh let's just do two
43:37so I don't run off the page. So now what
43:40we've done is we've created JSON where
43:42we have a key called items. Then inside
43:46of said key we have an array and inside
43:49of set array we have two more objects.
43:52Both objects have the key called first
43:55name. And then they have different
43:56values. The first has a value of Nick.
43:58The second has a value of Sally. Now, to
44:01make people's lives easy, usually the
44:02way that this works is you will do some
44:04level of uh formatting like this string
44:08formatting just to make your life really
44:10really easy. You'll be able to
44:12see like where the item starts and then
44:15there's usually like a fair amount of
44:16indentation and I don't know the exact
44:17amount of indentation, but usually it
44:19looks something like this. Now, at a
44:20glance, you can kind of see the
44:22structure of this. It's sort of nested.
44:23You have um this top level array, and
44:25inside of the array, you have two
44:27objects. first name Nick, first name
44:29Sally. Okay, great. So, let's create a
44:32hypothetical JSON object. And just
44:34because I know the most about myself,
44:35I'm going to be creating this for
44:36myself. Let's hypothetically just create
44:38a JSON object. And let's just do like a
44:40user object. Okay. So, what I'm going to
44:43do is I'm going to go user. That's going
44:45to be the key name. Then I'm going to go
44:47uh colon. And then I'm going to create
44:50another object.
44:54Inside of my user object, I'm gonna have
44:55first
44:56name. First name is Nick. I'm gonna have
44:59a last name. My last name is
45:02Sarafh. Um, I'll have city. My city for
45:06the time being is Calgary. I'll have
45:09um foods he enjoys or foods. Let's just
45:15call it food preferences, right? Because
45:16if you say foods he enjoys, now you're
45:19um insinuating that has to be a he. And
45:20then what if you add a user in the
45:22future that is a woman? Do you want to
45:23change the key name? No, obviously not.
45:25So, food preferences. I'm just going to
45:26add an array. And inside of my array are
45:28going to be a bunch of strings. So, one
45:29of my food preferences is um I don't
45:31know,
45:32Thai. I'm going to have another one that
45:35is uh I don't know, like Japanese. Okay.
45:38So, I like Thai food and I like Japanese
45:39food. Apparently, I like absolutely
45:41nothing else. I have a very strict diet.
45:43Okay, cool. And then why don't we add
45:46um let's just add one more. And then I'm
45:49just going to add one called friends
45:50hypothetically. Um, but because as we
45:52all know, I have absolutely no friends.
45:54Um, and then inside of friends, we're
45:55going to add a another object. We're
45:58going to add an array. And inside of
46:00that, we're going to have first name.
46:02We're going to have Peter, my uh dearest
46:04and longest friend, of course. Thank
46:06you, Peter. Then underneath that, we're
46:08going to have um last
46:12name Griffin because I am now
46:16uh love and family guy. And that's one
46:19of my friends. And then I'm just going
46:20to copy this over. I'm going to add a a
46:23comma because you need a comma in
46:24between all items in an array and also
46:25all items in an object. So we have our
46:28object here. It's a pretty intense user
46:31um object. We have a first name, last
46:33name, the city the person lives in, the
46:34food preferences. We have a list of
46:36friends, right? The reason why I go into
46:39this much uh detail here to create this
46:41object is just because I want to impress
46:42upon you that you can make an object
46:43arbitrarily detailed. You can make it as
46:46detailed as a human being could ever
46:47possibly want. And a lot of the time
46:49you'll see that these APIs that you're
46:50accessing, these these calls that you're
46:52making to these different nodes that
46:53return you data about a particular
46:55software platform, they will be really
46:57really deep and they will have nested
46:58data like six or seven things uh levels
47:01deep essentially. So the easiest ones to
47:04use in my experience are just the ones
47:06that are all um you know surface level.
47:09You just have like a user object and
47:10then a first name and then a last name,
47:11a city and then maybe some food
47:12preferences. But in practice, you know,
47:14we need to be a little bit more capable.
47:16And understanding how data is structured
47:18in JavaScript object notation is uh
47:20probably like half the battle to be
47:21completely honest. So, I believe I've
47:24covered everything I wanted to cover.
47:25The last thing I'll mention is um you
47:27can't have a comma, I believe, be the
47:29last. Yeah, it doesn't allow you to have
47:31a comma for the last item in an object
47:35or an array. So, notice here how we have
47:36a curly bracket, then we have the key
47:38name user, then we have another object
47:40sign, and then we have the key name, and
47:42then the value. the key name and the val
47:44the key name and then the value. Between
47:46each of these, we have a comma, but just
47:48know that at the last item in an array
47:51or the last item in an object, you can't
47:53have a comma. So, you just need to
47:55remove that. If I press format or
47:56beautify, which is just my button that
47:57tells me everything's okay. Um, then you
47:59see that it is indeed formatted and
48:00beautified. Everything's everything's
48:02all right. Okay, cool. So, that's the
48:04meandering um you know, that's sort of
48:06how to understand this stuff from a
48:07bird's eye view. Moving forward, what
48:09I'm going to be doing is just to make
48:10our lives a little bit easier. I'm going
48:11to be showing you guys in every module
48:13or every node I should say on what the
48:15JSON is of the input and the output. The
48:17reason why is it's just going to make it
48:18a lot easier for us to ultimately, you
48:21know, reference stuff and then do cool
48:22things with the data. So, I go back to
48:24our Google Sheets example from earlier.
48:26I'm just going to move the input, sorry,
48:28I'm going to have the output be JSON.
48:30And you'll see that in this case, what
48:32we have is we have an open JSON curly
48:34bracket. Then we have a bunch of top
48:37level keys. So row number over here,
48:40well that's a key. And you can see that
48:42it's represented as a two. Very similar
48:44to what we talked about earlier, right?
48:45You'll notice that the formatting here
48:47is a little bit different. Notice that
48:48this one has an underscore and then
48:49these other ones are all camelc case.
48:51And some of these are capitalized
48:52because these are within quotes. None of
48:54this stuff really matters. But just
48:55showing you guys that there's a there's
48:57a variety of like conventions that
48:58people do. Some people like capitalizing
49:01things, some people don't.
49:03So my recommendation to you just to keep
49:04everything really clean and and expected
49:06is just to pick one format and stick
49:07with it. If you like the underscores,
49:08use the underscores for everything. If
49:10you like the camel case like me, use the
49:11camel case for everything. But anyway,
49:13civility is Mrs. First name Amy. First
49:15name suggestion, it's empty. You know,
49:17when something is empty in JSON, you
49:19just use these quotes. Notice that every
49:21item here has a comma in between it.
49:24Last name, comma, full name, comma,
49:26right? Just going all the way down. And
49:28then if I zoom out, I scroll, you'll see
49:31that what do we have here? This was just
49:32one item. So, if I just click on this
49:34little blue left curly bracket, it'll
49:36actually nest the item for me. And
49:38you'll see that inside of this item are
49:4038 other items. But, it'll just nest it
49:41for me. And then I can see the next one.
49:43Now, I can see the next one. Now, I can
49:44see the next one. Right? We only have
49:46five. So, that'll be it. But now, I want
49:48to show you guys a little bit about how
49:50an format stuff because it's a little
49:52bit different than Jason I just showed
49:53you. But once you understand this,
49:54basically everything from here on will
49:55be child's play. Notice how the very
49:59first character that you see on the
50:01output page on the JSON is a square
50:04bracket. Well, if you think back to the
50:05example that I gave you earlier, if we
50:07click out of this um Pizza Hut ad, as
50:09much as I love Pizza Hut, this array
50:12here starts with these square brackets.
50:15And so we see over here we have a square
50:16bracket as well, that means that this is
50:17an array basically. So the way that data
50:21is represented in NADN is all data on
50:23the platform is represented as an array
50:26of objects. Okay. So if I scroll down
50:29here to how data in NAN is represented.
50:31All of it is an array of objects. All of
50:33it will basically be those two square
50:36brackets on the outside of a number of
50:38items. And you could have as many items
50:40as you want. As we saw, we had four back
50:42over there. And inside of those four
50:44items, we had an additional 38 items
50:46nestled inside. But all data is an array
50:48of objects. Meaning that that's how you
50:50send and receive multiple objects.
50:53Remember at the beginning we had one
50:54item. We just outputed a single variable
50:56there. Well, now after this Google
50:57Sheets call, we're doing four items.
50:59Those four items are represented in our
51:01JSON as an array inside of which is
51:04another object that has the key name row
51:06underscore number, civility, first name,
51:08first name, suggestion, and so on and so
51:10on and so forth. So all data in NAD is
51:12an array of objects. The number one
51:14gotcha that I always see when beginners
51:16start out with this is they end up not
51:19fully understanding how many objects the
51:21previous node is sending or the current
51:22node is receiving. And so then when they
51:24try and reference a particular item
51:26inside of the data structure, they find
51:28that it just doesn't exist or they need
51:30to like index it, they need to slice in
51:31to find a specific item inside of the
51:33array of items or some other problem.
51:35But this is the number one problem that
51:37I see in practice just running through
51:39reading like N8 and help threads and
51:40stuff like that that people struggle
51:41with on this platform. So if you
51:44understand this the fact that all inputs
51:46and all outputs are an array of items
51:48represented as follows and now if you
51:50understand how to format JSON what JSON
51:52looks like and now further if you just
51:54make it so that you look at the JSON and
51:56not necessarily the table or the schema
51:58format every time you're sending and
51:59receiving data you will solve the
52:00biggest gotcha that people have in their
52:02net it's just going to be a lot easier
52:03for you moving forward to you know
52:05create flows you're you're basically
52:06going to take so much of the load off
52:08that most other people spend like hours
52:10and hours and hours trying to debugging
52:12um right from the get- go, which is
52:13ultimately what I wanted to do here.
52:15Okay, great. So, now we know that data
52:17in NAN is represented as an array of
52:18objects. So, how do you actually
52:20reference that data? You guys remember
52:21earlier in that example here where we
52:23were using this Google sheet module,
52:25sorry, this Google sheet node, I should
52:27say. And if we scroll down here, we were
52:30updating a field using data not from the
52:33previous node, but from a few nodes
52:35back. Well, basically if I go back to
52:37JSON here, what you can see is we can go
52:40one node back to open ad, two nodes back
52:42to Google sheets, three nodes back to
52:43when clicking test workflow. Okay, let's
52:46just go to this Google sheet. In order
52:48to reference data, actually in this
52:49case, we will use the schema cuz you can
52:51actually see sort of them logically top
52:53to bottom. In order to reference data
52:55more than one node back, what we have to
52:56do if we just want to redo this email
52:58one, we go curly bracket curly bracket
53:00dollar sign. Then what we want to do is
53:02we go this left round bracket. Then we
53:06have access to all of our earlier nodes.
53:07We can select the current node open a
53:09but we can also select Google sheets and
53:11we can also select when clicking test
53:12workflow we want is the Google sheets.
53:14And then if you just dotindex if you put
53:15a period then you'll get an
53:18item. And the reason why I bring up this
53:20item is because basically all of this
53:23stuff is buried under this dot item
53:28syntax. And it's kind of annoying but in
53:30order to reference I don't know the row
53:32number what we have to do is we have to
53:33reference the Google sheet. Then we have
53:35to reference the item. Then we have to
53:36reference JSON. Then we have to
53:38reference the row number. Why? Because
53:40NAN actually hides some of this
53:42information from us. We don't actually
53:43see the nested data structure. All we
53:46see is the nice representation of it.
53:47Okay. So this isn't actually represented
53:50this way despite the fact that it looks
53:52kind of like it is the way that this
53:54actually looks kind of underneath the
53:56scenes behind what NAD is showing us is
53:59it looks like this. And if you
54:00understand this, you'll understand how
54:01to reference basically any item in NAN.
54:04So this is equivalent to what we're
54:06seeing here. What we actually have is
54:07there's an additional two layers between
54:09us accessing the data through the dot
54:11thing. It's actually
54:12item.json and then we have the row
54:14number stability, first name, first
54:15name, suggestion, stuff like that. Okay,
54:17so that means that when we want to
54:18access it kind of just just looking over
54:19here, the very first thing we have to do
54:21is we have to reference the Google
54:23sheet. Then think about it logically.
54:25Then we have to reference the item. So
54:27go
54:28item. Then we have to reference the
54:30JSON.js.
54:32And then we have to reference the row
54:33underscore number if we want to like
54:35that. And then we get that data. Okay.
54:38So big issue, big misunderstanding I
54:40would say with Naden. Um unfortunately
54:42their documentation in my experience is
54:44not clear enough to really elucidate
54:46what's going on here unless you have a
54:47programming background. Um but just want
54:49you guys to know that this is how it's
54:50done when you reference nodes that are
54:52more than one module back. If you wanted
54:53to just reference something in the
54:54previous node, it's a lot easier. You go
54:56dollar sign and then you go jso n. then
55:00you can just go immediately into the
55:01variables. Message content or something
55:04like that dot subject line for instance.
55:07All right, so let's start looking at
55:08some of these foundational nodes over
55:09here because I think at this point we've
55:11done four different workflows and I
55:13think you guys probably have a
55:14reasonable understanding of how to put a
55:15workflow together now as well. Some of
55:17the more nuanced portions of NAN like
55:19the way that they do their JSON, some of
55:21the the nuances behind burying names
55:24inside of various keys and how to do
55:26arrays of objects and backtrack and all
55:28that fun stuff. Let's actually cover
55:30like nodes because nodes are ultimately
55:31what you guys are going to be using on a
55:33daily basis. After we're done that, then
55:34I'll I'll rebuild this flow up here and
55:36I'll show you guys how all that stuff
55:37works under the hood. This will allow us
55:40to use some of the more um I guess code
55:44oriented features of N&N. Then I think
55:46after this point like you guys have a
55:48reasonable enough understanding to build
55:49most things. It's just a matter of like
55:51what can you build and how exactly do
55:52you put the various Lego blocks I've
55:54shown you together. That's what the
55:55subsequent videos in this course are
55:57going to are going to ultimately just
55:58show you. just going to be non-stop
55:59building 24/7, baby. Anyway, so let's
56:03cover these foundational nodes. The
56:04first thing is we're going to cover
56:06nodes for doing things. So, HTTP
56:07requests, web hooks, and open AI nodes.
56:09And we'll cover nodes that modify flows.
56:11So, if filter, merge, split into a
56:12batches. There are a couple of other
56:13ones, but these are the ones that we're
56:14going to be focusing on, at least for
56:16today. So, you know, in terms of nodes
56:18that do things, um, if you guys aren't
56:19familiar with, um, HTTP request, this
56:22stands for hypertext, I don't know,
56:24hypertext transfer protocol. And what
56:27we're doing when we do an HTTP request
56:29is we're doing the same thing that your
56:31browser does when it goes to a website.
56:33So just like when I go to google.com,
56:36I'm sending a request to Google,
56:38receiving a bunch of information what
56:39this web page looks like, and then I'm
56:41using my browser Chrome to render it
56:43into the beautiful, wonderful image you
56:45have in front of me. The HTTP request
56:47does the same thing. It just it just
56:48returns the thing to you in in the code.
56:50You don't have that rendering portion.
56:52So I'm going to do a get request here.
56:54And the get request is just the simplest
56:56and most basic request. And this is
56:58ultimately what you're probably going to
56:59be using for for most cases. And the URL
57:01I'm going to be doing is just my own.
57:03Leftclick.ai. So leftclick.ai just for
57:05the purposes of this discussion. Looks
57:07like this. We build hands-off growth
57:09systems for B2B founders. There's a
57:10bunch of information about what our
57:11clients get, our leads. The lovely Joe
57:13Davies left me a testimonial. I should
57:15probably touch this website up at this
57:16point. It's been the same for a while.
57:17But anyway, I'm just doing an HTTP
57:19request using a method get to
57:22leftclick.ai AI with no authentication,
57:24no nothing. We're just going to see what
57:25happens. So, let me click that test
57:26step. And the response that we've
57:28received is again an array of objects.
57:31Our one object has a key name data. Then
57:34inside of that key name, you'll see that
57:37there is a ton of code, HTML it's
57:40called. Okay. And just because this is
57:42not the easiest to see here, I'm just
57:43going to go to schema view so you can
57:45see a little bit more of it. But
57:46basically, this here is the code of my
57:48website. This is what my website looks
57:50like to the browsers. um you know and
57:52like what ultimately my browser uses to
57:54render it. You can see it says leftclick
57:56space vertical carrot space AI and
57:59amperand. This is just a symbol that um
58:01allows it not to break any characters
58:03process optimization. Left click is an
58:05AIdriven performance optimization agency
58:07is cutting edge tech to scale your
58:08company. This is all the code right it's
58:10pretty badass. If I were to go to
58:11leftclick and then I were to go to
58:14inspect. If I were to open this up this
58:17is like the Chrome dev tool which allows
58:18you to see the code of the website. It's
58:20the exact same thing that's over here in
58:23the bottom lefthand corner, right?
58:24Literally no differences whatsoever. You
58:26built your agency, we'll scale it. The
58:28only difference is some symbols like the
58:29amperand or maybe the at sign, they just
58:31have like little replacements here or
58:33there so they don't break any um string
58:34formatting. So that's the HTTP request.
58:36Why why does an HTTP request matter and
58:38why would we want to do an HTTP request?
58:40Well, the reason why is cuz you can do
58:42pretty cool stuff with this. Like if I
58:45go um HTML and then I say extract HTML
58:48content. What we can do is we could use
58:51the code of the page to pull out all of
58:53the text. Okay. So why don't I just go
58:55text? I'll go P. Uh let's just do H1,
58:57H2, H3, H4, H5, H6. Let's do P and
59:01return this value as text. And then I'm
59:03going to return uh let's just test this
59:04and see what happens.
59:06What we're doing is we're basically
59:08feeding in the HTML and then we're using
59:10various CSS selectors they're called to
59:13extract a bunch of text for us. And it
59:14looks like I didn't do this right
59:15because we're not actually retrieving
59:17anything. Let's just try P for
59:19now. We'll do this. You're seeing
59:22already that we've extracted a bunch of
59:24P text. We've extracted basically like a
59:27specific type of
59:28tag inside this website that starts with
59:32a P. Okay. Now, we can do the same thing
59:34with a variety of other tags. Let's say
59:36I want to do H1. This is going to return
59:37all of the um top level selectors
59:40basically. So, let's do H1
59:43test. We build we build hands-off growth
59:45systems for B2B founders. That's pretty
59:47cool. If I return an array, let's return
59:49all of them. We build hands-off growth
59:51systems for B2B founders. A better way
59:52to build ops. What our clients get. If I
59:54do uh I think if I want to select
59:56multiple, I just would I just do P like
59:58this. H1 and P. Yeah, there we go. Okay.
1:00:02So now I'm getting all the text of the
1:00:04website. We build hands-off growth
1:00:05systems for B2B founders. Find the
1:00:06perfect offer. Automate your lead
1:00:07acquisition. Solve your project
1:00:08management. A better way to build ops.
1:00:10This is all the text of the website. And
1:00:12all I needed to do in order to feed this
1:00:14in was I basically went through and then
1:00:16I fed in a bunch of elements which I
1:00:17know just correspond to text like this.
1:00:20And then I pressed test step. It went
1:00:22through and it extracted all of them
1:00:24into this big fat array which is really
1:00:26cool. Now like if you think about it, I
1:00:28could actually do some pretty cool stuff
1:00:29with this. I could have AI tell me
1:00:32something about the site very easily.
1:00:34You're a helpful intelligent uh website
1:00:36scraping
1:00:37assistant. We'll go got to add my
1:00:40credential first. We'll go down here and
1:00:43I'm just going to have
1:00:44AI tell me a little bit about this
1:00:46website. Return in JSON just some data.
1:00:49I'll do that as my system prompt. And
1:00:51then here, your task is to take as input
1:00:54a bunch of scraped website text and
1:00:58return as output a JSON that follows
1:01:01this
1:01:03format. I'm going to say summary. I'm
1:01:07going to say three unique
1:01:10points. We'll do an array. We'll do um
1:01:14probable customer demographic. Okay, I'm
1:01:17going to have it return an object. we'll
1:01:20see contact
1:01:22information if any and then we'll do I
1:01:25don't know some sort of like array of
1:01:27objects. Okay. And then that's that's
1:01:30what we're going to have it return.
1:01:30We're going to output the content as
1:01:32JSON and then as input you add a
1:01:34message. What we want to do is we just
1:01:36want to join this is um being output as
1:01:38an array right now. Right? Arrays as we
1:01:40see are many options or many different
1:01:42um things on various lines. What we want
1:01:45to do is we want to take all of this
1:01:46output data. We just want to turn it
1:01:48into one big long string. The way you do
1:01:50that here is I would use the expression
1:01:52tab. And then I'm just going to add some
1:01:54lines so the AI knows that this is my
1:01:56input. Then I'm just going to go
1:01:58JSON.ext and then dot we'll just go
1:02:01join. Join is just a way to convert an
1:02:03array of items into just one big long
1:02:06string. And the thing you put inside of
1:02:07the join is you just put what you want
1:02:10to separate it by. So in my case, I'll
1:02:12just separate it all with a new line. If
1:02:14I enter the detailed editor here, you
1:02:16can see that now I've just turned all of
1:02:17this into one giant long string. I'm
1:02:20going to feed this into AI and I'm going
1:02:21to have it just tell me something about
1:02:22the
1:02:23website. So, this took us just a few
1:02:25seconds and we already have a scraper
1:02:27that's basically capable of coming up
1:02:29with and then outputting a summary of
1:02:31what I do, three unique points that
1:02:34separate me from the competition,
1:02:36probable customer demographic
1:02:37information maybe I can use to do
1:02:39something, then contact information if
1:02:41any. And it looks like it separated that
1:02:43into a subobject that says method, book
1:02:44a call, details, get started today,
1:02:46platform, website. As I'm sure you guys
1:02:48could imagine, I spent 15 seconds
1:02:49putting this puppy together. If you guys
1:02:51wanted to maybe scrape emails or do
1:02:52something like that, you could put
1:02:54something together that does this pretty
1:02:55easily. So that's the HTTP request node.
1:02:58Pretty simple, pretty straightforward.
1:03:00The next thing I want to show you is I
1:03:01want to show you basically the inverse
1:03:03of the HTTP request node. Instead of us
1:03:05sending data, I want to show you a quick
1:03:07and easy way that we can receive a
1:03:09little bit of data if necessary. And
1:03:11it's nowhere near as hard as you think.
1:03:12There are a variety of different ways
1:03:13that you could do this, but I'm going to
1:03:14show you guys a really simple and easy
1:03:16one that I personally use all the time.
1:03:18It's called the web hook. So, I'm going
1:03:20to go over here. Then, I'm going to type
1:03:22in web hook. Starts the workflow when a
1:03:25web hook is called. Basically, what a
1:03:27web hook is is it's just a server URL
1:03:29that you spin up, almost like my website
1:03:31leftclick. And every time that server
1:03:33gets a request to it, it'll show up here
1:03:36with all of the data. Why is this so
1:03:38valuable? Well, it allows us to do a
1:03:40million things. Connect workflow to
1:03:42workflow, add up and create our own API
1:03:44integrations, do a variety of things
1:03:46that otherwise we wouldn't really be
1:03:47able to do without them. This is
1:03:49basically the glue that holds the
1:03:50internet together. And this is a quick
1:03:51and easy way for you to make your own
1:03:53piece of that. So, this is what the web
1:03:54hook fields look like. We have a test
1:03:55URL, production URL. Don't worry about
1:03:57the distinction there for now. We'll
1:03:58just use test URL. HTTP method we want
1:04:01to allow to access our service. Think we
1:04:03might actually allow multiple. One of
1:04:04these I think allows us to do multiple,
1:04:06but we're just going to go with get for
1:04:08now. The path, we're going to leave the
1:04:10path as fixed. The path is just this URL
1:04:12string. Authentication, we're going to
1:04:14turn this off. We don't want any
1:04:15authentication. They recommend that you
1:04:16have authentication, but for simplicity
1:04:18sake, I'm just not going to have any
1:04:19because otherwise it might be a little
1:04:20bit too much at once. Then we're going
1:04:22to do respond immediately. What I'm
1:04:24going to do is I'm going to set up a
1:04:25test event for this URL. Okay. Actually,
1:04:27I don't know if I can do this with the
1:04:28same workflow. Actually, no, I can't
1:04:30because the workflow is already running.
1:04:31So, I'm actually going to make another
1:04:32workflow really quickly. And I'm going
1:04:34to use that to call this web hook to get
1:04:36some cool data. So why don't I create a
1:04:39workflow. We'll just call this three NAN
1:04:42concepts. And then we'll go web hooks
1:04:44HTTP
1:04:45requests. I'm going to make a new HTTP
1:04:49request here. It's going to get this
1:04:51long thing that I've done over here.
1:04:53Okay, I'm going to test it. Then over
1:04:55here, I'm going to grab that data. And
1:04:57as you can see, like what just happened
1:04:59if you were paying close attention is
1:05:00this just ran the second I sent the data
1:05:02from this node which is in another
1:05:04workflow over to this node which is on
1:05:06the current workflow. We received a ton
1:05:08of info and the info that we received
1:05:10was received a big object one item
1:05:12inside of our array of objects here. So
1:05:14a single object with a key name headers
1:05:17which had a bunch of other data
1:05:19underneath params query body web hook
1:05:22URL execution mode test. So this might
1:05:25look a little bit dry and a little bit
1:05:26boring to us right now. But what's the
1:05:28value here? The value is you can run
1:05:30something from one workflow, send it to
1:05:31another workflow really easily. So in
1:05:33our our first example, we sent no data.
1:05:35But what if I go back to my other
1:05:37workflow? Okay, that's number three
1:05:39here. And then I send some query
1:05:40parameters and I say first name and I
1:05:43say Nick. Then I go here a last name
1:05:47surive. Then here maybe I go UU ID.
1:05:50That's just like user ID. And then I
1:05:52type something like this. Now, if I go
1:05:54back here and I listen for a test event,
1:05:57I go back here and then I send the test
1:05:59event. Now, when I receive it, not only
1:06:01do I get the headers, sorry, the headers
1:06:04over here, not only do I get the params
1:06:06inside of our query are the variables
1:06:09that I just sent over inside of JSON.
1:06:11First name, last name, UU ID. So, man, I
1:06:14can do so many cool things with this.
1:06:15It's crazy. I could connect this to any
1:06:19web service out there. just give this
1:06:21URL as the URL where the events are sent
1:06:23and then voila, I basically have like an
1:06:25infinite machine. I'll show you guys a
1:06:28quick example right now using
1:06:30ClickUp, but you guys can extend this
1:06:32example and do whatever the hell you
1:06:33want with it. So, ClickUp is just this
1:06:36project management platform that I have
1:06:38that allows you to send out web hooks.
1:06:40And most services that are good will
1:06:42allow you to do stuff like this. But you
1:06:44see there's a call web hook feature
1:06:46here. I'm going to go back to my web
1:06:48hook and I'm going to copy this URL.
1:06:50Now, this is for get only. I don't
1:06:52actually remember if ClickUp sends a get
1:06:54or a post. So, we're going to see what
1:06:55happens here. And then what I'm going to
1:06:57do is I'll just have status change.
1:07:01We're going to say from specifically
1:07:04hook to specifically
1:07:08outline. And we're going to create this.
1:07:10And basically what this means is when I
1:07:11change a field called status inside of
1:07:13my my project manager, it sends a web
1:07:15hook over to this
1:07:17address. So hook to outline finds
1:07:19something that's hook. Maybe this one
1:07:20here. Now what I'm going to do is I'm
1:07:22going to go over here, listen for a test
1:07:23event. Then I'm going to change this to
1:07:25outline. And I don't remember if it's a
1:07:27get or a post request. So we might have
1:07:29to wait and try two or three. This
1:07:32unfortunately does not respond to the
1:07:33methods that are not the same. methods
1:07:36are, you know, kind of a deeper story,
1:07:37but basically there are variety of ways
1:07:39you can query a website or a web
1:07:41service. HTTP, most commonly, you'll do
1:07:43either a get or a post. Um, in the
1:07:47specific instance of ClickUp, it looks
1:07:48to me like they're probably using post.
1:07:49So, I'll go HTTP method. I'll go
1:07:51post. Now, I'll listen for this test
1:07:53event. I'll change this back to
1:07:56hook. Then, I'm going to change this
1:07:58back to outline. And now that it's
1:08:00outline, um, we're waiting for this this
1:08:02post request. Let's see if we we are
1:08:04receiving it from ClickUp. Okay, great.
1:08:06Looks like we received it. Now, what did
1:08:09we receive in reality? Well, excuse me.
1:08:11I'm like really close to sneezing, but
1:08:13I've decided not to, so I won't. Uh,
1:08:16before we updated the query field, now
1:08:18we're updating the body field. We see
1:08:19it's built into ClickUp. What we did,
1:08:21ClickUp has a number of default things
1:08:23that they send over when you do this web
1:08:24hook integration. One of them is the ID
1:08:26of the record. Now there's the trigger
1:08:28ID ID the trigger payload ID the name of
1:08:31the thing which was three chat GBT
1:08:33prompt engineering hacks you need to
1:08:34start using next some hooks some order
1:08:38in text some information about the
1:08:39person that created it the point that
1:08:41I'm making is we just created our own
1:08:42integration with ClickUp and it took me
1:08:44like 30 seconds realistically after I
1:08:45got off the HTTP method hump so in
1:08:48practice sometimes APIs like ClickUp I'm
1:08:51sure they have API documentation
1:08:52somewhere but sometimes they just don't
1:08:53tell you right at the point of creating
1:08:55the web hook whether it's going to be a
1:08:56get or a post request. So if your get
1:08:58request doesn't come in, just change the
1:08:59HTTP method to post and then rerun it
1:09:02with the post uh example and then one of
1:09:04those will work, which is pretty cool.
1:09:06Okay, so that's how you do it as a test
1:09:08URL. Ultimately though, we don't just
1:09:10care about having this workflow be sort
1:09:12of a test. We want it to be live. And so
1:09:13when your workflow moves to production,
1:09:16aka you publish it and you make it live
1:09:18to actually interact with the internet,
1:09:19you're going to want to go over to this
1:09:20production URL and then copy this URL
1:09:22and update all of your web hooks to send
1:09:24here. This will enable you to activate
1:09:26this. If it's in test mode, you actually
1:09:27won't be able to activate this. Um, just
1:09:29I guess for safety or security purposes.
1:09:32It just makes the transition to publish
1:09:33it unfortunately involve an additional
1:09:35step, but it also makes your workflows a
1:09:37little bit more secure. So, that's how
1:09:39you do web hooks. The last thing I'll
1:09:41mention are these OpenAI and AI nodes.
1:09:43Now, I'm going to have many, many videos
1:09:45after this one be all about AI agents
1:09:47since that's obviously the big thing
1:09:48that's blowing up right now. What I'm
1:09:50going to do here is I'm just going to
1:09:52cover them super super briefly. I'm not
1:09:54even going to like run anything, but I
1:09:55just wanted to show you guys that NAN is
1:09:57very AI native. And so whereas I've been
1:10:00doing some very basic um OpenAI calls
1:10:02with this OpenAI module, there's a
1:10:04variety of things you could do. You
1:10:05could create an AI agent which generates
1:10:07an action plan and executes it. Uses
1:10:09external tools. You can have OpenAI
1:10:11message an assistant or GPT. This is
1:10:13what we've been using. Some basic LLM
1:10:15chains and a bunch of like specific
1:10:17tools that are used to do things like
1:10:19categorize information, summarize
1:10:21information, and so on and so forth. AI
1:10:23agent. Just to give you guys a very
1:10:25brief example, probably is one of the
1:10:27most intimidating looking modules or
1:10:28nodes, but it's actually one of the
1:10:30simplest in practice. When you create an
1:10:32AI agent, it'll automatically open up
1:10:34this when chat message receive node on
1:10:36the side. And then you'll see that down
1:10:37at the bottom of my screen, there's an
1:10:38additional button that allows me to chat
1:10:40with my with my model. But in order to
1:10:42make this work, what we need to do is we
1:10:44need to hook this up. Notice how there's
1:10:45this little um warning here. What we
1:10:47need to do is we need to go down to chat
1:10:49model. We actually need to select the AI
1:10:51module or AI node that we want the AI
1:10:54service I should say that we want to
1:10:55use. For most intents and purposes, I
1:10:58use OpenAI. This is just the best to me.
1:11:00But you could use O Lama, Mistral,
1:11:02Google, Gemini, Anthropic. Feel free to
1:11:04play around with this for whatever your
1:11:05use case is or whatever your data
1:11:06privacy security requirements are. So,
1:11:09I'm going go down to my OpenAI chat
1:11:10model. The model I'm going to be using
1:11:11for this is going to be GBD40. I just
1:11:13find it has better answers. And then now
1:11:16you'll see that the warning sign is
1:11:17gone. Now we have an additional node I
1:11:19can drag and drop here. And now I can go
1:11:21to chat and I could say, "Hey, how are
1:11:22you doing?" We've essentially opened up
1:11:24our own chat window. Hey, I'm just a
1:11:26computer program, but I don't have
1:11:28feelings, but I'm here and ready to
1:11:29assist you. Thanks, Chat GPT. And on the
1:11:31right hand side, probably the most
1:11:32valuable part about this is you could
1:11:33see a log of what is happening and how
1:11:35many nodes were called in order to get
1:11:38you the result. This is important
1:11:39because the whole point of AI agents is
1:11:41their ability to call other tools to do
1:11:43things for you. So this says system,
1:11:45you're a helpful assistant. human, hey,
1:11:47how are you doing? This is just their
1:11:49prompt setup. So, the input to OpenAI
1:11:52was this right here. And because we just
1:11:54asked how it's doing and so on and so
1:11:56forth, um, you know, it didn't it didn't
1:11:57really do anything special. There were
1:11:58no additional tools. This is the same
1:12:00thing as you just sending a message to
1:12:01chat GBT essentially. Now, in order to
1:12:04make an AI agent like really work,
1:12:06you're going to want to add two things.
1:12:07The first thing you're going to want to
1:12:08add is you're going to want some sort of
1:12:09memory. If an AI agent doesn't have
1:12:11memory, then basically if I go back here
1:12:14to chat and then say, "What did I say in
1:12:17my last
1:12:18message, it will have no context or no
1:12:21idea. I don't have any access to past
1:12:23messages or personal data. Each session
1:12:25is independent." Basically, this is like
1:12:26a one it's like it's like a send a
1:12:29question, receive an answer sort of
1:12:30window. But we don't want that. We want
1:12:32this to actually have access to our chat
1:12:33history. We want it to see what we've
1:12:34been talking about over the course of
1:12:35the last like 20 or 30 minutes and be
1:12:37able to reference those. So, there are a
1:12:39variety of ways to do this. Basically,
1:12:40you need to implement some sort of
1:12:41database. I'll show you guys how to
1:12:42implement some more complex databases in
1:12:44the future, but the simplest one, the
1:12:45one that Naden provides right out the
1:12:46gate, the one that most people on
1:12:47YouTube are going to be talking about is
1:12:49this window buffer memory. Window buffer
1:12:51memory basically just allows you to
1:12:53store it here inside of the test window,
1:12:55which is the easiest to do. And the
1:12:57default is five messages. So, u
1:13:00basically every time you send it a
1:13:01message, it will send up to five pass
1:13:03messages. But just for the purpose of
1:13:05this discussion, I'm going to go 10. So
1:13:06now what I'm going to do is I'll go to
1:13:08chat and then I'll say hey how are you
1:13:11doing and I'm going to say what did I
1:13:14ask you in my previous message and
1:13:16you'll see that it's asking how it's
1:13:18doing right so we're actually now
1:13:20accessing the previous message using
1:13:23this buffer memory and on the right hand
1:13:25side you'll see here that the log has
1:13:27gotten a little bit more intense too so
1:13:28basically we called the AI agent up at
1:13:30the top the next thing that happened was
1:13:32we went through the buffer memory we fed
1:13:35this in and basically ally added this to
1:13:37some big long stack of message history.
1:13:40Then we fed that in plus the previous
1:13:42message. Then we said, "Hey, what did I
1:13:45ask you in my previous message?" This is
1:13:46the input that is currently being fed
1:13:48into the model on that second call. And
1:13:51then we went down into buffer memory. We
1:13:53saved all of this again. And then uh we
1:13:55kind of came up and then and sent the
1:13:56answer. How about
1:13:59now? Cool. So now we're three levels
1:14:02deep. And as you can see, this is just a
1:14:03quick and easy way to load the memory.
1:14:05make sure that we're always having some
1:14:06sort of topical contextual conversation,
1:14:08which is pretty cool. Now, the real
1:14:10juice in AI agents, the reason why
1:14:12they've gained so much popularity is
1:14:14just because of this tool section here
1:14:16where you can essentially call an action
1:14:18just like we were doing before
1:14:19procedurally, but you can call it using
1:14:21AI and you can automatically format and
1:14:23get information from different tools.
1:14:25So, there are variety of tools that are
1:14:26sort of set up for you. Air table, base
1:14:29row, calculator, Gmail, Google calendar,
1:14:31Google Docs, Google Drive, all this
1:14:32stuff.
1:14:34What I'm going to do in this example,
1:14:35just because I don't want to spend all
1:14:36day on it, um, before I do my more
1:14:38detailed AI agent tutorials, is I'm just
1:14:40going to select Google Calendar. I'm
1:14:42going to create a new credential, sign
1:14:43in with my Gmail
1:14:46account, and then I'll go over
1:14:48here. I'll close this window. Now that
1:14:52I've uh I've connected my Google
1:14:53calendar agent, what I'm going to do is
1:14:55I'm going to select my specific
1:14:56calendar, which is Nick
1:14:58leftclick.ai. And then now that it's
1:15:00connected to my AI agent, this is the
1:15:02create event. I don't want to create. I
1:15:04just want to get so get all of my events
1:15:06basically from my calendar. Okay. And
1:15:07then in addition to that, what we have
1:15:08to do is we have to use this dollar sign
1:15:10from AI feature here. And we just have
1:15:12to paste that into the expression field.
1:15:14Um what this does is this just tells AI,
1:15:16hey, I want you to provide uh you know
1:15:18your own details for the value of a
1:15:21field. In our case, I wanted to feed in
1:15:23some options that say, hey, you know, I
1:15:25want you to grab data that is after this
1:15:27date but before this date. So, if I'm
1:15:29asking
1:15:30AI like, "Hey, what's going on? Can you
1:15:34tell me what I'm doing tomorrow?" And
1:15:36I'll just say, "Jan 28, 2025." The whole
1:15:38idea here is AI now has access to my
1:15:40calendar. It also has the ability to
1:15:42call that API. Then it can actually go
1:15:44and retrieve specific events from my
1:15:46calendar and then return them here. So,
1:15:48as you can see, I have this call uh me
1:15:50and my my buddy Zach, and then it just
1:15:51has all of this information. Okay,
1:15:53great. How are you more generally? you
1:15:55know, I can also just chat with it like
1:15:57I'm chatting to chat GBT or something
1:15:59like that. So, I don't always have to
1:16:00use like the tool that I'm I'm calling.
1:16:02And the idea is you basically stack on
1:16:04three, four, 5, 10, 15, 20 of these
1:16:06tools. Although, I find in practice when
1:16:08you get um past maybe six or seven,
1:16:10instead of calling a tool, what you want
1:16:11to do is you want to call another agent
1:16:12which then decides to call a tool. It's
1:16:14basically like a big almost like a
1:16:15search tree or something. But anyway,
1:16:17that's more or less the AI side of
1:16:19things. The last thing I'll mention here
1:16:21is uh this OpenAI note doesn't just have
1:16:23the message a model text action like
1:16:25we've been doing before. There's a
1:16:26variety of other things you could do.
1:16:27You can create an assistant, delete an
1:16:29assistant, list assistance, message
1:16:30assistance, update assistance, analyze
1:16:32images, you can generate images,
1:16:34generate audio. Like you have a ton that
1:16:35you could do here, which is pretty
1:16:36sweet. I go down to generate audio and
1:16:39I'll say um I don't know, Nick is
1:16:42awesome and very pretty and I generate
1:16:44it using the Nova voice. Click this test
1:16:47step. Not only can I generate text and
1:16:50stuff like that, but I can also have
1:16:51this generate me an audio output I can
1:16:53then listen to. Variety of cool things
1:16:55you could do with this. Nick is awesome
1:16:57and very pretty. You're damn right I am.
1:17:00Um variety of cool things you can do
1:17:01with this, but definitely don't sleep on
1:17:03the AI nodes. Uh you know, don't just
1:17:05like stick to the one that I've shown
1:17:06you guys so far. Okay, great. So, those
1:17:08are the foundational ones. In practice
1:17:09with NAN, you're probably going to be
1:17:11using these quite often. What I'll do
1:17:12next is talk about some nodes that
1:17:13modify flow. And here a bunch more that
1:17:15like you're going to want to read their
1:17:17docs and add them to your toolkit
1:17:18because this is like an everyday sort of
1:17:19thing. The first is an if. The second is
1:17:22filter. The third is merge. And the
1:17:23fourth is split into batches. So let me
1:17:26show you guys a very quick and simple
1:17:28example of the if. If I go
1:17:30here and then I add my own trigger. Uh
1:17:33and I just want to trigger manually. Oh,
1:17:35sorry. It looks like I already have one
1:17:36somewhere in here. Right. So let's just
1:17:38repurpose this um manual trigger for an
1:17:41example workflow that I'm going to build
1:17:43down below.
1:17:44this example trigger. I'm going to click
1:17:46it. And then what we're going to do is
1:17:48we're going to use the edit
1:17:50fields. We're going to go down to JSON.
1:17:53This is just a handy dandy tool that
1:17:54allows you to set your own inputs and
1:17:56outputs. So I can now set my own um
1:17:58output. And I could say first name Nick,
1:18:02last name uh Sarif. And if I if I test
1:18:05this, if I test my whole workflow,
1:18:06you'll see this broke because um Sarif
1:18:08was not in quotes there. Got to make
1:18:10sure that all of your strings are in
1:18:11quotes. If I check out the JSON, you see
1:18:13the output of this module is now first
1:18:14name, Nick, last name, survive. Okay,
1:18:16I'm just going to pin this. Now, let's
1:18:18say I want to do something else, you
1:18:19know, if
1:18:20the if the input is Nick, I want to do
1:18:24something really cool. I want to provide
1:18:27prize. I don't know, um,
1:18:30$100. If the input is Nick, I want to go
1:18:33through my my sequence and then I want
1:18:34to generate another variable called
1:18:36prize, and I want to I want to have it
1:18:37be $100. Okay. But I only want to do
1:18:40that if the input is Nick. If the output
1:18:42is something else, then I want to have
1:18:46my prize be just $5. So Nick gets all
1:18:50the prizes here. He's very greedy. Okay.
1:18:52So how do you actually implement this
1:18:53sort of logic? Well, the simplest way is
1:18:54if I click this plus button and I just
1:18:56type if, you'll see I'll have this node
1:18:58pop up that says if wrote items to
1:19:00different branches, true or false. So
1:19:01I'm going to add that in there. And what
1:19:03I'm going to say is if first name, which
1:19:05by the way, we could still just drag if
1:19:06we wanted to. You can say if first name
1:19:08is equal to Nick, then proceed through
1:19:11the true node, which is up here. And if
1:19:15not, we're going to want to proceed
1:19:16through this false node. Isn't that
1:19:19cool? So now we basically have two
1:19:21things that are occurring. Okay, prize
1:19:24up here was 100. Prize down here was
1:19:27five. I'm going to click test workflow.
1:19:29This is now going to run. And I just
1:19:31want you guys to see what's happening. I
1:19:32clicked test workflow. We then edited
1:19:35our fields. We added Nick as the first
1:19:37name. We then went to the if and then as
1:19:39we saw here, first name was equal to
1:19:42Nick, meaning oops, if I double click
1:19:44this again, the output is now only going
1:19:47down the true branch with one
1:19:50item. And then the uh upper branch was
1:19:53illuminated. It's green. And then that's
1:19:54how we get to edit fields with the prize
1:19:56equal to $100. Now, if I change this,
1:19:58instead of Nick, if it's like Sally or
1:20:01something, and if we run this again,
1:20:04what you'll see is the
1:20:06data is flowing through here cuz I
1:20:08didn't unpin it. So, let's unpin it. If
1:20:10we if we test this now, uh what you'll
1:20:12see is the data didn't go through the
1:20:13top uh route anymore. Went through the
1:20:15bottom route. Okay, great. So, now with
1:20:16this example here, why don't we just
1:20:18pretend like we're emailing somebody.
1:20:20So, I'll go draft an email.
1:20:23create my thing here and we'll say
1:20:25congrats you won good expression. Then
1:20:29what I want is dollar sign
1:20:31Jason.prise right over here. So like
1:20:34congrats you won $5. How cool is that? C
1:20:38title
1:20:40loser. Uh okay, great. And then I'm
1:20:42going to go here and I'm going to create
1:20:43a
1:20:44draft. Voila. I have it. Now if I go
1:20:46back here to my SOS media queries page,
1:20:49see it says, "Congrats, you won $5."
1:20:51There's nobody to because we didn't set
1:20:52the email to. But pretty neat, huh? We
1:20:55gave the same thing with this $100
1:20:59field. Go over here. You'll see that I
1:21:01just copied like all of the same logic.
1:21:03It says, "Congrats, you won Jason.
1:21:05Prize." It's grayed out right now
1:21:06because there's no data coming in. But
1:21:08you'll see that it'll work if I change
1:21:09the um input back to Nick. Then if I
1:21:12test this, I'll see it'll follow the top
1:21:14route and then also send me an email.
1:21:16Okay, great. So now let's look to use
1:21:17the filter node. Um, what I have here is
1:21:19I have my little first name Nick here.
1:21:22Um, what I'd like to do instead is I'd
1:21:23like to just change this a little bit.
1:21:25So, instead we'll create an array of
1:21:28names. And inside of this, we'll have
1:21:30Sally, John, and then Nick. Okay. And so
1:21:34now, if we test this, we see three
1:21:36entries in an array called names. We
1:21:37have our top level array, which contains
1:21:39an array of objects, and we have our
1:21:41object. And inside of that, we have key
1:21:43whose value equals a list of other
1:21:45objects and array of other objects. I
1:21:46know the terminology can be kind of a
1:21:48lot and unfortunately there are many
1:21:50ways to refer to the same thing. So if
1:21:52something doesn't make sense just bear
1:21:53with me here and we'll in a moment.
1:21:54Okay, great. So let's say what we want
1:21:56to do if this names array includes Nick
1:22:00then um I want to continue with the
1:22:02flow. So I'll go array. Then what I want
1:22:05is I want to see if this array of of
1:22:07names feed that in here contains and I
1:22:11just want to say Nick. I'm going to test
1:22:13this out.
1:22:15What you'll see is that we've kept it
1:22:16because it does in fact contain Nick,
1:22:18which is pretty cool. If instead we
1:22:20wanted to see if it contains Peter, we
1:22:22test this. You'll notice that we are now
1:22:24following the discarded route. Okay,
1:22:26there's kept and then there's discarded.
1:22:28The thing is um it just goes down the
1:22:29same flow. Whereas if sort of split into
1:22:32two, there's a true and a false route.
1:22:33Uh this one actually just like continues
1:22:34and proceeds down the same flow. If
1:22:36something matches the filter, it will
1:22:38continue. Something doesn't match or the
1:22:40fil match the filter, then it won't. So
1:22:42what we could do if I just paste in this
1:22:44Gmail node. So we could basically build
1:22:47uh a very similar flow but what we could
1:22:50do is if it is kept then we could send
1:22:52the prize of $100 instead. We could
1:22:54hardcode that $100 in. So I'm going to
1:22:56do is I'm going to check to see if it's
1:22:57kept. Okay. So right now name contains
1:22:59Peter. It's probably not going to be
1:23:00kept, right? So test workflow. It's
1:23:01going to stop right here. Does not
1:23:03proceed any further. If instead I change
1:23:05the filter so that it contains Nick,
1:23:06then we test it. we see is we're going
1:23:08to move on and we're actually going to
1:23:10like proceed with the rest of our flow.
1:23:12So, this filter here just allows us to
1:23:13kind of stop if it doesn't match our
1:23:15condition or or continue. And you can
1:23:17add as many conditions as you want. You
1:23:18can go and or or um you can add whatever
1:23:20sort of logic you'd like. I used array
1:23:23logic here too, but there's also a lot.
1:23:24There's like string. You can check to
1:23:26see if something exists or matches array
1:23:27X, number, date and time, boolean,
1:23:30array, and then there's also a bunch of
1:23:31object ones as well. So, that's filter.
1:23:34Pretty straightforward, I would say. The
1:23:36last thing is two more. There's one
1:23:38called merge and then there's split into
1:23:40batches. What I'm going to do here is
1:23:42I'm going to have two routes or two
1:23:44outputs of a module and then I'm going
1:23:46to combine them back into one. And I'll
1:23:47show you guys what I mean with this.
1:23:49Remember earlier how we had some HTTP
1:23:51requests. What I'm going to do is I'll
1:23:53go first name
1:23:57Sally and I'm going to
1:24:00have let's just say second name.
1:24:03Actually, let's
1:24:05go person one. Go person two. Just for
1:24:09the purpose of this example, we're going
1:24:10to have two people. Person one, Sally.
1:24:12Person two is Nick. Okay. Next, what
1:24:14we're going to do is we're going to add
1:24:15an AI node. You know, down to open AI,
1:24:18and I'm just going to message a model.
1:24:20Then here, I'm going to say write a
1:24:23detailed fun story about what I'm going
1:24:26to do is I'll go I don't know, person
1:24:29one. So, JSON.person one. This example
1:24:32is sort of silly if I'm honest because
1:24:34we could just hardcode the names in
1:24:36there. But I just wanted to do this to
1:24:37show you guys how this logic of the
1:24:39merge node would work. I'm going to
1:24:41select
1:24:43GPT40. And then I'm, you know, because
1:24:45this is just a very quick and easy
1:24:46example. I'm actually going to add a
1:24:47user
1:24:49prompt. Okay. It's now going to go and
1:24:51it's going to write me a fun story about
1:24:52Jason. One. Person one was Sally. So,
1:24:55we're going to see it in a
1:24:57second. Very fun. Thank you very much
1:24:59for the detailed story.
1:25:03Q Jeopardy
1:25:05music. Q other elevator
1:25:08music. All right, it's taking its sweet
1:25:10ass time. Could be for a variety of
1:25:11reasons. I might have like a little bit
1:25:12of rate limit action going on on my end
1:25:14just because of all the examples that I
1:25:15provided, but could also be something
1:25:17else. I don't
1:25:19know. Let's see
1:25:22here. Okay, cool. Looks like it did.
1:25:24Once upon a time in the vibrant city of
1:25:26Elmssworth, where the streets hummed
1:25:28with the rhythm of hopeful dreams and
1:25:29endless possibilities. Okay, so we just
1:25:31uh you know we just wrote a cool story
1:25:33about Sally. What what you can do in N8
1:25:35is you can actually connect the same
1:25:37output to multiple um multiple future
1:25:40nodes. So what I've done is I've you
1:25:42know I have one over here which I'm
1:25:43going to rename write story about uh
1:25:47Sally. Then I have another one over here
1:25:49which I'm going to say write story about
1:25:52Nick.
1:25:54Then down over here, I'm going to say
1:25:56write a story about person two instead
1:25:59of person one, which is, you know, now
1:26:00going to equate to neck, right? If I
1:26:02test the step, same thing's going to
1:26:03happen. It's going to call GPT40. It's
1:26:06going to write me a cool
1:26:07story. The issue is if you think about
1:26:09it logically, we now have two routes. We
1:26:12have one top route that writes a story
1:26:13about Sally, another bottom route that
1:26:14writes a story about Neck. Um, so if we
1:26:16wanted to do something with these
1:26:18stories, like I'd kind of have to repeat
1:26:19the same logic up here. Let's say I
1:26:20wanted to email this to somebody. Well,
1:26:22I'd have to Gmail up here. and I'll set
1:26:23to Gmail down here, right? I have to
1:26:25duplicate it. And it then provides a
1:26:27pretty simple and easy built-in way to
1:26:28avoid that. It's called the merge node.
1:26:30So, you can merge data of multiple
1:26:31streams once data from both is
1:26:33available. So, if you just click on it,
1:26:35you'll see that there's a mode append or
1:26:37combine or SQL query. I'm just going to
1:26:40stick with append for now. I'm just
1:26:42going to feed in these
1:26:45inputs. And in this way, what I can do
1:26:47is I could actually just write, you
1:26:49know, one Gmail node here instead of
1:26:51two. Um, and maybe I could like append
1:26:52both of these stories or something. But
1:26:55let me actually show you um what this
1:26:57looks like. Now, I'm actually going to
1:26:58test this workflow from end to end. So,
1:27:00you see it first does the top route and
1:27:02you can see this is orange because it's
1:27:03like filling out the um story about
1:27:06Sally right now. This is currently
1:27:07active. It's waiting to fill in the
1:27:09merge the second this is finished. And I
1:27:11think I probably should have set some
1:27:12character limit to the story cuz now I'm
1:27:13thinking about it's probably writing a
1:27:15lot. RIP my
1:27:17tokens. And then after it's done with
1:27:20the story about Sally, it's gonna go and
1:27:23just gonna do the same thing. Write a
1:27:24story about Nick. Um, hopefully this
1:27:26finishes before the next ice age. Okay,
1:27:27that took way too long, but uh, just
1:27:29make sure you put in some sort of limits
1:27:31next time you do one of these calls.
1:27:32Otherwise, you'll be waiting here until
1:27:33the end of time. However, what we see as
1:27:36our final product is the top route
1:27:38completed and then populated the merge
1:27:40and the bottom route also completed and
1:27:41populated the merge. Now we had one item
1:27:44from a top route, one item from the
1:27:45bottom route. Then we also carried
1:27:47forward one end from the top route, one
1:27:48item from the bottom route. But what
1:27:50you'll see is the output of this merge
1:27:51is now two items instead of one. The
1:27:53reason why it's two items is because we
1:27:55use the the append. So now we have uh
1:27:58you know the story number one and we
1:27:59have the story number two. Basically we
1:28:02don't actually have to just output two
1:28:03things. We could actually just output
1:28:04like one item instead. Um but because in
1:28:06N8 um outputs are arrays of items, you
1:28:10kind of have a choice there. Now, since
1:28:11we output two items, what we could do is
1:28:13we could add our little Gmail node.
1:28:15Stick that down here. Connect
1:28:18it. Then I'm just going to pin this. And
1:28:22what I could do is I could email myself
1:28:24this
1:28:26story. I could say story about just cuz
1:28:28I back myself into a corner here. I need
1:28:30to write kind of like a little bit more
1:28:31difficult of a line of code. But I don't
1:28:34have access
1:28:35to Nick here, right? Like I don't have
1:28:37access to a single variable that
1:28:38contains the value that I'm looking for.
1:28:40This is person one, Sally. Person two,
1:28:42Nick. So, I mean, I could select person
1:28:44one, but then my second run would also
1:28:48say Nick, right? So, both of these would
1:28:49say story about Sally, story about
1:28:51Sally, even though they'd have different
1:28:52stories. So, what I'm going to do is I'm
1:28:53going to say I'll look at the actual
1:28:56story. So, I'll go
1:29:00uh sorry, I'm going to go to the merge.
1:29:01I'll look at the actual story here,
1:29:05which now that I think about it is
1:29:06actually just JSON. Then I'll go
1:29:08message. I'll go content. Then if it
1:29:10includes the term
1:29:13Nick, then I'm just going to return
1:29:15Nick. Otherwise, I'm going to return
1:29:17Sally. That's how that works. So if this
1:29:20contains Nick, I'll return Nick. If not,
1:29:22I'll return the ter I'll ret I'll return
1:29:24the term Sally. This is just a kind of a
1:29:26shorthand way to use the if um else
1:29:29logic. Same as what we had before. So,
1:29:31I'm just going to pop this puppy
1:29:34open. Um, and let me take a look at the
1:29:37data. Story about Nick. Nick was an
1:29:39ordinary guy with an extraordinary
1:29:41dream. I wanted to become the first
1:29:42person to ride a unicycle all the way
1:29:44across the United States. Then Sally,
1:29:46uh, Once Upon a Time, the quaint town of
1:29:48Lavender Hill, I think. Uh, this was the
1:29:50one where I timed out or something
1:29:52because of the rate limit,
1:29:53unfortunately. So, it doesn't look like
1:29:54it generated me anything more than Once
1:29:56Upon a Time, the quaint town of Lavender
1:29:57Hill. But, I'm sure we could. Yeah, like
1:30:00I could rerun this. Let me just make
1:30:01sure that the prompt is a little bit
1:30:04shorter. Less than 100 words. Let's just
1:30:07do
1:30:09that. And then good. Uh, awesome. We
1:30:12should be good now to actually produce
1:30:14this puppy. Let me just go over here and
1:30:17delete
1:30:18these examples that I don't need in
1:30:21preparation for the next run. And cool.
1:30:24We we warmed up two
1:30:26Gmails. Now we have a story about Sally,
1:30:28who's a curious hamster. And then I am a
1:30:30curious inventor. Lovely. Wonder why uh
1:30:33they use the term curious both times.
1:30:36But anyway, I hope you guys see now that
1:30:37like basically the merge connects two
1:30:38things together. The if statement sort
1:30:40of does the opposite. It kind of creates
1:30:41two routes,
1:30:43right? Yeah. This is kind of neat when
1:30:45you contrast and compare them like that.
1:30:48So I believe now uh we have everything
1:30:50we need except for the split into
1:30:52batches run. Split into batches is kind
1:30:54of a a little trickier of a thing to
1:30:56conceptualize. So I'm going to show you
1:30:57a real example from a source that I used
1:30:59to extract a bunch of data. So let me
1:31:02take a quick peek here at
1:31:04um I think I was doing depersonalization
1:31:07system. Yeah. So I created a video on a
1:31:09depersonalization system a while ago and
1:31:11as part of it um what I'm doing is I'm
1:31:14waiting over here for data to come in
1:31:15through a web hook. I send in data to
1:31:18this web hook and then I use it to call
1:31:20an API that gets a bunch of data set
1:31:23items. The data set items are pretty
1:31:25big, right? As you can see over here,
1:31:26it's a bunch of data about specific
1:31:27leads. But notice how it says 128 items
1:31:30above, right? Anytime you output more
1:31:32than one item in N8N, what you can do is
1:31:35you could loop over every item. Then you
1:31:37could perform something individually on
1:31:39just that item. And then once you're
1:31:42done with that, you could go back to the
1:31:44loop over and over and over and over
1:31:45again until you're completed. So in my
1:31:47case, I had a lot of items in this. I
1:31:51had 128 for Christ's sake, right? And
1:31:53what I wanted to do is I wanted to run
1:31:55my five column personalization flow
1:31:56similar to what we saw earlier. And then
1:31:57I also wanted to add a row to my
1:31:59spreadsheet. Now unfortunately every
1:32:01time I did that I consumed one API uh
1:32:04call and a lot of these platforms have
1:32:06pretty intense rate limits. So instead
1:32:09of me um one issue I always found I
1:32:11found very frequently was I just kept on
1:32:13getting timed out. It would say 400
1:32:14error or 403 error or whatever.
1:32:17Basically, the gist of that is that, you
1:32:19know, I'm over the rate limit and
1:32:21they're not going to allow me to make
1:32:21any more requests for a certain amount
1:32:22of time. So, what I did instead is
1:32:24instead of me just submitting all of
1:32:26those requests simultaneously, I added
1:32:28this to a loop over items and then I
1:32:29added a designated weight node. The
1:32:32weight node is a simple node in N that
1:32:34allows you to wait for a certain number
1:32:35of seconds. In my case, five. And in
1:32:37this way, I was able to basically take
1:32:39one item, go from start to finish, wait
1:32:425 seconds, and then loop back and then
1:32:44proceed with my next item. And I
1:32:46basically just went, you know, one after
1:32:48the other after the other after the
1:32:50other over and over and over and over
1:32:52again. So that's just to give you guys
1:32:54some context on on what that actually
1:32:55might look like. If I go down
1:32:57here and I set um my items here, I'm
1:33:01just going to use a future a feature in
1:33:02NAN that allows you to automatically set
1:33:04like your own test data. So I'm going to
1:33:06say, you know, there's there's first
1:33:08item and then there's second
1:33:10item and my data for that. Where is the
1:33:13edit fields? Right over here.
1:33:16If I zoom way in, you'll see that I'm
1:33:19now outputting two items, right? So,
1:33:21what I can do is I can go loop over
1:33:22items, split in batches. You set the
1:33:25batch size to one. What it'll do now is
1:33:28it will go first item and then second
1:33:30item. What I'll do is when you add a
1:33:33loop over items, it immediately adds a
1:33:34replace me node. And this is what you're
1:33:36supposed to basically replace with the
1:33:37thing you want to do. So, in my case, I
1:33:38just want to wait 5 seconds. So, I'm
1:33:40just going to go over here and go wait.
1:33:43wait exactly 5 seconds. What I want to
1:33:46do is for the loop route, for the route
1:33:48that is going to be looping over my
1:33:49items. So basically for every item, you
1:33:52can think of this as I want to wait and
1:33:55I want to wait 5 seconds. Very cool.
1:33:59Then the output of this needs to feed
1:34:00back into the input. This is kind of
1:34:02like the tricky
1:34:04part. So when you go through a loop, I'm
1:34:06going to click a test workflow. I'm
1:34:07going to generate two items and then I'm
1:34:09just going to pull one item out of that
1:34:10and I'm going to wait 5 seconds. I'm
1:34:12going to go to the second item and I'm
1:34:13going to wait 5 seconds. Is this going
1:34:15to do anything? No. But notice that
1:34:17there is both a loop route and then
1:34:18there's a done route. Basically in NAND
1:34:20once you're done with the loop route, it
1:34:22just automatically goes to the done
1:34:23route. So I could do something like this
1:34:24and maybe I send myself an email. Let's
1:34:26just
1:34:28draft. And then let's say um you
1:34:32know done
1:34:35looping. You successfully waited 10
1:34:38seconds.
1:34:41Awesome. So, we're going to wait 5
1:34:44seconds and then 5 seconds. Then we're
1:34:45going to Gmail. Okay. So, that's that.
1:34:48I'm going to test this workflow. That's
1:34:50the first 5 seconds
1:34:53here. And that's the second 5 seconds
1:34:57here. And once this is done, we can now
1:35:00send over an email draft or queue up an
1:35:02email draft, I should say, which is
1:35:04right over here. I should note that I
1:35:06may have ran this twice. I feel like I
1:35:08just ran this twice. Looks like it's
1:35:10carrying all of these here. Oh, yeah.
1:35:12Sorry. It'll it'll output all of the
1:35:14records that you feed it in basically.
1:35:16So, I fed it in two records and then the
1:35:18third run it went and then fed both of
1:35:19those records in as input to my Gmail
1:35:21branch. Um, what I could do is I could
1:35:23take these two items and I could convert
1:35:24into just one item by combining them.
1:35:26Um, and then I wouldn't have to deal
1:35:27with this, which is kind of neat. So,
1:35:29that's probably what I would do in
1:35:30practice. I wouldn't actually proceed
1:35:32here with two items. I would just do
1:35:34one. There's a really cool built-in way
1:35:36to do this in NAN just called execute
1:35:38once. So if you just go to the settings
1:35:40page of any node and then just click
1:35:42execute once, you basically stop the
1:35:44multiple executions regardless of the
1:35:46number of elements that precede it. So I
1:35:48just clicked execute once and instead of
1:35:50me sending two emails, now it's only
1:35:51going to send one. That's run number
1:35:54one. That's run number two. Then it'll
1:35:57go and it'll feed one item as an output.
1:36:01So if I refresh this now, instead of
1:36:03two, I'm only going to have one. Quick
1:36:05and easy hack. Um, and yeah, you know,
1:36:07because we're building stuff live,
1:36:08hopefully you guys get to see the
1:36:09applications of this in real time as we
1:36:11put something together. All right, so
1:36:13now I think we are at the point where we
1:36:14can realistically build out
1:36:15substantially more complicated flows.
1:36:17What I'm going to do now is basically
1:36:18run almost like a test of sorts where
1:36:21we're going to take all the information
1:36:22that I just tried to shove into your
1:36:24brain and we're going to use it to build
1:36:25out a flow that actually does something
1:36:27business worthwhile, a flow that I've
1:36:28sold many times before and a flow that's
1:36:30made people a fair amount of money. So
1:36:32this is what the flow looks like right
1:36:34now. I'm actually going to simplify it.
1:36:35I've decided to do it a little bit
1:36:36simpler just over the course of the last
1:36:38like 20 minutes thinking about it. But
1:36:39basically, just to keep things make a
1:36:41long story short, there's this service
1:36:42out there called SOS. Um, and I
1:36:44mentioned this at the beginning of the
1:36:45video, they send out like a a query
1:36:47every day from journalists uh where the
1:36:49journalists are looking for people that
1:36:51match their criteria to answer
1:36:53questions. So, uh, for instance, you
1:36:56know, this one up here is from Jordan
1:36:57Rosenfeld who's saying, "Seeking
1:36:59healthcare Medicare specialist weigh on
1:37:00how RFK Junior and Dr. Medat Oz might
1:37:02affect benefits or healthcare if
1:37:04appointed. know that this is usually
1:37:05like US specific. I think they have kind
1:37:07of like a like a global arm sometimes
1:37:09too, but most of this is going to be USD
1:37:11uh US specific. And then it says, "Hey,
1:37:14um I'm looking to speak to people in a
1:37:16nonpartisan way, but the possible
1:37:17changes, things like Medicare,
1:37:18healthcare, insurance, these are two
1:37:20stories. Specify what you're commenting
1:37:21on can be both robust and longer answers
1:37:23are prioritized. You must have the
1:37:24relevant experience. We'll link back to
1:37:25your site. Please include pronouns."
1:37:27There's a lot going on here, right?
1:37:28Basically what we want to do is we just
1:37:29want to take this whole long email and
1:37:33we just want to extract all of these. So
1:37:37this would be
1:37:39one, this would be one, this would be
1:37:44two, this would be three, and so on and
1:37:47so forth. And we want to feed this into
1:37:49AI. And we just want AI to give us a
1:37:50very simple answer. Hey, is this
1:37:52relevant to me based off of some
1:37:53characteristics I'm going to give you?
1:37:55and two, if it is, can you like
1:37:57pre-draft an email for me? So, pretty
1:37:59pretty simple, pretty straightforward
1:38:00stuff, right? Let me show you how
1:38:02straightforward this flow can be given
1:38:04what you now know. And I want you to
1:38:05treat this as like a test, basically.
1:38:07Like, you've made it this far. Let's
1:38:09actually see if you could build
1:38:10something out that's business
1:38:11worthwhile. If something that I'm saying
1:38:13doesn't make sense, uh, pause the video
1:38:14and look for the specific part that I've
1:38:16covered the concept in, cuz that's
1:38:18that's basically the purpose here. I
1:38:19just want you guys to be able to
1:38:20reaffirm your knowledge and show you how
1:38:21now you can do something pretty cool.
1:38:23Okay. is the first thing I'm going to do
1:38:24is I'm just looking for a Gmail trigger
1:38:25there. I'm going to select my
1:38:27credential. Sorry, not create a new
1:38:29credential. I'm going to select my
1:38:31credential, Gmail account 3. And the way
1:38:33that this module or node works is it
1:38:35extracts emails from my inbox that match
1:38:37my specified filters. And it does so in
1:38:39the timing that I give it. So every
1:38:41minute, hour, day, week, month, x,
1:38:42custom, whatever. I'm just going to say
1:38:44once a day for now. It's going to be
1:38:46zeroth hour, zeroth minute, simple
1:38:48stuff. The event I'm looking for is
1:38:50message received. Then what I need to do
1:38:52is I I need to add a filter down here.
1:38:54And there's one called search where I
1:38:55basically just look for emails from SOS.
1:38:59Luckily for me, they're all formatted in
1:39:00very similar ways. SOS media queries. So
1:39:02if I want to get all the emails from
1:39:03SOS, this is just what I do. Now I don't
1:39:05just want to get any email. I just want
1:39:06to get the specific email just to show
1:39:08you guys what I'm working with. Later
1:39:10on, we'll then um we'll separate it. So
1:39:11it's just SOS media queries. It'll work
1:39:13with any of them. But for now, I just
1:39:14want to grab this one. Here's what you
1:39:16do. You just go
1:39:18subject and then you'd feed this in.
1:39:21This is a Gmail operator, so just use
1:39:23whatever same filtering mechanism you do
1:39:24for your own emails in Gmail. Uh, and
1:39:26just feed it in over here and it'll work
1:39:28fine. Okay, now let's test this out.
1:39:30Let's grab the data. We've received a
1:39:33ton of data. Uh, this is an object with
1:39:3511 items inside, but this simplify is
1:39:39sort of working against us here. The
1:39:41Gmail trigger just natively always has
1:39:43simplify on. We actually want to get rid
1:39:45of this. So, I'm going to go to
1:39:45expression just like we know how and
1:39:47press and and type in false. This is the
1:39:49same by the way as just turning this
1:39:50off. I just wanted to be clear that I
1:39:52always use the expression field. And now
1:39:54I'm going to get the actual data of the
1:39:56email which is way more as you can see
1:39:58here. Instead of whatever it was 12 or
1:40:00something, now it's or six, now it's 13.
1:40:02And uh the headers object has 27 items
1:40:06buried in it just in and of itself. The
1:40:08thing we're looking for is this text
1:40:09variable, which is the same as what we
1:40:11had before. Tell friends to join source
1:40:12of sources. It's always free. want to
1:40:14know how to strengthen your relationship
1:40:15with journalists blah blah blah. We're
1:40:17then going to pin this. So now we have
1:40:19access to all of this JSON in future
1:40:21nodes. And I think I got lost here with
1:40:24my Gmail
1:40:25trigger. And now uh let's actually go
1:40:28ahead and let's let's split this data.
1:40:29Let's basically get our data so that
1:40:31it's just a bunch of these. How are we
1:40:33going to do this? Just think about this.
1:40:34We got a bunch of text processing
1:40:36features available to us. We know a
1:40:37little bit about the JSON JavaScript and
1:40:40stuff like that, but what are some ways
1:40:41we might actually realistically be able
1:40:43to do this?
1:40:44Well, the way that I see it is the great
1:40:46news about source of sources and the
1:40:48previous uh service called Haro is that
1:40:50they just have the same like characters
1:40:52everywhere. So, they have a bunch of
1:40:54stars here. Then between every story is
1:40:56basically just like these underscores.
1:40:59So, underscores there, underscores
1:41:02there, underscores there. So when you
1:41:05see a similar pattern like this, it
1:41:09becomes very easy for you to like
1:41:10process this in a noode tool using a
1:41:12term or a function called split where
1:41:14you basically just feed in a whole big
1:41:16string and then you just split it based
1:41:17off something that you want. So I'm
1:41:19probably I'm going to probably need to
1:41:21split this twice. The first thing I'm
1:41:22going to do is I'm going to split based
1:41:22off this up here and then is you know
1:41:26there's like this top section and then
1:41:27there's going to be this whole bottom
1:41:28section. Then after that I'll grab the
1:41:30bottom section. I'll split it based off
1:41:32of uh this probably. then I'll just be
1:41:34able to get like the individual
1:41:35sections. If that sounds like rocket
1:41:36science to you right now, don't worry.
1:41:38We're going to go over here, press edit
1:41:40fields. And what I'm going to want to do
1:41:43is for now I'm just going to go manual
1:41:44mapping. Click add field. This allows me
1:41:46to create my own variable basically
1:41:48based off of um you know the the
1:41:50previous module. So I'm going to type
1:41:52above. Uh
1:41:55actually yeah, let's let's just call
1:41:57this
1:41:59below. And then what I'm going to do is
1:42:02I'm going to feed in where is this text.
1:42:05Ah, it's right over here. We'll go to
1:42:06the expression field. Then I'm just
1:42:08going to type dollar sign JSON dot. And
1:42:11what I want is I want text. Okay. So now
1:42:14if we open up this big fat editor here,
1:42:15we got all the text right here. Pretty
1:42:17sweet, right? We don't want all the
1:42:18text. We only want the stuff that is uh
1:42:21below this line. So I'm going to copy
1:42:23this. And then I'm just going to go over
1:42:25here and press dot. Now we have a bunch
1:42:26of functions. And I haven't covered all
1:42:28these functions yet. I will in the
1:42:29future videos. Um, but one of the
1:42:31functions that I use all the time is
1:42:33called split. Just press split. And all
1:42:35we need to do now is we just need to
1:42:36feed in the thing that we want to split
1:42:37it by. So I'm going to feed in what I
1:42:39just copied a moment ago. Okay. And now
1:42:42instead of just seeing the string, we
1:42:45actually see an array. And this is what
1:42:46arrays look like when they're output in
1:42:48um naden. It says bracket array and then
1:42:51colon space. And then we actually have
1:42:53the whole array here. And this array is
1:42:55split based off of wherever this was. So
1:42:59I think it's going to be split right
1:43:01over here. The last character before it
1:43:02will say information week. Okay. So we
1:43:05go information week. I'm going zoom way
1:43:08in. And yeah, that's what the array
1:43:11looks like. We have a comma. So this
1:43:12whole thing was a string. Then we have
1:43:14um quotes and then a comma, a space, and
1:43:16then we have another quote. And this is
1:43:17the beginning of everything underneath
1:43:18it, which is awesome for us. Okay, so
1:43:21this is basically what we get. Um, and
1:43:23now the really cool thing that allows us
1:43:25to do is it allows you to pull objects
1:43:27out of an array. So this is an array
1:43:29with two items inside of it. The one
1:43:32string that's everything above those
1:43:33lines, this little star line, then
1:43:35another string that's everything below
1:43:36the star line. We can just go dotlast.
1:43:39And now we'll just pull out the actual
1:43:41string itself, which is this. All of
1:43:44this. How cool. Now what else we could
1:43:48do is theoretically we could just split
1:43:49this again. We could split this again
1:43:51and then extract everything split based
1:43:55off of these characters. So I go
1:43:57dotsplit feed this in. Now we have
1:44:00another array, right? How many items are
1:44:02in here? I don't know. Let's find out.
1:44:04So I'm going to test the step. You click
1:44:06on test step. And now we have a bunch of
1:44:07different items. So yeah, just make sure
1:44:09you like set the array um here anytime
1:44:12you're screwing around with data.
1:44:14Otherwise, I believe they have a field
1:44:15like autotype convert or something. Um I
1:44:17haven't used that one before. type
1:44:18conversion errors or something. I
1:44:20actually just set the specific uh data
1:44:22type that I want. In this case, I'm
1:44:24creating an array. I'm splitting stuff
1:44:25to turn it into array. So, uh I'm going
1:44:28to be doing so with this array drop
1:44:30down. Okay. But anyway, now we have a
1:44:31big array. Pretty cool,
1:44:33right? And it looks like we have 19
1:44:36items in total. What I want to do with
1:44:38this is first of all, I'm going to pin
1:44:40this. Second of all, I'm going to go
1:44:42over here to extract titles. And I'm
1:44:43just going to copy this because I don't
1:44:44want to have to rewrite the whole
1:44:45prompt. I think that would probably take
1:44:47like 15ish minutes or so once when all
1:44:49is said and done. Um, what I want to do
1:44:51is I want to um grab this data which
1:44:54looks just like this. And all I want to
1:44:56do is I just want to feed this into AI
1:44:58now. And I just want to have AI tell me,
1:45:00hey, am I good? You know, if I'm good,
1:45:02then go ahead and like draft an email.
1:45:04If I'm not good, then um then don't. And
1:45:07I know just from experience that this is
1:45:08sort of split into two parts
1:45:11here. So, I'm just going to copy this
1:45:15over. I'm going to use it to create my
1:45:17prompt. Okay. What does this prompt look
1:45:20like? You're a helpful intelligent
1:45:21administrative assistant. Very on brand
1:45:22for me. That's a system prompt. Then,
1:45:24hey, I'm a business owner specializing
1:45:26in AI, automation, marketing, and
1:45:27software. Then what I'm going to say is
1:45:29below is an email requesting a
1:45:35uh below is an email requesting let's do
1:45:38an email request from a
1:45:41journalist looking for a
1:45:45story about sorry information about
1:45:49their
1:45:50story. Then just going to paste a bunch
1:45:52of data in
1:45:58Your task is to determine whether it is
1:46:01relevant to me and if so pre-draft an
1:46:04email that answers their questions using
1:46:07my tone of voice and I'll say casual
1:46:09Spartan. Some
1:46:12information about me. I own one second
1:46:14copy. Here are my
1:46:18links. Then I will say
1:46:23uh sorry I just got a lot going on here
1:46:25because I'm piecing this together
1:46:27between two different
1:46:28um prompts. But anyway, some information
1:46:31about me. I own one second copy a
1:46:33successful AI marketing company that
1:46:34doesn't came up. My name is Nick Raf
1:46:35here. My links don't use unless asked
1:46:37links. And then um below is a request by
1:46:42a journalist for outreach. Write a
1:46:43sinking spartan email responding to each
1:46:45query.
1:46:46says Spartan email be concise. Use the
1:46:50following
1:46:53format.
1:46:55Okay. Then I will
1:47:00say if it is relevant return a JSON
1:47:04object as
1:47:07follows.
1:47:09True. Email body. Email body goes here.
1:47:17If it is not
1:47:22relevant, return false for relevance and
1:47:25leave email body
1:47:29blank. Some information about me.
1:47:34Good. Use the following email format.
1:47:37Email template when responding to
1:47:39relevant inquiries. Cool.
1:47:45Make sure to respond in
1:47:48JSON. Very sweet. Okay, great. And now
1:47:51all I'm going to do is I'm going to
1:47:54provide as input
1:47:59um the specific item that I am
1:48:02referencing. So what you'll find is when
1:48:05you're referencing a an array like this,
1:48:07what it'll do is it'll grab the specific
1:48:09item of the array. So JSON.blow zero. I
1:48:12don't actually want that. Um what I want
1:48:13to do is I I basically want to loop
1:48:15through this array and then for every
1:48:16item I want to feed this in as input. Um
1:48:19this is selecting the first item here
1:48:20with the zero. Um everything is zeroth
1:48:22indexed. So this is 0 1 2 3 4 and so on
1:48:25and so forth. Um so in order to do that
1:48:27we're going to have to take our data and
1:48:28do just a little bit of pre-processing
1:48:35first. Um we're going to want to combine
1:48:38a field from many items. Sorry. uh turn
1:48:41a list inside items. So you're using the
1:48:43split out node. Don't believe I talked
1:48:45about split out, but rest assured all
1:48:48this does is it turns an array into a
1:48:49bunch of items. So you can run them one
1:48:51by one. Okay, great. So below no other
1:48:53fields, and now we have uh 20 items on
1:48:55the right hand side. And now basically
1:48:57we can feed in every one of those 20
1:48:58items to
1:49:00AI. So all I'm going to do now is I'm
1:49:03just going to feed in uh this below
1:49:05field. And now instead of me having to
1:49:07go JSON items.below below zero, below
1:49:10one, below two because we are now
1:49:12splitting this into a top level array
1:49:14instead of before how it was an array
1:49:17and then the curly bracket below and
1:49:19then another um array with like 20
1:49:22records. Now it's just below below below
1:49:23below below. It's going to run basically
1:49:25once for every item that we've received.
1:49:28So yeah, that's that. Um we should be
1:49:30able to get some JSON here. Uh I don't
1:49:32want to run it on all 20 as a test
1:49:34though because all we're doing is
1:49:35testing. So, what I'm actually going to
1:49:36do is I'm going to go in between these
1:49:37and type in limit. Limit allows us to
1:49:40restrict the number of items. So, I
1:49:42actually only want to run this twice to
1:49:43start, and I want to see what happens.
1:49:45So, I'm actually going to do this on two
1:49:47items. Then, we're going to see what
1:49:49those two item outputs are. And if
1:49:50they're good, then we'll continue. We'll
1:49:51pin them and then move on. And if not,
1:49:53then we won't. We'll be able to modify
1:49:54them before we actually waste 20 uh
1:49:57tokens worth of data. And I'm just going
1:49:59to pin all the data moving forward. And
1:50:01then I'm going to go over here to limit.
1:50:02And then I'm just going to press test
1:50:03step.
1:50:05Okay, I'm going to pin this now. So now
1:50:07we have the two items. So I'm going to
1:50:08go over here and then I'm going to test
1:50:09this
1:50:11step. Looks like we are now producing.
1:50:14And it looks like both of these were
1:50:15false. So I'm going to want to up this
1:50:17limit just a little bit. Maybe we'll try
1:50:20three last items instead. We'll
1:50:22overwrite the data that's pinned. We'll
1:50:24pin it again. I'll go back to extract
1:50:26titles. And now we're feeding in the
1:50:27last three enterprise genai users. Yeah,
1:50:29this is probably me.
1:50:34edge AI and stuff. Looks like they kept
1:50:35their AI entries at the end, so that
1:50:37makes
1:50:40sense. And we're now doing three API
1:50:44calls. It looks like uh there were two
1:50:47TRS. So, true up here, true up here.
1:50:49This looks like it was just junk data.
1:50:50So, we could actually cut that out. Show
1:50:52you how to do that later. Um, but now we
1:50:54actually have like emails drafted. Hey
1:50:55Pam, I own one second copy accessible
1:50:57blah blah blah. Here's a big answer to
1:50:59all of these questions. That's pretty
1:51:01cool. All we need to do now is we just
1:51:03go Gmail. We draft. Oh, you know
1:51:06what? Uh, we need to grab the email,
1:51:08don't we? Yeah, I don't think I actually
1:51:11grabbed the email address of the
1:51:13person. Yes, I did not. So, let's
1:51:15actually change our prompt a little bit
1:51:16and let's edit it so that we actually
1:51:18output the email,
1:51:19too. So, I'm going to go back here. I'm
1:51:22actually go
1:51:28um email address
1:51:33um discovered or let's just go their
1:51:40email. Okay, there you go. That should
1:51:44probably be
1:51:47sufficient. Let's actually test this one
1:51:49more time. So now we should actually
1:51:50extract their email address as well,
1:51:51assuming the AI does what I what it's
1:51:54silly human overlord tells it to
1:51:58do. And now that we have the the email
1:52:01um address, we'll actually be able to
1:52:02like use that to feed into a draft.
1:52:04Yeah, I kind of forgot about that. So
1:52:05we'll go back to Gmail. I'm going to go
1:52:08draft create a draft credential Gmail
1:52:11account 3 resource draft operation
1:52:14create. Then I'll say
1:52:16re and then I'll say SOS inquiry. I'm go
1:52:21message and then all I'm going to do is
1:52:23I'll go back to my schema. Just going to
1:52:25drag my email body in here. Then I'm
1:52:27going to add an option called uh now
1:52:31we'll go to email and then we're
1:52:32actually just going to feed that puppy
1:52:34in there. And now we can actually test
1:52:36this out on three. So let's go one, two,
1:52:39three. So you should have three items.
1:52:41All of them just wrapped up. We go back
1:52:43to my email inbox, go down to
1:52:46drafts, we'll see that uh I created one
1:52:49for each. It looks like I created an
1:52:51additional one, but anyway, I'll cover
1:52:52that in a second. The first was this one
1:52:54to this lovely Pam lady. Very nice.
1:52:57Second was this other one to this lovely
1:52:59John
1:53:01fella. Very cool. Uh, everybody followed
1:53:04my email template. No issues. And then,
1:53:06yeah, looks like we just used one
1:53:07additional um
1:53:09email. I think the reason why we sent
1:53:11that additional email is because we
1:53:12technically outputed an item. So, I
1:53:15wonder if we could just not output an
1:53:16item. That would be one way to do
1:53:18[Music]
1:53:20it. Yeah, we could just not output the
1:53:22item. Or, you know, we could just add a
1:53:25filter like I uh was showing us how to
1:53:27do so
1:53:29before. So, if uh let's just go down
1:53:33here. Let's go JSON dot
1:53:40Let's go item
1:53:43three. We'll go down to
1:53:45[Music]
1:53:47JSON.relevance
1:53:51message.content.relevance. So basically
1:53:53if this is equal to true then we'll
1:53:54continue and then if not we won't. So we
1:53:57should get two, right? Yeah, there you
1:53:59go. We uh kept two items and now we're
1:54:01only going to be sending emails on the
1:54:02two items that passed our filter. So,
1:54:05just because I always like to do an end
1:54:07toend flow, I'm just going to discard
1:54:09some old drafts here, delete everything,
1:54:10and then run this one final
1:54:13time just to show you guys what all this
1:54:15looks like. We will use the Gmail
1:54:17trigger, edit the fields, split them
1:54:19out. I'm going to have the limit be
1:54:20three items just for now because I don't
1:54:22want to like draft a bunch of emails.
1:54:24Extract the titles, add a filter, and
1:54:25then create three drafts. Let's run this
1:54:27from start to finish. We're now
1:54:29extracting the titles. And by sorry
1:54:31extracting the titles I mean we are um
1:54:34filtering and creating an email. And
1:54:36then the end result is we have two
1:54:37drafts in our inbox which is kind of
1:54:39neat. And if we wanted to take this even
1:54:41further what we could do is we go down
1:54:42to Gmail and then we could add a label
1:54:44to this message. Just to make it
1:54:46abundantly clear if I select the message
1:54:49ID that we just created. It's going to
1:54:51be right over
1:54:52here. Uh I could just call this public
1:54:56relations or something. And
1:54:59now basically it'll just automatically
1:55:01apply a label to these drafts inside of
1:55:02my inbox that I just know that these
1:55:04are, you know, these are public
1:55:05relations inquiries basically. Um these
1:55:08are not, you know, other email drafts
1:55:10for some purpose. And that's kind of
1:55:12cool of a flow, but I'm actually just
1:55:14going to stick that right over there.
1:55:15And then because I'm already getting
1:55:17mixed up with the extract titles, I'm
1:55:18just going to say filter and respond to
1:55:21email or maybe create email body. There
1:55:25you go. A little bit simpler. So yeah,
1:55:27we used a ton of new functions here. Um,
1:55:30we use the split. I then use the split
1:55:32out. Uh, I don't actually use all of
1:55:34these super often. We did use the
1:55:36filter, which I talked about and
1:55:37covered. And then the limit is just
1:55:39basically like an internal tool that I
1:55:40like to use to uh make sure that I'm not
1:55:42screwing around with token usage or
1:55:44spending a ton of like executions or
1:55:46anything like that. Um, I think this
1:55:48system is a lot cleaner than that other
1:55:49system that I was going to build with
1:55:50you guys before. It's also a little bit
1:55:52more simple. Here I have just a ton of
1:55:53code unfortunately, but we'll get rid of
1:55:55that. We'll use this as the two
1:55:59templates for us. Then I'll also just
1:56:03make this nice and easy to see. And
1:56:06yeah, I hope you guys appreciated this.
1:56:07Um, just so that we could do a quick
1:56:09recap and because in my experience doing
1:56:12a recap of the stuff is sort of how you
1:56:14remember it. Um, we started off by
1:56:16talking a little bit about fields
1:56:17specifically two types of fields. There
1:56:18were fixed fields and then there were
1:56:20um, expressionbased fields. I sort of
1:56:23made a case for you as to why you should
1:56:24probably favor expressionbased fields
1:56:26over fixed fields wherever possible
1:56:28because you could do the exact same
1:56:29thing anyway and you also just get like
1:56:31a ton of code options. So I always just
1:56:33toggle little expression. I then showed
1:56:34you how all of these different field
1:56:36inputs even like the little toggle
1:56:37buttons these really are just
1:56:39expressions at the end of the day. You
1:56:41know if it's a toggle button it's true
1:56:42or false. If you're selecting a Google
1:56:44sheet or something and there's actually
1:56:45an ID behind it and so now you know a
1:56:47lot more about sort of the underlying
1:56:49data and the way that nad structure
1:56:50stuff. I then covered JSON JavaScript
1:56:52object notation in probably pretty
1:56:54excruciating detail. Hopefully that
1:56:56wasn't too boring. But we covered a
1:56:57bunch of different variable types. Just
1:56:59to recap them, there was a string, there
1:57:01was a number, there was a bool or
1:57:03boolean, true or false. There was an
1:57:05array, and then there was also another
1:57:06object. So you could bury JavaScript
1:57:08objects inside of JavaScript objects.
1:57:10There were key names, values. We learned
1:57:12a little bit about the formatting with
1:57:14quotes, um, as well as commas and and
1:57:16brackets and that sort of stuff. But the
1:57:17reality is if you just like stare at
1:57:19JSON long enough, kind of give it a good
1:57:20squint or two, eventually it'll start
1:57:22making sense. And that's why I've now
1:57:24changed all of the input and outputs
1:57:26inside of our NAN course tutorial to to
1:57:28favor a JSON JavaScript object just so
1:57:30you guys could see it and kind of get
1:57:31used to it. From there, we covered a
1:57:33little bit about how data is represented
1:57:35in NAN. So specifically, all data, all
1:57:38inputs and outputs in NAD are structured
1:57:40as an array of objects. So there's some
1:57:43top level square bracket and inside
1:57:44there's just a bunch of those JavaScript
1:57:46objects nestled in it. And if you want
1:57:48to reference the most previous node,
1:57:50then all you need to do is just use this
1:57:52little dollar sign JS O N syntax. If you
1:57:55want to reference nodes from 2, 3, 4, or
1:57:58nodes back, n standing for whatever
1:58:00number, then you would do the dollar
1:58:02sign, but then you'd have to like
1:58:03specifically reference the name of the
1:58:05node. No big deal. Naden actually does a
1:58:07lot of that selection for you. And
1:58:08there's usually a little drop down or
1:58:10toggle button that you can just click to
1:58:11get there. We talked about how to
1:58:12reference earlier fields, how to do some
1:58:14backtracking with like dot notation and
1:58:16square bracket notation. Then I also
1:58:17covered some common gotchas. The most
1:58:19common gotcha in Naden, just to be
1:58:20clear, is people don't understand that
1:58:22it is an array of objects that you're
1:58:23referring to. And so NAD will run once
1:58:25per item in the array. If you're trying
1:58:27to reference one item, but you're really
1:58:29referencing all of them, obviously
1:58:30you're going to get an error message.
1:58:31It's not going to work. Likewise, if
1:58:33you're trying to reference a number of
1:58:34items, but you only reference some
1:58:36subset of them, you're going to have
1:58:37some error, a message, and you know,
1:58:38you're going to get that dreadful red
1:58:40text that I think we all hate so much.
1:58:41So, understanding that everything is
1:58:43just an array of items and array of
1:58:44objects. This goes a long way towards
1:58:46insulating you against that. Finally, we
1:58:47covered some foundational notes. We
1:58:49started off with the HTTP request node,
1:58:51which allows us to basically request or
1:58:54do the same thing that your browser is
1:58:55doing when you access a website, pull
1:58:57all of the code, and then I also showed
1:58:59you guys how to do cool stuff with AI,
1:59:01where you take the extracted or parsed
1:59:04components of that node, like my
1:59:06leftclick website, and then turn that
1:59:07into some sort of AI structured data,
1:59:09like a summary, like some interesting
1:59:11tidbits about that website, maybe the
1:59:13contact details if you could find it. I
1:59:14then covered a little bit about web
1:59:15hooks. If you guys are familiar, if you
1:59:17guys remember, web hooks are just like
1:59:18the glue that holds so much of the
1:59:19internet together. I showed you guys how
1:59:21to send a request from one workflow and
1:59:23receive it in another workflow. And I
1:59:25also showed you guys how to use a third
1:59:26party platform, in this case, ClickUp,
1:59:28but you can really use whatever the hell
1:59:30you want to send a request upon some
1:59:32triggers. So that now I'm like
1:59:33connecting NAND and ClickUp with my own
1:59:35native integration without even
1:59:36necessarily having to know too much
1:59:38code. And then at the tail end there, I
1:59:39covered OpenAI and AI agent nodes. The
1:59:43real value of N8N in comparison to most
1:59:45other noode tools in addition to its
1:59:47ability to self-host is their AI agent
1:59:49functionality that just works fresh out
1:59:50of the box. So rest assured, we're going
1:59:52to be covering a lot more of that moving
1:59:53forward. But we built a very simple
1:59:55example where I essentially asked my AI
1:59:57agent what was going on for the day and
1:59:59then it pulled data from my calendar
2:00:00intelligently while also still being
2:00:02able to like talk back and forth in
2:00:04natural language. We covered some nodes
2:00:05that modify flows as well, including the
2:00:07if, the filter, the merge, the split
2:00:09into batches or bundles. We covered the
2:00:12split out and then finally we also
2:00:13covered while I was building that last
2:00:15example the limit. And then from there I
2:00:17showed you guys how to build a super
2:00:18simple and easy essentially email
2:00:20autoresponder type flow but one that
2:00:23does a very high leverage highv value
2:00:25business purpose which is parsing out
2:00:27defining whether a journalist inquiry is
2:00:29relevant to us or not than if it is
2:00:31actually writing out an example based
2:00:32off of a template. Awesome. You guys now
Asset-based AI Lead Generation
2:00:34have a solid understanding of NAND
2:00:35fundamentals, including how nodes
2:00:37connect, how data flows through
2:00:38workflows, and the core concepts that
2:00:40power more or less every automation that
2:00:41I'm going to build. Hopefully, you've
2:00:42moved from a complete beginner to
2:00:44somebody that now understands the NADM
2:00:46platform at at least somewhat a
2:00:47technical level. So, it's time to put
2:00:49those foundations to work and build our
2:00:50very first high-v value system. We're
2:00:52now going to be building an assetbased
2:00:53AI lead genen system. An assetbased
2:00:56system just means we're going to scrape
2:00:57prospect data. We're then going to use
2:00:59that to create customized lead magnets
2:01:00like a personalized newsletter or report
2:01:02and we're going to deliver them via an
2:01:04automated email campaign. The reason why
2:01:06this approach is so valuable is it
2:01:07generates 5 to 15% reply rates cuz
2:01:09you're giving value before you ask for
2:01:11anything. Let's dive
2:01:14in. So today I want to build an
2:01:16automated asset generator. I don't
2:01:18entirely know exactly where I'm going to
2:01:20start or how I'm going to do it, but
2:01:22this is a road map of my tenative
2:01:23thoughts. I built enough of these
2:01:24systems at this point to have a pretty
2:01:26good understanding of what I think I'm
2:01:27going to do, but as I've mentioned, I'm
2:01:28going to leave in the detours and any
2:01:30stumbling blocks along the way so you
2:01:31guys could see what an actual build
2:01:32process looks like. So, here is what I'm
2:01:34thinking is going to be the road map.
2:01:36And you know, in case you guys don't
2:01:37know, when I say asset here, I really
2:01:38mean like anything. You could generate
2:01:40like PDF slide decks, you could generate
2:01:42onboarding documents, you could generate
2:01:44newsletters. That's what we're going to
2:01:46be generating today. You could generate
2:01:47cold email sequences. Like the value of
2:01:49an automated asset generator is it just
2:01:51like gives a ton of value to somebody
2:01:52right off the bat. And you can also use
2:01:54it in your own business to generate
2:01:55stuff you want. Here's the mindset. So
2:01:56we're going to start by getting LinkedIn
2:01:58data. Now LinkedIn for those of you guys
2:01:59that don't know is what's called UGC.
2:02:01It's user generated content. So this is
2:02:03my own LinkedIn profile. All of the data
2:02:04on this page is data that I have written
2:02:07essentially most of the data. Anyway,
2:02:08the value here is that means that I've
2:02:10written most of this in my own tone of
2:02:12voice. So if somebody does something
2:02:14with it, if it uses if they use it to
2:02:15create an asset or something, I'm a lot
2:02:17more likely to find it valuable. Okay,
2:02:19so that's where all of this rests on.
2:02:21We're going to start by scraping
2:02:22LinkedIn data. The idea after that is,
2:02:25let me just skip ahead. I'm also going
2:02:27to scrape their company website and
2:02:28we're going to get the data of their
2:02:29website from LinkedIn. Like we're going
2:02:30to get the URL and stuff like that. Once
2:02:32we have the LinkedIn data and the
2:02:34website, we're going to feed this into
2:02:35AI and we're just going to generate a
2:02:37summary. Then with this summary, what
2:02:38we're going to do is we're going to
2:02:39generate a customized newsletter using
2:02:42that data, convert it into an HTML. Then
2:02:45we're going to create a Google doc with
2:02:46it. And then ultimately, you can do
2:02:48whatever you want with you. You could
2:02:48send it to your prospects through email.
2:02:50You could fax it to their address. You
2:02:52could print it out and literally send it
2:02:54to their place of business. You could do
2:02:55whatever you want with what I'm about to
2:02:56show you. That's what's really cool
2:02:57about it. And because cold outreach, for
2:02:59those of you that aren't aware, reaching
2:03:01out to people that haven't opted into
2:03:02some sort of marketing communications
2:03:03with you, because cold outreach is
2:03:05getting more and more saturated, this is
2:03:06a very high value way of raising the bar
2:03:09and making it seem as if you spent a ton
2:03:11of time and effort creating something
2:03:12valuable for your prospect before you've
2:03:14even talked to them, which they tend to
2:03:15really like. So, all of this is just in
2:03:17pursuit of really high reply rates on an
2:03:21email. And let me yeah, let me walk you
2:03:22through um how all that works. So yeah,
2:03:24we're going to use LinkedIn to be the
2:03:26primary data source along with the
2:03:27website of the prospect. So this is my
2:03:29own website. Then I want to combine
2:03:30these, pump these into Apollo. Apollo is
2:03:33a way that we could scrape mass lists of
2:03:35LinkedIn profiles. And then instead of
2:03:37me paying for Apollo, I'm probably going
2:03:38to use this Apify scraper, which allows
2:03:40me to scrape Apollo, which scrapes
2:03:42LinkedIn. This just allows me to get it
2:03:44for a lot cheaper. So $120 instead of
2:03:45whatever the heck Apollo is charging me.
2:03:47The end result is going to be something
2:03:48like this. This is a newsletter that I
2:03:50generated using a similar approach a
2:03:51while ago. Design meets real estate. the
2:03:53Evermore approach to bespoke living. The
2:03:55idea is that we created a newsletter for
2:03:57them called the Evermore edit. You know,
2:03:58we created topics. We wrote said topics
2:04:01and, you know, we talked about the
2:04:02founder of the business and the realtors
2:04:04and and anyway, it's just super
2:04:05customized. It's super perfect for them.
2:04:07And in our case, maybe we're like, hey,
2:04:08you know, I want to write you customized
2:04:10newsletters, super high quality. Um, you
2:04:12know, so I actually just went ahead and
2:04:13I wrote one for you. So, here it is.
2:04:14Okay. Hopefully everybody here's on the
2:04:16same page. Let's now get into actually
2:04:18building the system with an
2:04:21AD. So, the very first thing we need to
2:04:23do is we need to grab a LinkedIn data
2:04:25and we need to feed that search into a
2:04:26scraper. I'm going to be using Apify for
2:04:28it. So, what I've done is I've already
2:04:29assembled a giant list of people that
2:04:31I'm interested in working with um
2:04:32through Apollo. The way I did this was I
2:04:34added some filters up here at the very
2:04:36top. I wrote creative agency. Then under
2:04:39job titles, I wrote founder, partner,
2:04:40and co-founder. And then you can also
2:04:42add some additional filters to like
2:04:44constrain the location. In my case, I
2:04:45just wanted to get this up and running
2:04:46quick and dirty, so I didn't constrain
2:04:48the location. What we get now is we get
2:04:49a URL up at the top of the page. What
2:04:51I'm going to do is I'm going to go to my
2:04:52Appify scraper by Code Pioneer. I'm just
2:04:55going to paste in the URL and then I'm
2:04:56just going to click save and start. The
2:04:58reason why is I just want to verify that
2:04:59this works on Appify first before I try
2:05:01putting it in NAN. Okay, sweet. So,
2:05:03we're now done with this. If I go to the
2:05:05output, you'll see there's a bunch of
2:05:06information here from our search. So,
2:05:08this includes the person's location, um
2:05:10some email addresses, there's also names
2:05:13and so on and so forth. So, we basically
2:05:15have all of that LinkedIn data including
2:05:17like the title and then the industry and
2:05:19and so on and so forth. What I want to
2:05:20do now is I want to get that inside of
2:05:22NAND. So what I did is I just went over
2:05:24to their API and then I found this
2:05:26endpoint called run after synchronously
2:05:27with input and return output. What's
2:05:29really cool about this is in NADN. You
2:05:31can just copy over the curl of any API
2:05:33request and then you can paste it in. So
2:05:35that's what I'm going to do. HTTP
2:05:36request here. I'll go import curl. Paste
2:05:39it. And then what this will do now is
2:05:41it'll actually map all of the fields for
2:05:43me. So I don't actually have to do a ton
2:05:44of work. There are a few fields
2:05:45obviously I still have to put in. So
2:05:46bearer token over here. I see some body
2:05:49content type stuff. So, uh, let's sort
2:05:51that out. Now, actor ID, that's just
2:05:53going to be the URL ID up here. So, that
2:05:56is my actor ID. I'm just going to copy
2:05:57and paste that in here. And then
2:06:00underneath that, I see accept
2:06:01application JSON. Oh, authorization
2:06:03bearer token. In order to get that on
2:06:05Appify, I'm just going to open up a new
2:06:07Appify tab. And then I'll go right over
2:06:10here. API
2:06:12integrations. Create a new token example
2:06:15for N8N asset
2:06:18generator. And then let me see. I'll
2:06:21click create. So now all I do is I copy
2:06:23this. I go back here. And then I need to
2:06:26feed in one more thing. If I go back to
2:06:28my actor and then I go here. If I go
2:06:32click JSON here, I actually have access
2:06:34now to the the input that I fed in in
2:06:37JSON notation. And it looks like I'm not
2:06:39entirely sure, but I think in order to
2:06:42feed this in, I just need to feed this
2:06:43in that whole JSON string in somewhere
2:06:46here. So, I don't actually know. We're
2:06:47going to find out. I think body content
2:06:50types JSON. Specify body using JSON. I
2:06:52think I just paste this in. I don't know
2:06:53for sure. We're going to give it a try.
2:06:55We're doing this live. And then, yeah, I
2:06:58just click execute step. So, what we did
2:07:01a moment ago is we just verify that we
2:07:03can actually get the data we want from
2:07:04LinkedIn on Appify, right? Well, now
2:07:06what we want to do is we want to verify
2:07:07that we can execute that appy scraper
2:07:10inside of nana and then retrieve the
2:07:11data. The reason why that's important to
2:07:13me is because I just always like to
2:07:14verify like at every step that what I'm
2:07:16doing is directionally correct. So what
2:07:18I'll do is I'll just test every node one
2:07:19at a time until the end and then
2:07:21assuming that I can get this data then
2:07:23you know I can sort of check mark the
2:07:25first step in our road map. So a quick
2:07:27and easy way I can verify whether or not
2:07:29that is actually running because it
2:07:30looks like it's running. I haven't
2:07:31received an error code. I just want to
2:07:32verify. I can actually go back to
2:07:33Apollo, go to runs. You can see that
2:07:36there's actually a run that is currently
2:07:37occurring. How cool is that? So, this is
2:07:39actually now outputting email addresses
2:07:41and stuff like that, which is crazy.
2:07:42This is the input that I fed it. So,
2:07:44that looks fine to me. And yeah, you
2:07:45know, more or less this is now currently
2:07:47executing. And once it is done
2:07:49executing, we will hopefully receive all
2:07:51of the data here. Okay. So, I just
2:07:53pinned this and executed it. Then I
2:07:56renamed it as well. And just taking a
2:07:58peek at the output here, you see we get
2:08:00JSON with the first name, last name,
2:08:02LinkedIn. We get all the data that we
2:08:03need. The reason why I'm pinning this,
2:08:05aka I like selected it and then I
2:08:06pressed P. Um, you can also rightclick
2:08:09and and press that button as well, is
2:08:11just because it's going to allow me to
2:08:12execute future runs much faster. I don't
2:08:15actually have to wait that whole long
2:08:16process, which I think was like four or
2:08:18five minutes for 500 items ever again.
2:08:20But anyway, so moving on, we verified
2:08:22that we can do that first section that
2:08:23we want. So where's my road map? Right
2:08:25over here. We can get the LinkedIn data
2:08:27and we can feed it into a scraper appi.
2:08:29The next step we need to do is we need
2:08:30to scrape the company website, right?
2:08:31How am I going to do this? Let's just
2:08:32move this over here so it's right by my
2:08:34notes and I can just jump back and forth
2:08:35really easily. How are we going to do
2:08:36that? Well, a quick and easy way is
2:08:38obviously just using the HTTP request
2:08:40node in NAN and then just feeding in the
2:08:43website. So, if I go to website, see
2:08:45there is a website URL and it looks like
2:08:47this is the same lead that I scraped
2:08:48when I did this. So, the Apollo search
2:08:51must just be the exact same one over and
2:08:52over and over again. But anyway, let me
2:08:54paste that in. What I want to do now is
2:08:55I just want to like call the website
2:08:56with an HTTP request. If you guys are
2:08:58unfamiliar like what an HTTP request to
2:09:00a website is, is this website here,
2:09:03leftclick.ai, I could actually just run
2:09:05this independently using this by like
2:09:08hard coding. Okay, if I just delete all
2:09:11of these and then execute this one
2:09:13manually here, what happens when I click
2:09:15execute workflow is this is actually
2:09:17outputting all of the HTML data from my
2:09:20site. Now, this may not seem like it
2:09:22means anything to us, but check this
2:09:23out. growth systems for B2B companies.
2:09:25Let me command F growth systems. Do you
2:09:27guys see how the exact same thing is
2:09:29written both on my website and then
2:09:31represented inside of the code of my
2:09:33website too? So all of this HTML, this
2:09:35is just my whole website. It's just
2:09:36written for machines, not people. So all
2:09:38we need to do if you think about it
2:09:39logically is we just need to convert
2:09:40this from something that is machine
2:09:41readable into something that's more
2:09:42human readable or I guess AI readable I
2:09:45should say, which is a machine. The
2:09:46lines are blurring every day if you guys
2:09:48couldn't tell. The issue is um notice
2:09:50how like here I'm outputting 500 items.
2:09:53Do you guys see how it says 500 there?
2:09:55If I were to just run this, I'd
2:09:56basically have to run 500 HTTP requests
2:09:58until I see the final result. I don't
2:10:00want to do that. What I want to do is I
2:10:01just want to run it like one at a time.
2:10:02One at a time, one at a time. And then I
2:10:04want to see what the output is. And I
2:10:05want to verify that things are okay. I
2:10:06think a lot of beginners make this
2:10:07mistake. They try and run off of full
2:10:09data sets. Don't do that. Instead, just
2:10:11let's think to start like some of these
2:10:13aren't going to have a website, right?
2:10:14So, why don't we filter these and we'll
2:10:15just make sure that like we're only
2:10:16going to operate off of things that have
2:10:18websites. So, let's go down to website.
2:10:20Let's say website URL has to exist. And
2:10:23let's also say, you know, I don't know,
2:10:25maybe I only want to do this for people
2:10:26that have email addresses. So, email
2:10:28address also has to exist. And now what
2:10:30I want to do is now I'm going to execute
2:10:32this. Uh, hold on. Just going to delete
2:10:35this here because I only want to run
2:10:36this uh last one filter. Let me just
2:10:38execute this and let's see how many of
2:10:40the 500 are we actually going to get
2:10:41that have both websites and emails. 247.
2:10:43Okay. So, I'm going to pin this. And now
2:10:44what I want to do is I actually just
2:10:46want to test. So, I'm just going to use
2:10:47a limit node. And I always use limit
2:10:48nodes. And I'll just do two. The reason
2:10:50why I always do two is because if you do
2:10:52one, sometimes you can't fully figure
2:10:54out like array logic. So, you need to do
2:10:55more than one. But if I do more than
2:10:56one, then I'm just doing a bunch of HTTP
2:10:58requests unnecessarily. Okay. Now, I'm
2:11:00going to feed this in. And what's the
2:11:01output of this limit node? You know,
2:11:02it's the first two leads basically.
2:11:04Okay. So, actually, maybe we should do
2:11:06last two so I'm not just regenerating
2:11:07the same thing I showed you guys
2:11:08earlier. Let's do that. Let's unpin
2:11:10this. Let's execute this workflow.
2:11:13This is now going to output the last
2:11:15two. Okay, cool. And then I'm going to
2:11:16feed it into my HTB RES. And I'm just
2:11:17pinning every node as I run it one at a
2:11:19time. And this is really valuable for me
2:11:20because um again, it just allows me to
2:11:22test really quickly. So now what I want
2:11:24to do is I want to feed in the website
2:11:25URL. Just going to feed that in. Um I
2:11:27don't think I'm going to make any
2:11:28changes. I think that's probably fine.
2:11:29Now I'm just going to click execute
2:11:30workflow and let's see what we get as a
2:11:32result. Going to give this a click.
2:11:35Yeah, let's display the data. This is a
2:11:36fair amount of data, so it doesn't want
2:11:38to display it for me if it doesn't have
2:11:39to. But it looks like we're now scraping
2:11:41this website. Um,
2:11:44showandtell.co.cza, which is cool. So,
2:11:46showandell.co.ca. Let's see what it
2:11:48looks like. This is really clean.
2:11:50They're a premium content partner, Cape
2:11:52Town, South Africa based. Wow. Very
2:11:55cool. This is a fantastic example. So,
2:11:57I'm glad that we're scraping them. Cool.
2:11:58So, now that we have the data, if you
2:12:00think about it right now, this is an
2:12:01HTML format. It's really long. Do I want
2:12:03to load 2.2 megabytes of data every time
2:12:04I'm doing this? Probably not. So, what
2:12:06I'm thinking of doing is now that we've
2:12:08scraped the company website, we have to
2:12:10feed into AI, but it's just so big. I
2:12:12don't really want to spend all this
2:12:13money on tokens. So, what I'm thinking
2:12:14I'm going to do is I'm going to go
2:12:14markdown. And there's an HTML to
2:12:16markdown here. So, I'm just going to
2:12:17feed in the HTML. What this is going to
2:12:19do is you see all the tags, you know,
2:12:21the less than symbol, exclamation point,
2:12:23doc type HTML, back slash. I can
2:12:25actually just remove all these with this
2:12:26markdown node. And then it'll only
2:12:27output text in this format called
2:12:29markdown, which is a lot easier and
2:12:30simpler. So, this is no longer 2.2
2:12:32megabytes. This is actually pretty
2:12:34simple. And what's cool is I think
2:12:35there's email addresses on this page.
2:12:36Yeah. So, we could actually scrape the
2:12:38hell out of this ourselves if we wanted
2:12:39to. Okay. But anyway, so now if you
2:12:41think about it, what is the output of
2:12:42this? It is a bunch of data about the
2:12:43specific website. It's just like this.
2:12:45And now we have it in a format where we
2:12:47can feed it into AI and have it tell us
2:12:49something about this website so we can
2:12:50customize the hell out of our outreach.
2:12:52So, let me just double check. How far
2:12:54are we down the road map? Yeah. Okay.
2:12:56So, it's time to feed into AI to
2:12:57summarize leads. So, how are we going to
2:12:58do that? Well, it's pretty simple. Now
2:13:01that we're done with all these damn HTTP
2:13:02requests, we just go to OpenAI and I'm
2:13:06going to do message a model. And first
2:13:08we have to do our authorization. So give
2:13:09this a click. What you have to do is you
2:13:11have to head over to the OpenAI API site
2:13:13and then you have to grab your API key.
2:13:15Now I'm not going to share my API key
2:13:16with you guys, but I want you to know
2:13:17it's really easy and ADA has awesome
2:13:19documentation for this. It actually
2:13:20shows you how to do this. You just go to
2:13:22the API keys page here and you see at
2:13:24the bottom lefthand corner of my URL
2:13:25says http
2:13:28platform.open.com/appi-keys. That's what
2:13:30you feed in here. You don't need to do
2:13:31the organization ID, at least not as the
2:13:32time of this recording. Once you make
2:13:34your connection, now you actually have
2:13:36access to the open AI API. So, hello,
2:13:38how's it going? Let's ask. I'm going to
2:13:41click execute step. Now, this is
2:13:43actually going to ask the model. Hello,
2:13:44how's it going? Uh, what's the issue
2:13:48here? I don't actually know what the
2:13:50issue is. Oh, sorry. We haven't picked a
2:13:52model. My bad. My bad. We got to pick
2:13:53the model first. Let's do chatb 4.1.
2:13:55That's the current model that I'm going
2:13:56to use. And now I'm going to execute the
2:13:58step.
2:13:59and we should get something should tell
2:14:01us hello I'm doing well hello I'm here
2:14:03and ready to help. So we ran this twice
2:14:04for two items and it gave us two
2:14:05different um outputs, right? So now what
2:14:08we have to do if you think about it
2:14:09logically, if we want to make this
2:14:10output like something that's relevant to
2:14:12us, we have to take all of that website
2:14:13data, we have to give it to AI, but we
2:14:14also have to give it some instructions.
2:14:16So what I'm going to do next is I'm
2:14:16going to write a a quick and simple set
2:14:18of instructions that you guys could use
2:14:20in order to have AI convert things into
2:14:21a format that you want. Make sure to
2:14:23output content as JSON. There are a
2:14:24million ways to do this. Um what I'm
2:14:26going to do is I'm going to basically
2:14:27say, hey, at least I think I'm going to
2:14:29do this. Hey, can you summarize what the
2:14:31website is about? give me some unique
2:14:33information. From there,
2:14:35maybe I'll combine it with the profile
2:14:38history as well. So, what I always do is
2:14:40I always start with a system prompt that
2:14:41says you are a helpful intelligent
2:14:43assistant. I just do this because I
2:14:45think the model ends up smarter as a
2:14:47result of this. Next, I do a user
2:14:49prompt. Now, user prompts are where you
2:14:51basically tell the model exactly what
2:14:52you want it to do. So let's say your
2:14:54task is to take as input a bunch of
2:15:01unstructured
2:15:02information about the client's website
2:15:05and linked in profile and convert it
2:15:09into a JavaScript object notation a JSON
2:15:13output. I may adjust this wording a JSON
2:15:15output of the
2:15:17following format. Let's do one called
2:15:21website context.
2:15:23Let's do one called person context. And
2:15:26let's do one called, I don't know,
2:15:28unique angles. I'll just go with unique
2:15:30angles for now. And what's the idea
2:15:32here? I just want to take this massive
2:15:34string of both the LinkedIn profile
2:15:35data, which I'll show you guys in a
2:15:36second, and then the website data and
2:15:38just turn it into something simple for
2:15:39me so that I could feed it into the
2:15:41newsletter generator, which I'll feed in
2:15:42after this, and then have it like do
2:15:44something with. Okay. So, I've also just
2:15:45written a bunch more instructions. So,
2:15:47you receive all the data. You need an
2:15:48unstructured string. You're ask to parse
2:15:49that out, turn that into the above
2:15:50object. uh go deep into detail for
2:15:52website contexts. Write at least two
2:15:53paragraphs for person context where use
2:15:55all the data available and for unique
2:15:56angles. Use all the website and
2:15:57information about the provided person to
2:15:58create three interesting points that we
2:16:00could write about in a later article.
2:16:02Return any new lines as back slashn.
2:16:03Okay, that seems pretty simple. Um what
2:16:05I got to do now is I obviously have to
2:16:06feed in the data. So I'm just going to
2:16:08go to my user prompt here and then I'm
2:16:09going to start like adding variables. So
2:16:11let's start with the website scrape.
2:16:14Website scrape is just going to be this
2:16:15markdown data. So, let's just do that.
2:16:18And then let's go personal data scrape.
2:16:23And then here, I'm just going to start
2:16:24feeding in a bunch of information from
2:16:25the LinkedIn profile. So, where am I
2:16:26going to get that? Probably from the
2:16:27limit node. So, I'm going to go like
2:16:29name here. Let's just work our way down,
2:16:32right? Like title. That seems pretty
2:16:34valuable for the AI to have. Let's do
2:16:36headline. So, maybe we know that we're
2:16:37addressing the person. Okay. And I just
2:16:39added a bunch more. Email, state, city,
2:16:41country, whatever. So, um, that should
2:16:44now be everything that we need in order
2:16:45to actually have this run. So let's
2:16:46execute this now and let's see what
2:16:47happens. Just double checking my data is
2:16:49the same. Let's do temperature also and
2:16:52let's go 0.6. I just like to have like
2:16:55lower temperature in general. And let's
2:16:56execute this. Let's see what happens
2:16:57now. Okay. So we're now feeding it in
2:17:00that data from the markdown node. It's
2:17:02running which is great sign. Let's go
2:17:04open AI. Nice. Okay. Great. And let's
2:17:06see what do we get. Website contact.
2:17:08Showand tell Creative is a premium
2:17:09content partner based in Cape Town,
2:17:10South Africa specializing in stills. The
2:17:12company position solves as broader
2:17:13impactful. Wow. This is really cool. So,
2:17:16it gives us all of the data. It gives us
2:17:18a ton of data
2:17:19actually. Gives us some context about
2:17:21the specific person. Then it gives us
2:17:23unique angles. This is what I was most
2:17:24interested in about because I want to
2:17:25use these in order to generate the
2:17:26newsletter. The impact of running a full
2:17:28service content production agency is
2:17:29solo founder. How Kevin Sawyer manages
2:17:30every aspect. How he does this, how he
2:17:32does that. Okay, cool. This seems pretty
2:17:33valuable. You can see we did the same
2:17:35for another agency called Craft and
2:17:37Slate. These always have such
2:17:38interesting names, but then again,
2:17:39that's creative agencies for you. Um,
2:17:41now let's take this data and use it to
2:17:43generate something. So, I'm just going
2:17:44to duplicate this. Paste this in. And
2:17:46you'll have to bear with me here. Um, my
2:17:48prompt
2:17:49engineering a little bit rusty. I
2:17:51haven't designed a system in a couple of
2:17:52weeks here. But I think what I'm going
2:17:54to do is I'm going to have it generate a
2:17:55newsletter. So, your task is to take as
2:17:59input information about a website and a
2:18:07person and then return. Let's do
2:18:10customize
2:18:12newsletter. a customized newsletter that
2:18:16contains maybe we'll say customized
2:18:18newsletter that will act as a lead
2:18:21magnet to get them to want to purchase
2:18:24my stuff. Let's just go with that. Okay,
2:18:27this looks pretty good to me. Now, I
2:18:29want to give it an example of a
2:18:31newsletter. So, the reason main reason I
2:18:33picked this example is cuz I knew it'd
2:18:35be easy for me. But um I used to write a
2:18:37newsletter back in the day called the
2:18:39cusp where I basically had AI helped me
2:18:42write this stuff way back in 2022, but
2:18:44it was just a whole newsletter all about
2:18:46like AI and automation and how AI is
2:18:48changing the economy and stuff like
2:18:49that. So what I'm going to do is I'm
2:18:50actually just going to copy my own
2:18:51newsletter format like verbatim. And I'm
2:18:52just going to paste it
2:18:54in. Let's go back here. Let's paste it
2:18:57in. That looks pretty good. And I'm just
2:18:59going to use this as like the format.
2:19:01I'm going to say return the entire
2:19:02newsletter in markdown using this JSON.
2:19:05And then okay cool we should now return
2:19:06it in title subheading and newsletter
2:19:09body format. I did some minor adjusting
2:19:11to this. Um but anyway this is what this
2:19:13looks like now. This is the prompt that
2:19:15we are now giving it. So what do we
2:19:16actually want to do now? We just want to
2:19:17feed in that object that we gave a
2:19:18moment ago. Website context person
2:19:20context unique angles. Okay. So let's
2:19:22delete that and let's just
2:19:24say website
2:19:27context person
2:19:29context and then unique angles.
2:19:34And then what I'm going to do is I'm
2:19:34just going to go expression and I'm just
2:19:36going to drag this in. Website context
2:19:38here, person context here, then unique
2:19:41angles here. Awesome. So now I'm
2:19:44actually feeding in all the data.
2:19:45Outputting content as JSON 0.6 again.
2:19:47And this is just happening cuz I
2:19:48duplicated this. So all the settings are
2:19:50going to be the same. I'm thinking we
2:19:51should probably rename this. So this
2:19:52will just be like generate website
2:19:55context or generate context, let's say.
2:19:57And then this here will be like generate
2:19:59newsletter. That seems smart to me. And
2:20:01then yeah, I have everything I need to
2:20:02actually just test this again. So let's
2:20:04click execute workflow. Let's see how it
2:20:09works. Execute and workflow. Cool, cool,
2:20:12cool. Okay, cool. Now let's take a look
2:20:14at the output. Content that gets
2:20:16remembered. The show and tell creative
2:20:17approach inside the solar journey of
2:20:18Kevin Surin and how Cape Town's boutique
2:20:20agency is reshaping media production.
2:20:22Then we have the newsletter body. Wow,
2:20:24this is great. Well, I actually don't
2:20:27know how great it is, but we're going to
2:20:29see in a second. Um, now the rest of
2:20:31what I want to do here hinges on Google
2:20:34Docs cuz n Google Docs is kind of hard.
2:20:36But to make a long story short, what I'm
2:20:37thinking of doing is we're going to take
2:20:39this output and we're going to convert
2:20:41it into HTML because HTML is the format
2:20:43that Google Docs natively uses. And then
2:20:44we're going to try generating a Google
2:20:45Doc with it. This may require a little
2:20:46bit of finagling with like the Google
2:20:48Docs API spec, but I'm confident I can
2:20:50make it work. I've done it before.
2:20:51Basically, so yeah, like the markdown
2:20:53stuff is cool, but I want it to be in
2:20:55like a sexy format like this, right? So,
2:20:57you can't get a sexy format like this
2:20:59through markdown. Unfortunately, you
2:21:00have to do HTML. So, what I'm going to
2:21:01do is I will take this and then I'm
2:21:04going to output another markdown
2:21:06converter. We'll go HTML to markdown.
2:21:08Now, we're going to go markdown to HTML.
2:21:09Feed that in. Now, this should give me
2:21:12just a bunch of markdown that I could
2:21:13use, which is what we want. Come on,
2:21:15little markdown node. I believe in you.
2:21:18Okay, where is this data? As you guys
2:21:20can see, I use the JSON. Okay, so here
2:21:22it is. It's in a data object. So H1,
2:21:25they even add some ids which is really
2:21:26interesting. Very cool. Okay. And then
2:21:29now now I want to do a Google Docs. So
2:21:30Google Docs
2:21:32here create a document right over here.
2:21:36Now I already have a Google Docs
2:21:37credential. If you guys don't, you just
2:21:38click create new credential ooth 2. Then
2:21:41there is one additional step you have to
2:21:43make you have to take which um you guys
2:21:45might not have already. What you have to
2:21:47do is you have to go to your cloud
2:21:49console Google account and you have to
2:21:50pump in the client ID and the client
2:21:51secret. if you've never done this before
2:21:53and it has awesome guides and breakdowns
2:21:55that will help you do that. There also a
2:21:56bunch of videos that other people have
2:21:58actually posted going through this whole
2:21:59process. I've already created a Google
2:22:01Cloud Console project, so unless I make
2:22:02an entirely new one for a new Workspace
2:22:04account, it's not going to be the
2:22:05cleanest. I don't really want to just
2:22:07make a bunch every time. But what you
2:22:08can do is you can create a Google Cloud
2:22:10Console project by logging in and then
2:22:13selecting a new project, adding a
2:22:15location, and then once you've created
2:22:16it, you just enable Google Docs as an
2:22:19API. Then you request API access and
2:22:22then get your little um OOTH token. Um
2:22:25the really cool thing about NN is they
2:22:26just walk you through how all this this
2:22:27stuff works which uh makes it
2:22:29significantly simpler for beginners.
2:22:30What I've done obviously is I've already
2:22:32created one. So now that I've created
2:22:34one, all I have to do is I have to like
2:22:36add some location. Then what I want to
2:22:38do is I just want the title to be
2:22:40something really simple. Let's just go
2:22:42for let's add the person's name. So for
2:22:44Kevin. So I'm gonna say hey this is for
2:22:47Kevin. Maybe like newsletter for Kevin.
2:22:49That sounds pretty cool. Okay, so um
2:22:52what I want to do is I now want to
2:22:53create these. So I'm just going to pin
2:22:54this previous output. I'm going to
2:22:56create it. And the really annoying thing
2:22:58that you can't do natively in Nadens's
2:23:00Google Docs nodes is I don't believe you
2:23:02can like create documents with HTML. So
2:23:05what we have to do is we have to split
2:23:06into two steps. We have to create the
2:23:07document first. Now we have a document
2:23:08called newsletter for Malcolm and
2:23:10newsletter for Kevin. I'm just going to
2:23:11pin these. And now what we have to do is
2:23:13we actually have to update that document
2:23:14with HTML. So if you've never done this
2:23:16before, HTTP request node and then what
2:23:18you have to do is under authentication
2:23:19go predefined credential type. All
2:23:21right, the credential type is going to
2:23:23be what you just created a moment ago.
2:23:25Google Docs O2 API and it'll
2:23:27automatically populate. Then we want to
2:23:30send
2:23:31headers. I'll go JSON. I think it's
2:23:33content
2:23:35type text HTML. I'm not entirely sure.
2:23:38And what we need is we need a very
2:23:40specific API
2:23:41endpoint which I think is this one here.
2:23:44It says upload file data.
2:23:48googleis.com/upload/drivev3/files upload
2:23:50type equals media. So I think this is
2:23:52the endpoint. I'm not entirely sure.
2:23:54We're going to give it a try in a
2:23:55second. The last thing I have to do is
2:23:56go patch. Then we got to send the
2:23:58body. We're just going to go raw and
2:24:01then text HTML probably. Then under body
2:24:05we're going to feed in I guess the HTML
2:24:07that we just generated which will be
2:24:09here. Oh, okay. Right over here. And I
2:24:12think this is probably it. I'm not
2:24:14entirely sure, but let's just give it a
2:24:15go. Screw it. Okay, so I got the data.
2:24:18Don't know if this is right. So, what am
2:24:20I going to
2:24:21do? I'll just go Google Docs and see if
2:24:23there's newsletter. Oh, there is. So,
2:24:25let's watch the one for Kevin. Ah, nice.
2:24:27And now we have our newsletter.
2:24:28Beautiful. Okay, let's actually read
2:24:30some of this. Welcome to the insiders
2:24:31lens. That's what we're calling the
2:24:33newsletter. A fresh look at how
2:24:34impactful content is made and the people
2:24:35behind the camera are redefining what it
2:24:36means to be seen and remembered. In this
2:24:38issue, running a full-ervice content
2:24:40agency as a solo founder, Kevin's
2:24:41Playbook: The Art and Science of
2:24:43Unforgettable Content and Navigating the
2:24:44South African Media Scene. Meet Kevin,
2:24:46the founder and driving force behind
2:24:48Show and Tell Creative based in Cape
2:24:49Town. Kevin wears every hat. Creative,
2:24:51director, producer, liaison, and
2:24:53post-production specialist. Do you guys
2:24:54know notice how like I knew none of this
2:24:56in generating the newsletter. None of
2:24:58this data was known to me. We just
2:24:59pumped it all into the system. Pumped
2:25:01way too much data into the system, I
2:25:02should say, and then just let AI figure
2:25:04it all out. And now AI actually has all
2:25:06this information. like the fact that
2:25:07Kevin is a creative director, producer,
2:25:09client leazison, post-production
2:25:10specialist, end to end ownership, right?
2:25:13Um, you know, you could see this being
2:25:14pretty valuable as like an internal
2:25:16newsletter. We even have like the email
2:25:17address. We have everything. So, I mean,
2:25:19you know, obviously some ways you can
2:25:21make this sexier. We could add some
2:25:23spacing. We could add some more, I don't
2:25:26know, we could add images. We could add
2:25:27links here. As you can see, it already
2:25:28hyperl in an email. But, um, you can
2:25:30take this into a million different
2:25:31directions. My goal was just to show you
2:25:33guys how simple it is to get up and
2:25:35running with an actual asset generator.
2:25:37Okay, so what I want to do now is yeah,
2:25:39like if you wanted this to run
2:25:40completely autonomously, it'd probably
2:25:42be difficult without adding some
2:25:43weights. So you see this like limit node
2:25:45here. We're just doing two at a time.
2:25:47What you can do instead just to make it
2:25:49like run kind of a lot more autonomously
2:25:51is you use a loop over items node and
2:25:54you just set the batch size in like
2:25:56this. The replace me loop. This isn't
2:25:59going to be
2:26:00done. What a loop and batches does is
2:26:02actually allows you to run instead of
2:26:04like right now we're running kind of
2:26:05like all of these simultaneously. What
2:26:07the loop and batches node is is going to
2:26:08do is just going to run like one at a
2:26:10time and then you could add like a
2:26:11weight. I don't know, let's say you do
2:26:13this uh and then for every person you
2:26:15wait like 5 seconds and then you loop
2:26:16back. This is a pretty simple and easy
2:26:18way that I've seen people get around
2:26:19rate limits and and whatnot. So maybe
2:26:21I'm going to add that in. The thing is
2:26:22once you're done obviously then um you
2:26:25know you would attach this top route.
2:26:27So, I'm just not going to attach
2:26:28anything in the top route and I'm just
2:26:29going to use the loop and batches node
2:26:30to like give me some peace of mind. Then
2:26:32I'm going to increase the limit here to
2:26:33let's say 10
2:26:35items. Going to unpin this. And then I
2:26:38think we can probably just execute the
2:26:40workflow. No. Yeah, it looks good. And
2:26:42now we're waiting and we're just going
2:26:43to do the same thing over and over and
2:26:44over and over again. Oh, I think I'm
2:26:46realizing now I've just pinned all
2:26:48these. So, it's just generating the same
2:26:49thing one more time. Let's just undo
2:26:50this. Uh, unpin. We're going to have a
2:26:54bunch of data issues because I don't
2:26:55think it's actually been filled
2:26:57in. Okay, there we go. Now it's actually
2:26:59generating the context. And notice how
2:27:01it's going to do two API calls. It's
2:27:03going to do, sorry, it's going to do a
2:27:04couple API calls, but two API calls to
2:27:05open AI. This one here, this one here.
2:27:07Then we're going to do an API call here
2:27:09to the website. Well, I guess this is
2:27:11just an HTTP request. And then two
2:27:13Google Docs API calls. It's going to be
2:27:15two to
2:27:17OpenAI, two to Google Docs, and then
2:27:20we're going to wait 5 seconds. And I
2:27:22think the 5-second wait is going to give
2:27:24us enough time to like never have to
2:27:26worry about hitting rate limits. But
2:27:27obviously it depends on like the the
2:27:28frequency that you hit and also your
2:27:30tier. And this one you should be you
2:27:32should be totally fine cuz just an HTTP
2:27:34request. And then yeah, we're just going
2:27:35to cycle over and over and over again.
2:27:37Wait 5 seconds and just do it until the
2:27:38end of time. You can increase the batch
2:27:40size however you want. I've just done
2:27:41one here, but you could do two. And then
2:27:43yeah, let's see what this next one was.
2:27:44Newsletter for Adam. Let's just go back
2:27:47to my other account.
2:27:52Let's see this one. The bright age
2:27:54advantage creative campaigns, measurable
2:27:56results inside the agency where data
2:27:58meets design and clients come first.
2:28:00Now, I mean like if I were to actually
2:28:01make one of these things, as in actually
2:28:04send this to clients, I would probably
2:28:06ask the model to do this in slightly
2:28:08less of a syopantic tone. Like the way
2:28:10that it's written right now is sort of
2:28:11like, hey, look how great our agency is.
2:28:13Uh, you know, obviously it depends on
2:28:15the agency. There are a lot of like big
2:28:16PR companies that actually want to write
2:28:17in a way where it's like hey here's
2:28:19what's what's going on at you know
2:28:21Bright Age dispatch or something like
2:28:23that like here's Bright Age dispatch or
2:28:25weekly newsletter talking about what our
2:28:26company's up to. In my case you know I I
2:28:28think that it's it's better to write a
2:28:30newsletter just like hey here's a bunch
2:28:31offormational value that you get from
2:28:33people and know how to do the thing. But
2:28:35you know if you wanted to adjust that
2:28:36you would just adjust the prompt that we
2:28:37used right and then if you wanted to
2:28:39change like the output format. So maybe
2:28:40instead of like a Google doc newsletter
2:28:42you did some sort of like slide deck or
2:28:44something. Well, you know, instead of
2:28:46doing the Google Doc generation, what do
2:28:47you do instead? You just do the Google
2:28:48Slides generation. You create a template
2:28:50with variables in it and then just like
2:28:52have it automatically generate that. I
2:28:53basically tried to take as simple as an
2:28:55approach as humanly possible here with
2:28:57the website context and the person
2:28:59context. But I want you guys to know you
2:29:00can scale this up to whatever the hell
2:29:01you could do. Website context, company
2:29:03context, lead deal context, person
2:29:07context, you know, boss context, uh,
2:29:09subordinate context. You could get so
2:29:11much information about anybody that you
2:29:13want inside of the company using this
2:29:14sort of approach and then weave it all
2:29:16together into a huge thing. Hell, maybe
2:29:18you're generating or charts. I don't
2:29:19know. Okay, so hopefully everything here
2:29:21I've said makes sense. Hopefully you
2:29:22guys see how this works. I'm obviously
2:29:24going to be including the blueprint or I
2:29:25guess NAN template down below so you
2:29:26guys have that as well. But yeah, uh
2:29:28really had it fun putting the system
2:29:29together for you and uh looking forward
2:29:31to seeing all the cool things that you
2:29:32guys generate with this as well. What
AI Custom Proposal Generator
2:29:34we're going to be doing next is we're
2:29:34going to be building an AI proposal
2:29:36generation system that creates
2:29:37professional proposals on demand during
2:29:39sales calls. This system takes basic
2:29:41client information from a form. Then
2:29:43we're going to generate fully customized
2:29:44proposals with problem statements,
2:29:46solutions, timelines, and pricing. It's
2:29:48all going to be in real time and it's
2:29:49all going to seem very personalized. A
2:29:51automation agencies typically charge
2:29:52$1,500 to $5,000 for this system because
2:29:55it dramatically improves close rates and
2:29:56it also makes them look incredibly
2:29:57professional. Let's dive in. So from a
2:29:59bird's eye view, system is going to look
2:30:02like this. We're going to start by
2:30:05filling out a form. Okay, this is going
2:30:07to be called our trigger. Obviously, I'm
2:30:10doing this just on a whiteboard here
2:30:11because I want to be able to, you know,
2:30:13kind of express my thoughts a little bit
2:30:14better, play around with some ideas. I'm
2:30:16going to be building this with you guys
2:30:17as if I was a builder, not necessarily a
2:30:19teacher. So, I'm going to be showing you
2:30:20guys the various detours that I might go
2:30:22down. I'll show you guys my own thought
2:30:24process as I put a system like this
2:30:25together. You know, really the emphasis
2:30:26of this channel is obviously learning by
2:30:28doing. So, that's what I want to do
2:30:29here. But, we're going to start with
2:30:29this form fill trigger. From there,
2:30:31we're going to use AI to generate JSON.
2:30:36If you guys remember, JSON stands for
2:30:38JavaScript object notation. These JSON
2:30:41fields are going to be there going to be
2:30:42a lot of these JSON fields. Okay, but
2:30:44just to give you guys a quick example
2:30:46what this might look like, it might look
2:30:47like proposal title. Okay, and we'd
2:30:49obviously use this to fill in the
2:30:50proposal title segment of our proposal
2:30:52template. We might have, I don't know,
2:30:54problem statement.
2:30:56You know, I'm using camel case here,
2:30:58hence why the second word in a variable
2:31:01name is always capitalized. Feel free to
2:31:02call them whatever the hell you want.
2:31:03We'll do stuff like cost. You know, we
2:31:05might need to do some really quick
2:31:06formatting. AI is just a quick and easy
2:31:08way to like add commas in the right
2:31:09place, dollar signs, that sort of stuff.
2:31:11And then we might do things like
2:31:13timeline. And I'll show you kind of how
2:31:15all this works in a moment. But the
2:31:16important thing that I'm putting across
2:31:18from you is we're going to grab data
2:31:19from a form, but that's going to be sort
2:31:21of a simple like a dumb form. And what
2:31:23we're going to do is it's AI that's
2:31:25going to convert this simple dumb data
2:31:26into this super hyperpersonalized stuff
2:31:28that that makes it seem as if you wrote
2:31:30it yourself, you know, and then sent it
2:31:31within a few seconds. So that's really
2:31:33where the value is, and that's what I'm
2:31:34going to show you guys how to do. After
2:31:35that, we're going to do API calls or
2:31:38built-in nodes, you know, whatever it
2:31:41ends up being. And I'll show you how to
2:31:43do this with slides to start. And then
2:31:45afterwards, I'll show you how to do so
2:31:46using a platform called Tandoc, which I
2:31:48like to use for basically every business
2:31:50that I work with. It's the business
2:31:51proposal platform that I recommend
2:31:52anytime I start doing consulting with a
2:31:54new company or automation for a new
2:31:55company. And the value of me showing you
2:31:56how to do this is I want to give
2:31:57everybody here a free option to do this
2:31:59system. But I also want to show you guys
2:32:00if you guys just, you know, pour
2:32:01gasoline on it, what the system can look
2:32:03like. Panadoc's great because you can
2:32:04actually send like an invoice alongside
2:32:06your document, which is just super
2:32:08valuable. You know, you cut down like
2:32:09three or four steps of proposal,
2:32:11agreement, invoice, right? All that
2:32:14bureaucratic jumble you can cut down to
2:32:16just one where you send the proposal,
2:32:17which includes a built-in agreement and
2:32:18includes a built-in invoice. And then
2:32:20finally, we're going to weave it
2:32:21together with, you know, NAD. And I
2:32:23mean, I'm going to be doing all the
2:32:23building in NAN here. Uh, let me just
2:32:25show you guys where I'm at right here. I
2:32:27was just verifying that some of these
2:32:28API endpoints connected and worked. But
2:32:30yeah, let's uh let's get started. So,
2:32:32I'm just going to call this thing AI
2:32:33proposal generator system. I've done
2:32:36this build multiple times across various
2:32:38uh noode platforms. Like I did this same
2:32:40build in make.com for people here that
2:32:42have been with me since the uh the
2:32:43make.com days. This is a super high-rise
2:32:45system, but I want to impress upon you
2:32:47right now that it's not necessarily like
2:32:48a complicated system. You know, one big
2:32:50trend I see a lot of people do on
2:32:51YouTube nowadays is they'll they'll put
2:32:52together these
2:32:54extraordinarily complex looking things.
2:32:56Okay? Um, you know, like their system
2:32:58will will kind of look like this.
2:33:00There'll be like some start node here
2:33:01and then maybe there'll be like some AI
2:33:03agent node and then there'll be like 5
2:33:05million sub aents and every one of those
2:33:08sub agents will call like another 5
2:33:10million sub sub aents and so on and so
2:33:13on and so forth until a meteor comes and
2:33:15and obliterates us for the second time.
2:33:16These systems, you know, they look
2:33:18really pretty, but I'll be real, they
2:33:19don't actually most the time drive a
2:33:21business outcome because they're a
2:33:22little too flexible. Most of the time if
2:33:24you want to drive money using no code
2:33:26platforms, you have to be a little bit
2:33:27more rigid. And this is uh at least in
2:33:29my experience the the perfect mixture of
2:33:31the two. Okay. So for now I'm just going
2:33:33to add a manual trigger node. And we're
2:33:35just doing that because obviously we
2:33:36want to be able to test this. I'm just
2:33:38going to call this test. Kind of a
2:33:40couple options here. I'm going to start
2:33:41with the Google Slides approach. But you
2:33:43know we'll quickly segue into Panda do.
2:33:45Let me give you guys a quick example of
2:33:46what like a good Google Slides template
2:33:49might be. There's this one over here
2:33:50just called your big idea made to stick.
2:33:52So I'm just going to take a quick peek
2:33:53at that. And basically what I'm going to
2:33:54do is I'm just going to touch up a
2:33:56template like this. probably this exact
2:33:57one to be honest. Make a few changes to
2:33:59it. And then what I'm going to do is I'm
2:34:00going to replace this stuff with
2:34:02variables. If we jump into Google
2:34:04Slides, there's this one node called
2:34:05replace text in a presentation. So we're
2:34:07actually going to use that to like
2:34:08replace the various text fields. And so
2:34:10we want them to be very unique. I'm just
2:34:11going to wrap them in these double
2:34:12quotes which we're all used to for JSON
2:34:14formatting for convenience purposes. And
2:34:15these are the variables I'm going to be
2:34:16replacing with text. So yeah, you know,
2:34:18I have the proposal template over here.
2:34:20Let me touch this up really quickly and
2:34:21then I'll show you guys basically my ID
2:34:22and what this is going to look like.
2:34:24Okay, great. Just touch this up. give
2:34:25you guys an example of what a proposal
2:34:26like this might look like. So you can
2:34:28see they're pretty high quality. They
2:34:29look pretty sexy. I wrote one for my own
2:34:31content writing copy on Second Copy. So
2:34:32this is a hypothetical proposal for a
2:34:34lead genen system for one second copy.
2:34:36As you can see, we're going to customize
2:34:37the hell out of it. All of this is going
2:34:38to be AI generated. There's going to be
2:34:39nothing here that's human written aside
2:34:41from just some templated bits. I'll show
2:34:42you in a second, but lead genen system
2:34:43for 1 second copy is simple, scalable
2:34:45lead generation system built to help
2:34:46grow your content efforts and connect
2:34:47you with the right people. The problem
2:34:49right now, 1 second copy is struggling
2:34:50with an inability to generate qualified
2:34:52leads. The majority of our new clients
2:34:54are referral-based, which while always
2:34:55nice to have, is not scalable, nor is it
2:34:56reliable. Building an alternative
2:34:58strategy, one that allows you to take
2:34:59leads from cold to close, is vital to
2:35:01the health longevity of the company, and
2:35:02it's what we're going to help you with.
2:35:04The solution, after thinking deeply on
2:35:05things, here's what we've come up with.
2:35:07Number one, cold outbound lead genen.
2:35:09We'll put in place a robust cold email
2:35:10based system for you based on best
2:35:12practices. Let me just change that for
2:35:14you using best practices. Client
2:35:16reactivation system will build a simple
2:35:17but high ROI reactivation system to let
2:35:19you extract value from pre-existing
2:35:20clients. Best-in-class sales training
2:35:22will train your team with world-class
2:35:23setting and closing mechanisms. This is
2:35:25pretty similar, honestly, to a proposal
2:35:27that I would send when I'm selling cold
2:35:28email. Obviously, I do it in Panda
2:35:30because I can collect payment. But yeah,
2:35:31I'm not going to touch on everything for
2:35:33you. Just note that there's a scope
2:35:34section where we discuss specifically
2:35:36what the client's going to get. There's
2:35:37a timeline section over here where they
2:35:38could actually see the progress of the
2:35:40project. These are all going to be AI
2:35:41generated. And there's even like a
2:35:43little cost section over here as well as
2:35:44like a little thank you page and, you
2:35:46know, next steps, instructions,
2:35:47kickoffs, and so on so forth. So, what
2:35:49if I told you um by the end of this
2:35:50video, we'll be able to generate this
2:35:51whole system in like 5 seconds. We'll
2:35:53fill out a quick form. Form's going to
2:35:55include, you know, maybe 30 seconds of
2:35:56questions, a couple bullet points, then
2:35:58at the end of it, we're going to have
2:35:59this whole thing basically good to go.
2:36:00The value here is you could literally
2:36:02whip up a proposal while you're on the
2:36:04phone with somebody. And before you're
2:36:06even done the call, you can send them
2:36:07the proposal. It'll look
2:36:09extraordinarily smooth and sleek and
2:36:12really high-end. And this is just, you
2:36:13know, it's it's a great closing
2:36:14mechanism, but moreover, it's just a
2:36:16great way to learn an 8N, I'd say. So
2:36:18this is what it looks like actually
2:36:19instantiated. This is what it looks like
2:36:21when we don't. As you see, I've used a
2:36:22bunch of variables here like proposal
2:36:24title, description name, one paragraph
2:36:26problem summary, solution heading one,
2:36:28solution heading two, solution heading
2:36:29three, short scope title one, short
2:36:32scope title 2, short scope title 3.
2:36:34Basically, what we're going to have to
2:36:35do is we're going to have to replace all
2:36:36these. Okay? And I just realized this is
2:36:382024, uh, I don't know, 2014 here. I'm
2:36:40just going to go 2025 for simplicity.
2:36:42But, you know, we're basically just
2:36:43going to have to replace everything
2:36:44within these little double brackets. And
2:36:45I'm using double brackets here cuz these
2:36:47are pretty unique, right? This is that
2:36:48Google Slides node from a moment ago. If
2:36:50we wanted to replace text in one of
2:36:52these, what's the likelihood we'd run
2:36:53into what's called a collision where
2:36:55we're replacing text in a variable that
2:36:57we didn't want? Pretty dang low, right?
2:36:59Okay, so here's the example proposal.
2:37:00This is what I'm going to be using. And
2:37:01let me just change the name to make it
2:37:03even more immediately obvious. Let's
2:37:05call it example proposal template. And
2:37:06let me just zoom out here and make sure
2:37:08we're on the same page. What I'm going
2:37:09to do is I'm going to just call this
2:37:11replace text. And you can see it's
2:37:14already called replace text. But I
2:37:15personally like to do this whenever I
2:37:17add a new module whenever I'm actually
2:37:19doing a live build because it reminds me
2:37:20okay like what is the flow? What is the
2:37:22sequence here? Otherwise I end up with
2:37:2430 or 40 nodes I should say. That's the
2:37:26terminology and then you know like it's
2:37:29Google slides one, Google slides 2,
2:37:30Google slides 3. It just gets really
2:37:32annoying and complicated. So the first
2:37:34thing we got to do is we got to connect
2:37:35our Google Slides account. So I'm going
2:37:36to head over to create new credential.
2:37:37It's going to open up OOTH redirect URL
2:37:39in my case because I'm using the cloud
2:37:41hosted offering of Naden. But if you're
2:37:43unsure of how to do this, just open the
2:37:45docs. They're going to open a page over
2:37:46here and then go down to slides. Just
2:37:49command F finding it. Basically, what
2:37:52you have to do is you have to create a
2:37:54Google Cloud Console account. Go to API
2:37:56and services library and then you have
2:37:58to copy and paste like a like a like a
2:38:00scope code or something. So, I'm just
2:38:02going to go over to my other email
2:38:05address over here. And basically, in
2:38:08order to do this, I actually need to go
2:38:09and I need to create a new project. I'm
2:38:10going to create a new project here. I'm
2:38:12going to call this NAN. Let's just call
2:38:14it YouTube. I'll create. And as you can
2:38:17see, I already have some OOTH 2 client
2:38:19IDs for my new project. What I'm going
2:38:20to have to do is I'm going to have to
2:38:21create new credentials. I believe it's a
2:38:23web application at least as of the time
2:38:25of this writing. Call it NN for YouTube.
2:38:29What we're going to have to do is you
2:38:30see where it says authorized redirect
2:38:31URIs and stuff. We're going to have to
2:38:33fill that in with information from NAN.
2:38:35So you see it says OOTH redirect URL. So
2:38:38we're going to go down here and then
2:38:39I'll go authorized redirect URIs. Paste
2:38:41that in. And then we got to click on
2:38:42that button. Okay, great. So now we have
2:38:45OOTH uh NN for YouTube, I should say. So
2:38:48what do we have here? We have a client
2:38:49ID. We have a client secret. So I'm
2:38:50going to copy this. I'm going go back
2:38:52and then paste it where it says client
2:38:54ID. Then client secret. I'm going to
2:38:56copy that. paste it where it says client
2:38:58secret. Now it'll ask me to sign in with
2:39:00Google. So I'm just going to open up a
2:39:02new little tab here. We'll allow NAN to
2:39:05do all this fun
2:39:07stuff. And the window can now be closed.
2:39:09Beautiful. We are now connected. I'm
2:39:11just going to change this to YouTube so
2:39:13that I know later when I'm building,
2:39:14hey, this is a this is a YouTube
2:39:16credential. And voila, we are now
2:39:18connected. We're basically good to go.
2:39:19So the next step is we need to feed in
2:39:20what's called the presentation ID. The
2:39:22presentation ID in Google Slides is
2:39:24always just going to be this long string
2:39:25after back slash D slash and then before
2:39:28slashedit. So I'm just going to double
2:39:30click on this, copy it, then paste it in
2:39:32here. Okay, now I just want to test
2:39:35anytime I'm building a new flow, right?
2:39:37Just thinking out loud here. I always
2:39:39want to test and make sure that the node
2:39:41that I am operating on does what I
2:39:43expect it to do. So I expect this node
2:39:45to replace some text. But why don't I
2:39:47why don't I actually be sure? There's a
2:39:49match case button, page names or ids
2:39:51button, replace text button. I don't
2:39:53actually know how any of this works
2:39:54hypothetically. So, why don't I just try
2:39:56feeding in one of these variables.
2:39:58Clicking on this button and then uh I
2:40:00don't know, replacing it with
2:40:01something. Let's click test
2:40:04step. And it looks like something
2:40:06happened. If I go back to my example
2:40:07proposal, you did I change anything? No,
2:40:10it doesn't look like it. So, uh you know
2:40:12what what happened here basically? Well,
2:40:14clearly there's some sort of gap between
2:40:16what I want to do and then what
2:40:17ultimately ended up occurring. So, let
2:40:19me refresh this puppy. Um, I don't
2:40:23actually know why that didn't happen.
2:40:24So, I'm actually going to do a little
2:40:25bit of debugging right now. Uh, this
2:40:27should just say hey. Oh, actually, oh,
2:40:30my bad. I've actually mixed these two
2:40:31up. Replace text should go over here.
2:40:34And then this should be hey. Okay,
2:40:35great. Let's test this step. Let's head
2:40:38back over here. Okay. Well, voila. Looks
2:40:40like I figured out the problem. Um, as
2:40:43you guys could see, you know, any buddy
2:40:45that tries to build things on a no code
2:40:47tool will inevitably run into issues.
2:40:48What's important is that you uh I don't
2:40:51know, you you maintain a good attitude.
2:40:53So, it seems pretty simple. We have like
2:40:55a pretty good pattern here. All I'm
2:40:56going to be doing is I'm going to be
2:40:57pasting in the variables and then I'm
2:40:58going to be replacing the text, right?
2:41:00Cool. So, I've sort of verified now that
2:41:02the main function of my flow, which is
2:41:03the text replacement, that works. So, in
2:41:06my head now, I'm like, okay, let's
2:41:07actually work backward. Now that I've
2:41:08verified I can do the thing at the end,
2:41:09which is the important thing. I can like
2:41:11create a template. Logically, the next
2:41:13thing I do working backwards is I have
2:41:14to generate all of the AI stuff, right?
2:41:16So, that's sort of what I'm going to do
2:41:18in the middle section. So, what I'm
2:41:19going to do first is I'm going to look
2:41:20up uh open AI and then the specific node
2:41:24I'm going to want is just the message a
2:41:28model under text actions. Now, under
2:41:30credential, if you haven't connected a
2:41:31credential before, you have to click
2:41:32create new credential. Then, you have to
2:41:34go over to open AI's um API. You need to
2:41:39create an account if you haven't already
2:41:40done so. But you're going to have to go
2:41:41over to your OpenAI account, create an
2:41:43account, open your API keys page, create
2:41:46a new secret key, and you're going to
2:41:48have to add two things. You're going to
2:41:50have to add what's called a
2:41:52uh well, we're going to have to add a
2:41:53name. So, I already have YouTube, but
2:41:55I'm just going to go YouTube nad and
2:41:57we'll just go Feb 4. It's important for
2:41:59me to show you guys how to actually
2:42:00create these keys, right? And then we
2:42:02just copy this. We head over here back
2:42:05to API key. Paste that in. And you don't
2:42:07need to paste in the organization I ad
2:42:08anymore. You you used to have to, but
2:42:10you no longer have to. Just going to
2:42:12call this YouTube Feb 4. Save
2:42:14that. And then voila. We now have our
2:42:17second connection. Open it. The resource
2:42:19we're going to be asking for is text.
2:42:20Operation is going to be message model.
2:42:22The model we're going to have to choose.
2:42:23My recommendation for you is at the time
2:42:24of this recording would be GPT40. Um
2:42:27February the 4th, 2025. This just
2:42:29happens to be like the best combination
2:42:31of cost effectiveness and then quality.
2:42:33If you use something dumber than this, I
2:42:34find the quality of the writing will not
2:42:35be as anywhere near as good. Okay, now
2:42:38let's just kind of take a couple steps
2:42:39back here. Um, what I wanted to do is I
2:42:41wanted to do basically this, but
2:42:44obviously we're going to have to like,
2:42:45you know, we're going to have to feed it
2:42:46some information how to do this, right?
2:42:48So, keep in mind I haven't actually
2:42:50created the form that I'm going to be
2:42:51filling out yet, but I want it to be
2:42:53able to generate a bunch of this this
2:42:55text. I want it to do so with like my
2:42:57tone of voice and so on and so forth.
2:42:58You know, logically, the simplest way
2:43:01that I can get it to produce the stuff
2:43:02that I want it to is by giving it an
2:43:04example of me producing exactly what it
2:43:06is that I want it to. And because I had
2:43:08the foresight to actually write out a
2:43:10flow proposal, I actually have all of
2:43:11the data that I want in order to train
2:43:13this model or, you know, in context
2:43:15train it's called. Um, which is where
2:43:16you just provide a bunch of examples to
2:43:18it. Okay. So, basically what I'm going
2:43:20to do is I'm going to use I'm going to
2:43:22have it output stuff in JSON. I'm going
2:43:23to use this as the variable name and
2:43:25then I'll just use this as the value in
2:43:26a training run and then I'll just ask it
2:43:28to do it again. And uh yeah, we're going
2:43:30to build the prompt that way uh pretty
2:43:32intelligently. And then at the end, you
2:43:33know, instead of it being super variable
2:43:35and like I don't know, having its own
2:43:37opinions on stuff and answering us with
2:43:39like I'd love to help you, it's not
2:43:40going to be like an agent per se. What
2:43:43this model is going to be is it's going
2:43:44to be almost like an API endpoint that
2:43:46we call or some service that we request
2:43:49and it's just going to send us back a
2:43:50beautifully formatted proposal or the
2:43:52data for a beautifully formatted
2:43:53proposal. So let me show you guys how to
2:43:55actually do that in practice. Um first
2:43:57thing we're going to want to do is we're
2:43:58going to want to create a system prompt.
2:43:59So I'll say you are a helpful
2:44:01intelligent writing assistant. This is
2:44:03just how the the model identifies for
2:44:04the most part. I'm going to want to
2:44:06output the content as JSON and click add
2:44:08message. And next up we're going to want
2:44:10to add a user prompt. Now, the user
2:44:12prompt is basically we just say, "Hey,
2:44:14here's what I want you to do." Okay? And
2:44:17that's all that the first user prompt
2:44:19does. What we do after is we add a
2:44:21second user prompt where we actually
2:44:22give it an example of one input. Then we
2:44:24have an assistant prompt come and give
2:44:26us an example of one output. And then
2:44:28finally, we actually feed it in our real
2:44:30live data and we actually ask it to like
2:44:32create something for us. So, let me show
2:44:34you guys what this looks like in
2:44:35practice. I haven't pre-written this or
2:44:37anything. I'm just going to show you
2:44:38exactly how I would write it if I were
2:44:39in the situation. And the first thing I
2:44:40want to do is I just want to give it the
2:44:42instructions. So your task is to
2:44:43generate a
2:44:46proposal using input data from a form.
2:44:49This proposal should be highly
2:44:52customized to the
2:44:55prospect considering we're going to be
2:44:58sending
2:45:01prospects. We go highly customized,
2:45:04specific, and high quality. Considering
2:45:06we're going to be sending it immediately
2:45:09after you are done, the proposal
2:45:12template we're using has many fields.
2:45:15You must return these fields in one JSON
2:45:20object. Use this format. Okay. Now, I'm
2:45:23going to give it a big list of all of
2:45:25the fields that I want. So, the first
2:45:26one is proposal title. So, let's go back
2:45:28here. Let's go proposal.
2:45:31Oops. We'll go proposal title.
2:45:36The next one up is going to be a
2:45:38description name. So I'll go description
2:45:41name. And again, this is exactly what I
2:45:43would do if I were actually building
2:45:44this out. The next would be one
2:45:46paragraph problem summary. One paragraph
2:45:49problem summary. Solution heading two,
2:45:52we go like this. Solution description
2:45:53two, we go like this. And we'll also do
2:45:55milestone description one. So milestone
2:45:57description one. Okay. So we now have
2:46:00all of the fields in our JSON template.
2:46:02Beautiful. We've given it quite a lot.
2:46:05So, just to make my life a little bit
2:46:06simpler, I'm just going to go over to
2:46:08jasonformmatterater.org, paste this in,
2:46:10format this. This way, it's just going
2:46:11to be a lot easier for me to keep track
2:46:12of. And then paste it like with this
2:46:14nice new line format here. The value in
2:46:17this is now um I don't know, it just
2:46:18it's it's a lot simpler for me to see at
2:46:20a glance. It's a lot more maintainable.
2:46:22Um and and yeah, the next thing I'm
2:46:24always doing or I started always doing
2:46:26about six months ago is I started just
2:46:28providing it a list of rules. So, use a
2:46:30Spartan casual tone of voice.
2:46:33I will say
2:46:36um yeah, I mean that's pretty much
2:46:38it. Use a Spartan casual tone of voice.
2:46:42Be to the
2:46:44point and professional, but professional
2:46:47you're
2:46:49writing. Assume you're writing to a
2:46:53sophisticated audience. There we go.
2:46:56Okay, great. So, this is these are going
2:46:58to be my instructions. Your task is to
2:46:59generate a proposal using input data
2:47:01from a form. This proposal should be
2:47:02highly customized, specific, and high
2:47:04quality. Considering we're going to be
2:47:05sending it immediately after you're
2:47:06done. Proposal template we're using is
2:47:08many fields. You must return these
2:47:09fields in one JS object. Use this
2:47:12format. This looks very clean. Oh, you
2:47:16I'm finally going to say ensure that all
2:47:18fields are filled out. Do not miss a
2:47:22field or leave
2:47:24any variables empty. Cool. So, that is
2:47:28our main user prompt. What we're going
2:47:30to do now is we're going to feed in an
2:47:31example of the form data and then feed
2:47:33in an example of the output. So I'm
2:47:35actually lucky I already have an example
2:47:37of the output. If you think about it,
2:47:39the output
2:47:40is over
2:47:44here. And then I just need to go back
2:47:46in. I need to copy and paste all the
2:47:48output from the real proposal. So I'm
2:47:50just going to do that really quickly.
2:47:51Okay, just gave it a quick example of
2:47:53all of the data from that finished
2:47:55product. And now we just have to kind of
2:47:56think a little bit and figure out what
2:47:58sort of fields we want on our form. Uh
2:48:00because the way that this is going to
2:48:02work is we're going to trigger this
2:48:03based off of a form um input, right? I'm
2:48:06just going to use an NAND form for now,
2:48:08but you can use really any form that has
2:48:09a web hook. But if you think about it,
2:48:11like in order to get this information,
2:48:12in order to you know um and I'm always
2:48:14starting with the end result here. I
2:48:15always start with the form and I figure
2:48:16out exactly what information, sorry, I
2:48:18always start with the proposal and I
2:48:19figure out what information I need. I'm
2:48:21moving backwards from that because I
2:48:23care more about what the customer sees
2:48:24than anything else. That's what a lot of
2:48:25people I think sort of mess up. They
2:48:28start with like the data they think
2:48:29would be nice to have and they're like,
2:48:30"Okay, what can I do with this data?"
2:48:32It's like, "No, no, don't do that. Start
2:48:34with the end product, the thing that
2:48:35like you know is going to make a
2:48:36customer want to buy from you and then
2:48:37work your way backward from that and
2:48:38then ask yourself, okay, what do I need
2:48:39to ask the customer?" So, uh, here's
2:48:42some things that I need to ask the
2:48:43customer. Obviously, I need another
2:48:44company name, right? Like, duh. So, I'm
2:48:46going to go company name. Let me see
2:48:50what other information do we need. we
2:48:51need like a project description, but
2:48:53probably the simplest way to do it is
2:48:55with a problem and then a
2:48:58solution. So, what I'm actually going to
2:49:00do is I'm going to have the form have
2:49:03like a problem statement where basically
2:49:04it's like, "Hey, so what's the problem
2:49:05they're suffering from?" "Hey, so what
2:49:06are the solutions you're going to
2:49:07pitch?" And then we'll just go bullet
2:49:09points. Cold email lead genen client
2:49:10reactivation system, best-in-class sales
2:49:12training,
2:49:13easy. Okay? Like, what sort of like line
2:49:15item scope are we talking?
2:49:19and then you know like how soon
2:49:22basically and then it's just going to
2:49:24take the date and then work this out and
2:49:26then we'll also have like a little cost
2:49:28and I'll just use cost as like a string
2:49:29for now but you know feel free to do it
2:49:31as a number if you have some formatting
2:49:32requirements so this is the data that
2:49:34we're going to be feeding in with the
2:49:34form input okay so we're going to be
2:49:36feeding the company name problem the
2:49:37solution the scope how soon and the cost
2:49:40so the example as we see let's just go
2:49:42deposit cost and we can just multiply
2:49:43that by two to get the total cost we'll
2:49:45go 15 that multiplied by two is what
2:49:483,69 90 something like that. How soon?
2:49:50Well, let's see. What did I put as my
2:49:52example here for my training? Uh,
2:49:53February the 8th to April the 1st, 2025.
2:49:56So, it's two months. Okay. So, we'll go
2:49:58two months. And I'm going to write in
2:50:00lowercase and I'm not going to use
2:50:02formatting and be very dumb and simple
2:50:03because I want to mirror what I think I
2:50:06and the sales team that is going to be
2:50:07using this form is going to use. What's
2:50:10the scope? I'll show you exactly how I
2:50:11do this.
2:50:131k per day cold
2:50:15email
2:50:18infra, 30k
2:50:21leads, and then four
2:50:24weekly Zoom sessions for sales training.
2:50:28That's what they're going to get. As I'm
2:50:30sure you guys can imagine, this is
2:50:31totally something that you could just
2:50:33really quickly scribble as notes during
2:50:35a call, right? Prospect says something,
2:50:37you're like, "Okay, yeah, we're going to
2:50:38get this done." And you know, I mean,
2:50:40the how long did this take to do? This
2:50:41is like what 50 characters or something
2:50:43like that. You could realistically type
2:50:44that in like 10 seconds while you're
2:50:46talking to the customer. Um from there,
2:50:49let's think about the solution. So
2:50:50solution uh cold email legion
2:50:55system, client reactivation
2:50:58system, and best-in-class sales training
2:51:02for closing. And then the problem they
2:51:04suffer
2:51:06from, they can't generate leads.
2:51:08Everything is referral-based right now.
2:51:10Cool. done. So, this is the input that
2:51:13I'm going to be feeding in the model.
2:51:15And then I'm going to say, hey, if I
2:51:16were to feed you in an input like this,
2:51:18I want you to feed me an output that
2:51:19looks kind of like this. Okay, now that
2:51:21we have that relationship in place, what
2:51:23that means is I can feed in an an actual
2:51:26like real um piece of data. And I'll
2:51:29fill all these variables in later. Um,
2:51:31but uh well, I guess I'm going to fill
2:51:33them in right now. I'll fill them in
2:51:35right now with like an example uh that's
2:51:37a little bit different. So instead of
2:51:38they can't generate leads, let's say
2:51:40they're struggling making YouTube
2:51:43videos, everything is
2:51:45really time inensive right now, mostly
2:51:48because they don't have scripts
2:51:51solution. Let's do like AI script
2:51:54system.
2:51:56AI script writing system scrapes um
2:52:02competitor YouTube vids for ideas and
2:52:04rephrases best performing
2:52:07titles then writes
2:52:10outlines the scope um we're going to get
2:52:14a form you can fill out to
2:52:17generate form you can fill out with
2:52:19competitors that adds them to a
2:52:23DB once per day DB is scraped
2:52:27And you get um however many people are
2:52:31in the
2:52:32sheet times however many people posted
2:52:37videos worth of
2:52:42outlines. Max, let's just say max uh 200
2:52:45per
2:52:48month. How soon? Let's say two weeks.
2:52:51And let me make the deposit cost
2:52:54$3,525. Okay, so now I have everything
2:52:57that I need to actually test this out on
2:52:59my little example here. And I'll, you
2:53:00know, I'm just using this as a training
2:53:02example, but let's run this through and
2:53:04let's see what
2:53:06happens. So, this is pretty intensive.
2:53:09You know, we got a lot of variables
2:53:10here. We want to make sure it doesn't
2:53:11screw up. So, it's going to take its
2:53:12sweet ass time for
2:53:14sure. You could also do things like um
2:53:17add uh frequency penalties, presence
2:53:19penalties, and so on and so forth if you
2:53:21wanted to be a little clearer about
2:53:22what's going on. But basically, I'm
2:53:24going to take all the variables from
2:53:25here and I'm just going to feed them
2:53:26into our Google Slide. There's one more
2:53:29thing that I believe we're going to have
2:53:30to do. If you think about it, like this
2:53:32Google Slide here, when I um ran it the
2:53:35first time, I replace proposal title
2:53:36with the word hey, right? So, we can't
2:53:38actually do that because this is like
2:53:40one proposal template. So,
2:53:41realistically, before we do this, we're
2:53:43actually going to have to generate a new
2:53:44proposal template every time. Um, but
2:53:46that's uh probably pretty easy to do.
2:53:47We're going to walk through it together.
2:53:48Okay, great. So, we just got the
2:53:50execution. Let's jump through and let's
2:53:51see what's going on. Just going to move
2:53:53over to JSON view because it's a lot
2:53:55easier for me just to make sure that we
2:53:56have everything formatted correctly.
2:53:58Looks good. We do have all the
2:53:59variables. YouTube content efficient
2:54:01efficiency boost for left click. So, one
2:54:03thing that I'm seeing here is just
2:54:05um yeah, we're going to need to provide
2:54:07it some information that we are a system
2:54:10basically context. We are an automation
2:54:13no code agency that develops
2:54:18uh that
2:54:19develops systems
2:54:23revolving around growth revenue ops UTC.
2:54:26There you go. That'll make it a little
2:54:27bit simpler and probably a little bit
2:54:29more accurate for me. But okay, cool.
2:54:32This looks Oh, uh, one more thing is we
2:54:34need to feed in the current date, right?
2:54:35Because November the 20th, 2023, that
2:54:36doesn't really
2:54:37matter. Okay, so why don't we do that
2:54:39one more
2:54:41time? We'll go over here and we'll say
2:54:44um current date. There we go. cuz you
2:54:48know how soon 2 months like that doesn't
2:54:50really provide any context on its own.
2:54:53So I'm just going to go Feb 4 2025. Then
2:54:56we'll go 2 months. Then over here we're
2:55:00same thing. We're going to say current
2:55:02date for 2025. How soon? 2 weeks.
2:55:05Deposit cost $3,525. This should fix the
2:55:07milestone stuff. Let's test it out. I
2:55:10hope you guys see the value in me doing
2:55:12this live. Um this is very much more
2:55:14similar to what your actual build
2:55:15process would be like. like you're not
2:55:17going to get all this in one shot,
2:55:18right? It's not like you're going to
2:55:19know, hm, I guess I'm going to have
2:55:20these fields. You're going to map it out
2:55:22perfectly, send it, and see the results.
2:55:24Realistically, you're going to have like
2:55:25back and forth where you you test the
2:55:26output and you're like, that's kind of
2:55:28missing this context. I don't really
2:55:29know about that. Um, and then, you know,
2:55:31go go go back and forth in that
2:55:33way. Okay, great. Yeah, it looks pretty
2:55:35solid to me. Um, I'm not seeing any
2:55:37major issues here. So, uh, you know, I
2:55:39could just feed this forward. Like, we
2:55:40could just pin this output and I could
2:55:42just feed this forward into the replace
2:55:44node, right? But if you think about it,
2:55:46if I do that, I'm actually going to be
2:55:47replacing this. So, I don't actually
2:55:48want to do that. Like, I don't want to
2:55:49replace the main template. What I want
2:55:51to do is I want to replace a copy of the
2:55:52template. So, logically, we should copy
2:55:54this. Um, I don't see I didn't I didn't
2:55:58see anything in Google Slides where we
2:55:59could just like generate a new one. So,
2:56:02I imagine we'll probably be able to do
2:56:04this with Google Drive instead. Yeah.
2:56:06With a copy a file tool. So, I'm going
2:56:08to do the copy a file tool and I'm
2:56:09actually going to copy the proposal,
2:56:11duplicate it, and then I'm going to
2:56:12update the the the new copy instead of
2:56:15the old one. So, in order to connect to
2:56:17this, you have to create a new
2:56:18credential. Then, you're just going to
2:56:19have to go through the same flow that we
2:56:20did before where you go into your Google
2:56:22Cl console cloud account, you create a
2:56:23new account, um you you add a credential
2:56:26for NADN, then you have a client ID
2:56:28client secret, and you got to put in the
2:56:29redirect URL there. I already have one,
2:56:31so I'm just going to exit out of that
2:56:32and just use my own Google Drive
2:56:33account. What I'm going to want to do is
2:56:35I'm going to want to um resource file
2:56:37operation copy. And if you think about
2:56:38it, what I want is I just want that I
2:56:40want that proposal template, right? So I
2:56:42could select it manually or I could just
2:56:44copy in the ID and that's what I prefer
2:56:46to do. Just a little bit easier. Okay,
2:56:50great. And then the file name. Um I'm
2:56:51just going to feed in the proposal title
2:56:53as the file name. And for now, we'll
2:56:55just copy this in the same folder. Let
2:56:57me see if there are any cool um options.
2:56:59Copies. Copy requires writer permission.
2:57:03That's pretty interesting. Uh I don't
2:57:05think I'm going to do that. No, I just
2:57:06want them to have all of it. Then I'm
2:57:08going to test this. So we've just
2:57:10created a new system which looks like uh
2:57:12it's sorry a new proposal called
2:57:13automated YouTube script system for left
2:57:14click. Nice. Um so what I'm going to do
2:57:16here is I'm actually just going to pin
2:57:17this. Then I'm going to replace the
2:57:19text, but I'm going to do so using the
2:57:22ID from that. So that's my presentation
2:57:25ID. Now I should be replacing the new
2:57:26one. And if you think about it, um what
2:57:28we just did is now we have a new ID. So
2:57:30I can actually go and this is going to
2:57:32be my main example proposal template,
2:57:34right? So let me just actually paste in
2:57:36the ID of the new one that we just
2:57:37generated. And as you can see, it's just
2:57:39a it's a duplicate of the same one. The
2:57:41only difference is we have um automated
2:57:43YouTube script system for left click
2:57:45written up here. Okay. So now I'm just
2:57:47going to go back here and all I have to
2:57:49do is I basically just have to go
2:57:50through um and then enumerate across the
2:57:54variable names like this um and then
2:57:56replace them with the text from this
2:57:58open AI node. So, like a quick example
2:58:00of what I'll be doing is I'll be going
2:58:02proposal title and then I'll just be
2:58:03feeding in um you know, proposal title
2:58:05here, right? Not exactly rocket science.
2:58:08Um but, you know, it's going to be a
2:58:09little bit annoying cuz we got to go
2:58:10through and do this a bunch of times.
2:58:12Okay. And then for now, I'm just going
2:58:13to feed in um cost and I'll just make it
2:58:151850 hypothetically because we've stored
2:58:19we've hardcoded some variables in there
2:58:20earlier. Um but yeah, I just finished
2:58:22mapping all them. We should be good to
2:58:23go. I'm going to click test step. We're
2:58:24going to see what happens. We have a
2:58:27bunch of occurrences changed. one. The
2:58:29only difference is this last one which
2:58:30was cost says two. That seems reasonable
2:58:32to me. Uh and where would be? We we be
2:58:35right over here. Okay. So, automated
2:58:37YouTube script system for left click
2:58:39streamline YouTube content production
2:58:40with AI powered script writing. That
2:58:41looks reasonable. I don't really like
2:58:42that this is all like capital case
2:58:44though to be honest. So, probably going
2:58:45to tell the model not to do
2:58:47that. That looks good. Um these are
2:58:50looking a little too long. So, I'm just
2:58:51going to uh like go in and I'll tell it
2:58:54that the description should be shorter.
2:58:55So, you know, aim for like two lines or
2:58:57something. Actually, hold on a second. I
2:59:00think I might have Did I change the size
2:59:01of these? I feel like I changed the size
2:59:03of
2:59:04these. You know, I might have just used
2:59:06a slightly larger size for the template
2:59:09um to beh for for this to be honest. I
2:59:11don't know. I'll have to double check.
2:59:13Um okay, let's go back here. Let's see
2:59:15what's going on. So, this looks good.
2:59:16This one looks a little long, so I'm
2:59:17just going to have to make sure it
2:59:18writes shorter. That's fine. You know,
2:59:20it was about 2 weeks. Total turnaround
2:59:22times 10 days, right? That's fine. 1850
2:59:25today, 1850 when it's finished. Got the
2:59:27thank you. Okay, awesome. So, of this
2:59:29whole thing, the only two things I
2:59:30didn't really like now that I'm I'm
2:59:31testing this and seeing it are I'm down
2:59:33here bottom rightand corner, it just had
2:59:35a bunch of capital case um words. So,
2:59:38streamline YouTube content production. I
2:59:40don't want this to be a title. I just
2:59:41want this to be like a description,
2:59:43right? And then over here, it's just a
2:59:44little bit too long. Uh there probably
2:59:46ways that we could like dynamically
2:59:48change this. There might be like a way
2:59:49to like automatically resize the the
2:59:52thing like ourselves instead of um
2:59:54having
2:59:55this having to sort of like do it
2:59:57manually. That's fine. I don't really
2:59:59care too much about that. We could also
3:00:00like reduce the size of all these
3:00:02elements and reduce the line height and
3:00:03stuff just for safety. So, you know, I
3:00:05mean, this is more proposal template
3:00:07stuff, but I'm just going to do it um
3:00:08just in case. When we go down to 10
3:00:11here, we'll go 10 here. We'll go 10
3:00:14here.
3:00:16You know, I'm not like a designer or
3:00:18anything, so I'm sure designer
3:00:20uh a designer would have yelled at me by
3:00:22now. Why would you change that to size
3:00:2410? How dare you? I think it still looks
3:00:27pretty good. Um, and then I'm going to
3:00:29go back over to our model and then, you
3:00:32know, just as like an input, I'm going
3:00:33to make it a little bit shorter.
3:00:36rule. I'll say if a field is a
3:00:42description field contains the
3:00:45term description, it should be no more
3:00:49than two lines.
3:00:51Cool. That looks uh well, I mean, how's
3:00:54it going to conceptualize a line, right?
3:00:55Let's see how many words was
3:00:57this. I'm going to go word
3:01:02counter. This was 91. Uh, sorry, 14
3:01:05words. So maybe we'll go
3:01:07like no more than 10 words. If we go 10
3:01:10words each,
3:01:12then I guess if I make them smaller,
3:01:15like that's fine. Maybe we'll go no more
3:01:17than 14 words. That's quite the
3:01:20constraint. Okay, cool. Uh so just
3:01:23because we've run this like we've we've
3:01:25copied the file, but it's a different
3:01:27file now, like I'm going to want to copy
3:01:28it again. So I'm going to unpin this
3:01:29data. I'm just going to test the step.
3:01:31We're now going to copy it to a new
3:01:33duplicate. Now, that's been copied over
3:01:35as a new duplicate. Um, oh, you know
3:01:37what? There's one more thing I got to
3:01:38do, right? I got to change the uh scope
3:01:40so it doesn't include the
3:01:43um you know, if it is a description
3:01:48name, do not use
3:01:51capital. Uh do not use title
3:01:54case. Okay, cool. So now that now that
3:01:57we have that uh we should be able to you
3:01:59know like assuming that we fixed that um
3:02:02we've now copied it. We can pin this as
3:02:03an output. We are going to be using the
3:02:06old open output but that's okay. We're
3:02:09mapping this now. So I'm just going to
3:02:11copy this over use that to open up my
3:02:14second example which going to be right
3:02:16over
3:02:17here. And then I'm going to test this.
3:02:21It's going to go in and replace
3:02:22everything.
3:02:25Let me just see if it looks a little
3:02:26better with the smaller text. It does.
3:02:28Beautiful. So, actually, this is this is
3:02:29fine. We actually didn't need to shorten
3:02:30it at all um now that the text is
3:02:32smaller, which is good. And yeah. Yeah,
3:02:34we're basically good to go on that
3:02:36front. Um I'll leave it there for now.
3:02:38Uh so, the question is, you know, where
3:02:40do we go from here? Well, my
3:02:41recommendation to you guys is uh this is
3:02:43this is a free option. So, I'm going to
3:02:44show you guys how to basically do
3:02:45everything I just did except in Panadoc
3:02:47instead and include like a payment
3:02:48module. But my recommendation at this
3:02:50point is if you guys want to stick with
3:02:51the free option, then just send them an
3:02:53email and have a link over to the uh
3:02:55proposal and then you know in your email
3:02:57just ask them if they want to pay um or
3:03:00you know maybe even be prevent uh pre
3:03:02proactive actually send them an invoice
3:03:04along with the proposal. If they have
3:03:05their thumbs up and they're ready to
3:03:06move forward then just send them an
3:03:08invoice on your invoice. Maybe you have
3:03:09some like little legal ease by uh paying
3:03:12this thing. You accept our terms and
3:03:13conditions. Terms and conditions goes to
3:03:14some page in your website that just has
3:03:16like some very very basic stuff. uh you
3:03:18know, I've never really been super
3:03:19worried about agreements and so on and
3:03:21so forth. So, uh like personally, I
3:03:23probably wouldn't. And the best news is
3:03:24we can do that together. So, I'm
3:03:25actually going to show you what that
3:03:26would look like or how I would build it
3:03:27out if I were working for my own company
3:03:30or a client. I just head over to the
3:03:32Gmail node. Um what I would do is you
3:03:34could send directly or you could draft.
3:03:35Like, feel free to do either. Um I'm
3:03:37just going to send for simplicity.
3:03:39You're going to have to connect yourself
3:03:40a credential. Same idea as before. I
3:03:42think Gmail's a little bit easier
3:03:43because you can just sign in. Um, but
3:03:45yeah, you just click sign in with Google
3:03:46if you're on the cloud console account.
3:03:49That'll automatically just connect to
3:03:50you. Sorry, I'm a little out of breath
3:03:51cuz I had to run downstairs in between
3:03:53cuts and grab my groceries. I'm just
3:03:55going to use Gmail account 3. And then
3:03:58uh, you know, if you think about it,
3:03:58like you also do need an email address
3:04:00in the form, right? So, I'm going to
3:04:02assume that this form input that we put
3:04:03together has an email address and we can
3:04:05fix it all up later. But for now, I'm
3:04:06just going to go uh
3:04:09nicholas@gmail.com. And then I'm just
3:04:11going to paste
3:04:13in reproposal 4. Then I'll just include
3:04:17the company name. Uh, which I
3:04:20think was just going to be leftclick.
3:04:24Yes. Then I'll say, hey, you know,
3:04:26whatever the first name is. So maybe
3:04:29we'll go Nick. I don't like how this is
3:04:30not multi-line. Can I make this
3:04:32multi-line? Yes. Um, hey
3:04:36Nick, thanks for the great call
3:04:39earlier. I had a moment after our chat
3:04:43to put together a detailed
3:04:45proposal for you. Please take a look at
3:04:49your earliest convenience and let me
3:04:51know your
3:04:53thoughts. You can you'll find it here
3:04:56and then I can just put in like the
3:04:58link. Now, if you think about it, this
3:04:59link is always going to be formatted the
3:05:01same. It's just going to be this right
3:05:04here. And then we'll be feeding in the
3:05:07presentation ID right over here. So,
3:05:09what can we do? We can source the
3:05:11variable. And I'll just go JSON
3:05:13presentation ID. Now, we'll be filling
3:05:16it in like this. And then voila. You
3:05:17know, we have like the the link in the
3:05:19email. There are better ways to do this,
3:05:21of course. We could do HTML. If you have
3:05:23any questions, let me
3:05:26know. I've also sent over an invoice for
3:05:29the amount
3:05:31um just to keep things
3:05:35convenient. Thanks, Nick.
3:05:40Okay, I think I'm just going to leave it
3:05:42at that. Um, and then this is this is
3:05:45plain text, right? You can actually do
3:05:46HTML as well. If you do HTML, um, you'll
3:05:48actually be able to like add it as a
3:05:50link link in the email. I'm not going to
3:05:51do that. Um, just for simplicity, but
3:05:54yeah. Okay, let me just turn a pen and
3:05:56attribution off cuz you already know
3:05:58they're trying to sneak their marketing
3:06:00in here. Okay, and I'm going to go over
3:06:03to my personal email here and I see a
3:06:05link right right there. Hey Nick, thanks
3:06:07for the great call. I had a moment after
3:06:08I tried to put together a detailed
3:06:09proposal for you. Please take a look at
3:06:10your list convenience. Let me your
3:06:11thoughts. You'll find it here. If you
3:06:12have any questions, let me know. I've
3:06:13also sent over uh I guess I've said let
3:06:16me know twice. I've also sent over an
3:06:17invoice for the amount just to keep
3:06:18things convenient. Um docs, so let me
3:06:21just change the let me know invoice for
3:06:23the project just to keep things
3:06:24convenient. Can get started anytime
3:06:27that's sorted. Let's just go anytime
3:06:29that's sorted to make it abundantly
3:06:31clear. You got to pay. Cool. So you give
3:06:33it a click. What do you get? Voila. you
3:06:35get your customized proposal, right?
3:06:37Very clear, very clean, not at all
3:06:40complicated. Um, and you know, although
3:06:42the fact, you know, despite the fact
3:06:44that this doesn't really have like a way
3:06:45to sign, um, like you usually sign
3:06:47proposals, uh, it's free, 100% free,
3:06:49doesn't cost you a scent, and, uh, you
3:06:51still get like a very high quality
3:06:52impression on the client end, which is
3:06:54valuable. So, if I were just to run this
3:06:56whole thing from start to finish and
3:06:57just like kind of
3:06:58eliminate all of these pins just to show
3:07:01you guys how it would work. Imagine I
3:07:02just, you know, we just had a
3:07:03conversation or something. Um, I just
3:07:05click test
3:07:06workflow and, you know, I'll fill out
3:07:09the form in a sec. But now the Open AI
3:07:10model is like generating a bunch of
3:07:12text. Then the Google Drive is going to
3:07:14be copying it. We're going to be
3:07:15replacing it and then it's going to send
3:07:16over
3:07:17Gmail. If I just kind of back it up a
3:07:21bit and just refresh my inbox and
3:07:23actually just check these Walmart
3:07:26deliveries. Um voila, we have the same
3:07:28sort of email. Seems reasonably
3:07:30customized. And then as you see, you
3:07:32know, we have like the title, we have
3:07:33like the nicely fitting um uh sections
3:07:36here. Same over here. We got like the
3:07:39sexy timeline. We got the cost. Uh and
3:07:42you know, I click this in one button,
3:07:43right? Pretty simple, pretty
3:07:45straightforward. And this is good
3:07:46verification that this doesn't just work
3:07:47on like old data. This works on new
3:07:49data, too. Okay, great. So, let's just
3:07:51do let's do one thing before we move it
3:07:52over to Panadoc. Let's um let's add a
3:07:54form and then let's just replace all the
3:07:56data here with like actual live data
3:07:57with the form. And then we're also just
3:07:58going to want like a couple more pieces
3:07:59of information. We're going to need like
3:08:00an email address to send it to
3:08:01obviously. Uh and if there's anything
3:08:04else that comes up, I'll I'll deal with
3:08:05it. But yeah, we're just going to want
3:08:06to delete this trigger. And then what
3:08:08we're going to do is we're just going to
3:08:08go N8 form on new NAN form event. We're
3:08:11going to trigger the flow. So, let me
3:08:13connect this. What I want to do is um I
3:08:16want to actually go and I want to create
3:08:18um you know I want to create this whole
3:08:20thing. So what I usually call this I
3:08:21call this like a discovery call logging
3:08:23form or like a sale let's just go sales
3:08:25call logging
3:08:27form and this call logs a or sorry this
3:08:30form logs a sales call and automatically
3:08:34generates a
3:08:36proposal and now we can actually go
3:08:38through and just ask a bunch of
3:08:39questions. So um you know let's
3:08:42say prospect
3:08:46First name, we'll go last name. This is
3:08:49just useful information to have. Company
3:08:52name. Website. All useful information to
3:08:55have. Um, and let's actually get into
3:08:57what we were generating, right? If you
3:08:59think about it, we generated a problem.
3:09:01We generated a solution. These are both
3:09:02questions. So,
3:09:04problem, solution,
3:09:07uh, cost, and was there anything else?
3:09:10Let me check out the open AI node really
3:09:13quickly and check out the prompt.
3:09:14Company name, problem, solution, scope.
3:09:17There was a scope question. And then how
3:09:20soon? Okay, so we're going to go back
3:09:22here. We'll go scope. And then finally,
3:09:27we'll go how
3:09:29soon. I'm going to make them all
3:09:31required for simplicity because I don't
3:09:33want anybody on my team or somebody
3:09:35else's team to um have the possibility
3:09:38not to fill this information out. Like
3:09:39you should get the first name and the
3:09:41last name, the company name, and the
3:09:42website um you know at minimum. I don't
3:09:46see a URL text area thing here, which is
3:09:48unfortunate. That's okay though. Anyway,
3:09:50and then we're going to respond when the
3:09:52form is submitted. Um and then let me
3:09:54just check if there are any options we
3:09:55want. I want to take off the animated
3:09:57attribution obviously and then we should
3:09:59be good. Okay, great. So now if I click
3:10:01test step, what's going to happen? I'm
3:10:03actually going to go get a form that I
3:10:05can fill all this data out with. So for
3:10:07the purposes of this, I'm going to say
3:10:09Peter Sarif
3:10:12leftclick go left click I problem. I'm
3:10:15just actually going to go I'm going to
3:10:17paste in the problem statement that I
3:10:19hardcoded over
3:10:21here. So let's do this
3:10:24one. Paste in the problem. This should
3:10:26probably be a text area now that I'm
3:10:28thinking about, but it's okay. Paste in
3:10:30the problem. Paste in the solution.
3:10:33Paste in the cost of 3525,
3:10:36right? We should also paste in the
3:10:39scope. And I should readjust where the
3:10:41scope is just so that it's like a little
3:10:42simpler. Then how soon? I think it was
3:10:44two weeks, right? Okay, cool. So now I'm
3:10:46going to fill this out. We're now going
3:10:48to get all these events, right? So now
3:10:49we have access to this. And now we can
3:10:50just go down the the list. We could just
3:10:52you know replace these variables with
3:10:54um replace these this JSON I should say
3:10:57with the variables. So it was the
3:10:58company name right over here. Um problem
3:11:02statement was you know dollar sign JSON
3:11:06uh and it looks like we are now using
3:11:08brackets but you don't have to you could
3:11:10use uh whatever you want. So the problem
3:11:12statement here was just
3:11:14problem and oh this is company name
3:11:16because we split it right we had a space
3:11:18in between. That makes sense. Then we
3:11:20have a
3:11:22solution. We're going to have a
3:11:27scope. We're going to have a current
3:11:29date. That's just going to be
3:11:30automatically filled in with
3:11:33now. Uh we should also format that. Now
3:11:36that I'm thinking about it, let's just
3:11:38format it as
3:11:42uh for common formats till string may be
3:11:45easier. We might just go like toal
3:11:46string. I think we might have an error
3:11:47function in here. Is that why? No, I
3:11:50have no idea why. But anyway, um, now we
3:11:52get the current date. Same format. How
3:11:54soon was JSON how soon? Wonderful. And
3:11:58then the cost just going to be
3:12:02JSON.cost. Perfect. Cool. So, we've now
3:12:04mapped all the variables in, right? We
3:12:06have all the real variables, like actual
3:12:07live variables coming in with data. So
3:12:10now I can actually run a test step and
3:12:12it's it's going to go through it's going
3:12:13to generate all the data for me. Similar
3:12:14to how was doing before, but now it's
3:12:16being triggered off of a form input as
3:12:18opposed to just like my own whims and
3:12:19desires. And as amazing as my whims and
3:12:21desires are, ladies and gentlemen, form
3:12:23outputs are way better. Okay, cool. This
3:12:26is already mapping a variable. This is
3:12:28going to be fixed. So that makes sense.
3:12:30Replacing this text. This looks good to
3:12:33me. It says there's some error fetching
3:12:35options from Google Slides. That's just
3:12:36because the presentation ID isn't
3:12:37hardcoded. Then I'll have a Gmail. Let's
3:12:39just make sure this Gmail um actually
3:12:41uses the, you know, everything that I
3:12:44want it to use. So, let me actually just
3:12:46go through test everything up to and
3:12:47including
3:12:49this. So, it'll take the OpenAI text and
3:12:52then map it in here. I'm just going to
3:12:53pin this. Make my life a little bit
3:12:55easier. And then over here in Gmail, uh
3:12:57you know, I can just go down to on form
3:12:59submission and I can just grab the I did
3:13:01not ask for the email address, did I?
3:13:03That is so funny.
3:13:05Okay, so you're going to want to ask for
3:13:06the email address. Despite the fact I
3:13:08don't have an email address, I could
3:13:09still technically map this. I'm just
3:13:11going to go it is
3:13:12item.json email. I'll capitalize it as
3:13:15well. And then even though I don't have
3:13:17this, I know that it's going to work
3:13:19when I go over here and then I add a new
3:13:20field called, you know, email, right?
3:13:23Because it's just, you know, it's just
3:13:24code we're mapping at the end of the
3:13:26day. Uh like, you know, it's it's not
3:13:28necessarily going to work work until we
3:13:30fill out the form with the same output.
3:13:32But for now, we can
3:13:35um just modify this with uh email. We'll
3:13:39go Nick. Uh let's go
3:13:44Nicholas@gmail.com. There you go. I'm
3:13:45just going to save this. Make sure it's
3:13:46good. Jason
3:13:48good. We will pin that as well. I just
3:13:52like when I pin stuff, I like pinning
3:13:53everything. Sue me. Okay. And we're not
3:13:56going to have access to this right now,
3:13:57I don't believe. Uh if I test this, what
3:14:00happens?
3:14:02Yeah, we don't have access to this right
3:14:03now
3:14:05unfortunately. Even there's item.json
3:14:07email on the for Well, maybe we do
3:14:14actually. Maybe we do. No, it doesn't
3:14:17look like we do. I think we have to
3:14:18rerun the whole flow if we want it.
3:14:20Unfortunate, but is what it is. Um,
3:14:22cool. Uh, I'm just going to rerun this
3:14:24one more time, uh, just on my end. Make
3:14:26sure that everything checks out. But
3:14:27then from here on out, we're just going
3:14:28to add the we're going to swap this over
3:14:30to Panda for anybody interested in like
3:14:31leveling this up even more. And then
3:14:33we're going to call it a day. And as you
3:14:34can see, this is not a complicated flow.
3:14:35There's like 1 2 3 4 five realistically,
3:14:39maybe six if you count like the invoice
3:14:41step. There like six elements to this u
3:14:44from start to finish. This one is just
3:14:45duplicating a duplicate, which should
3:14:47honestly have some functionality built
3:14:48in, which it doesn't. So five if you
3:14:50want to call it that. Um, but you know,
3:14:52it's it's something that's really high
3:14:53ROI, something that you can actually
3:14:54slot into a real business as opposed to
3:14:56just like looking cool and not actually
3:14:57doing anything for you. So, yeah, let's
3:14:59test out this puppy one more time. Okay,
3:15:02looks good. We're going to
3:15:04submit. Nice. We got the data. Let me
3:15:07just see if the website field is a text
3:15:09area. It is. It's okay. Well, we should
3:15:11have just gotten the form. Cool. We did.
3:15:13We got the email address and everything.
3:15:15Awesome. Cool. If I go over here now, do
3:15:17we still have access to this? No. I
3:15:18think I need to rerun all this stuff,
3:15:20right? Oh, we do
3:15:26apparently unpin replace text to
3:15:28execute. We're going to have to unpin
3:15:31the old data unfortunately. So, I'm just
3:15:33going to unpin some of the old data
3:15:35here. And I should unpin because we're
3:15:37just replacing the
3:15:40replacement. And then we'll pin
3:15:43this. Go. Now, we'll test it. Cool.
3:15:46Looks good. We automatically got the
3:15:47email and then we have our, you know,
3:15:49proposal and so on and so forth. You
3:15:51might want to decrease the line height
3:15:52if you just copy my template verbatim,
3:15:54but feel free to do whatever makes you
3:15:55happy. From here on out, you know, we're
3:15:57going to shift gears. Instead of
3:15:59replacing text in a Google slide, we're
3:16:01going to do in Panda doc for people that
3:16:02are unfamiliar. Panda doc's a really
3:16:04cool platform that allows you to, you
3:16:06know, take care of a lot of stuff that
3:16:08otherwise you'd sort of have to do
3:16:09manually. Panda do open here. Panda doc,
3:16:12as you can see, is a little bit more
3:16:13professional looking than uh slides and
3:16:14so forth. There's a lot of stuff that we
3:16:16can add. We can add, you know, text
3:16:17blocks, video blocks, image tables,
3:16:19quotes, uh, page breaks, table of
3:16:21contents, stuff like that. This is just
3:16:23an example uh proposal that I generated
3:16:25for a fictional company that I put
3:16:26together during my Maker School
3:16:28training. If you guys want to see how I
3:16:29put this together, um, you can find it
3:16:31all under Maker School in classroom. I
3:16:33do it all in month one. But basically,
3:16:35there's like a big proposal template
3:16:37that I do. And this proposal template, I
3:16:39run through the entire building process
3:16:40for people that might be interested.
3:16:42Anyway, this is my proposal template. As
3:16:44you can see here, very similar idea.
3:16:45Anything in yellow is just a variable.
3:16:47So what I'm doing is I'm like weaving in
3:16:48my own procedural logic with like
3:16:50templated text and stuff like that and
3:16:52then with AI generated text. The reason
3:16:54why I'm doing this is cuz I just want to
3:16:55make sure that like the parts that are
3:16:57very valuable um I wrote myself. I
3:16:59didn't have AI right. This the parts
3:17:01that are really valuable I want to just
3:17:02be clean and powerful. Um anyway top to
3:17:05bottom everything works basically the
3:17:07same until we get to this section where
3:17:08it says your investment intelligent lead
3:17:11management system for leftclick. Right.
3:17:12And then we have a we have a price. The
3:17:14way that this works is in Panodoc, you
3:17:16actually hook this up to a payment
3:17:18button. And what happens is after the
3:17:20proposal is sent, uh, you basically,
3:17:22sorry, after you sign the proposal, uh,
3:17:24you have the option to pay immediately.
3:17:26So, it's great for collecting. Um, I use
3:17:28this in order to scale my agency to 72K
3:17:31a month. Um, I use this with one second
3:17:33copy where I scaled to 92K a month as
3:17:34well. This is just like a much cleaner
3:17:36way of going about things than the way
3:17:38that most people handle agreements and
3:17:39stuff. And I have a video on that. um
3:17:41you know providing logic around my
3:17:43proposals and stuff like that if you
3:17:44want to check it out in Maker School as
3:17:45well. I'll stop soft pitching that I
3:17:47think we're we're all adults here. Join
3:17:49my program if you want to get better at
3:17:51this sort of stuff. But yeah, let me
3:17:52actually run you through what this looks
3:17:53like. So in order to do this, basically
3:17:55we need to make a request to the API.
3:17:57Okay, it's not enough for us to do a
3:17:59request to like a panda dooc node
3:18:00because there is no panda dooc node,
3:18:02right? I just checked out panda dooc.
3:18:04You didn't find anything. But you know,
3:18:06you can do it with the HTTP request and
3:18:07they're 100% right on that. Now, in
3:18:09order to get this done, what we need to
3:18:10do is we need to feed in this giant
3:18:12super scary block of text that looks
3:18:14like this. And it's basically just a ton
3:18:16of JSON that we formatted to be um you
3:18:20know like curtailed to this particular
3:18:22template. So, this template's a little
3:18:24bit different, right? We have tokens, a
3:18:26value called client email, sender email,
3:18:28client scope one, client scope 2, client
3:18:29scope 3. As you can see, we're actually
3:18:31generating multiple client scopes as
3:18:32opposed to just one. And the reason why
3:18:34is because we are doing it like this,
3:18:36right? One, two, three, four, five. So I
3:18:39believe I'm I'm feeding in five in
3:18:41total. Yeah, looks like I'm feeding in
3:18:42five different scope items, right? How
3:18:44crazy is that? Then we have client
3:18:45company, center company, client last
3:18:46name, sender last name, client timeline
3:18:481, timeline 2, timeline 3. These are all
3:18:51just takes on the same idea. So really,
3:18:53in order to modify the system that we
3:18:54previously had into a system that's
3:18:55capable of operating with this, all we
3:18:58need to do is we just need to output
3:18:59slightly different objects. And that
3:19:00will require us to just once adjust our
3:19:03AI generated copy so that you know the
3:19:06objects look like what this is
3:19:07expecting. And then two, we just need to
3:19:09update those. There's a place for us to
3:19:10put price and everything like that. So
3:19:12I'm just going to go ahead and like do
3:19:13most of the grunt work, but I'm going to
3:19:14show you while I do it. I like cut at
3:19:16several points just so you can see
3:19:18exactly what that looks like. Okay,
3:19:19first things first. I'm going to jump
3:19:21into the expression editor here. And if
3:19:23you think about it, I actually have like
3:19:24a title variable already. So I'm just
3:19:26going to go proposal title right here.
3:19:28And then there's client scope one,
3:19:30client scope 2, client scope 3, client
3:19:31scope four, client scope 5. So there are
3:19:33five different client scopes. So I need
3:19:34to make sure that my object that I'm
3:19:35opening open actually has five scopes
3:19:37instead of just one. Just delete all of
3:19:39the scopes descriptions. We'll just
3:19:40change them all so that it's just the
3:19:42titles, right? Make sure they're inside
3:19:44of the string. Okay. And I just ran it
3:19:46using this API format. This is a very
3:19:50long and kind of scary object for most.
3:19:52So don't sweat the specifics too much.
3:19:54If you guys want to learn how to make
3:19:55something like this for yourself, I will
3:19:57be covering how to do API connections in
3:19:58the next video. But the end result is we
3:20:01end up with a proposal that looks
3:20:02something like this. AI powered script
3:20:03writing system for leftclick. You know,
3:20:05here's some information about what the
3:20:06core problems are. Here are, you know,
3:20:09some pieces about the solution. Right?
3:20:12As you can see, my proposed solution to
3:20:14the problem above is as follows. Tack
3:20:16these challenges. We propose an advanced
3:20:17AI script writing system that automates
3:20:19your content creation workflow. The
3:20:20system will script compared to YouTube
3:20:21channels for content ideas, analyze in
3:20:22the best performing titles. Use AI to
3:20:24rephrase these titles and generate
3:20:25detailed outlines. It could be with
3:20:27ready to use scripts to streamline your
3:20:28video production process. I consider
3:20:30this reasonably straightforward and I'm
3:20:31confident I can do an outstanding job
3:20:33here for you. If I wasn't, I wouldn't
3:20:35have put together this proposal. Right?
3:20:37We got all the scope stuff here. We got
3:20:39the timeline. Uh and then over here,
3:20:41this probably the most important part.
3:20:42We have the price. The way the price
3:20:43works, we actually have 50% due up
3:20:45front, 50% due in signing. we check our
3:20:48little payment note. Essentially, what's
3:20:50going to happen is when we send this,
3:20:51they're just going to receive an invoice
3:20:53um the moment that they sign for that
3:20:55amount of money. And I'm seeing here
3:20:57that I think I used an extra capital L.
3:20:59But, you know, we all can't be perfect.
3:21:02Uh yeah, that's that's more or less it
3:21:04in a nutshell. So, you can take the same
3:21:06approach that I just showed you guys how
3:21:07to do today to virtually any proposal
3:21:09platform or virtually not even just a
3:21:10proposal platform, but virtually any
3:21:12asset that you create. Cuz you know,
3:21:14creating a Google slide, if you think
3:21:15about it, that's creating an asset.
3:21:17That's basically creating like a lead
3:21:18magnet. It's creating a PDF. You could
3:21:20export that in a number of different
3:21:21formats. You could give it to somebody.
3:21:22You could print freaking books with
3:21:23that, right? If you take this core idea
3:21:26here and then extend it, you could do uh
3:21:28a number of things. But I hope at this
3:21:29point I've at least just given you guys
3:21:31the knowledge to be able to build a
3:21:32simple AI powered flow without
3:21:34necessarily overwhelming yourself with,
3:21:36you know, talk about AI agents and stuff
Website AI Agent
3:21:37like that. Nice job. You know, have an
3:21:38AI proposal system that creates
3:21:40professional customized proposals in
3:21:41real time during sales calls. We built
3:21:43that all out live and hopefully you guys
3:21:44understand what an actual proposal
3:21:46generation build process looks like. The
3:21:48whole idea is to give you guys a massive
3:21:49edge when closing automation deals and
3:21:51then also give you another product in
3:21:52your toolkit that you can sell. We're
3:21:54now going to be building a website AI
3:21:56agent that handles visitor
3:21:58conversations, answers questions about
3:21:59your services, and also allows you to
3:22:01book meetings directly into your
3:22:02calendar. This is not just a chatbot. It
3:22:04is a lead qualification and booking
3:22:05system that works around the clock. a
3:22:07automation agencies regularly to charge
3:22:09anywhere from$1 to $2,000 to implement
3:22:11these systems because these automate the
3:22:13entire lead qualification process. It's
3:22:14also a great introduction into agents
3:22:16and how they work more generally. Let's
3:22:17dive
3:22:19in. So, here's the AI agent right here.
3:22:22As you can see, it's very simple. We
3:22:23have a simple AI agent flow with a chat
3:22:25message that goes into this decision
3:22:27maker which calls the Open AI chat
3:22:30model, stores contacts in the window
3:22:31buffer memory, and then we have a few
3:22:32tools that we're calling the Google
3:22:33calendar create event, Google calendar
3:22:35get all event. That's actually not very
3:22:36important. There's a million and one
3:22:37ways to set up agents. The thing I want
3:22:39to impress upon you is this looks
3:22:40simple, but in reality, when you use AI
3:22:43agents in business, they tend to be very
3:22:45simple because businesses in practice
3:22:48don't really use these massive waterfall
3:22:50AI agents that you guys are probably
3:22:51seeing with like a million in one nodes
3:22:53where an AI agent calls another AI agent
3:22:55and that Agent calls another AI agent.
3:22:57And the reason why is because the output
3:22:59tends to be a lot less predictable and a
3:23:01lot less consistent. And if you're a
3:23:03business, your revenue is driven by
3:23:05consistency. You want to constrain the
3:23:07total realm of outputs down to something
3:23:10manageable. So this in practice is
3:23:12typically what automations that make
3:23:13money look like at least the AI agent
3:23:15forms. So set your timer. Let me show
3:23:17you how to build an actual AI agent just
3:23:18like you saw in the intro in just a few
3:23:22seconds. First things first, open up a
3:23:24new NAND workflow. Click add first step.
3:23:27Type the term agent, then open it.
3:23:29You're good to go. Next up, select a
3:23:32chat model. In our case, we're going to
3:23:33be using the Open AI chat model. And I'm
3:23:35just going to be using the default
3:23:36functionality to get you up and running
3:23:37as quickly as possible. Going from 0 to
3:23:39one really is the most important thing.
3:23:41Then under memory, select window buffer
3:23:44memory. Set contacts window length to
3:23:4710. You can actually get away with
3:23:48substantially longer because of a trick
3:23:50I'm about to show you. Now, you can chat
3:23:51with this just like you chat with any
3:23:52model. Click the chat button. Hey, how's
3:23:54it going? And you'll see that GPT4 Mini
3:23:57will give you a response. But the really
3:23:58cool thing is if you go to when chat
3:24:00message received over here and you
3:24:01select make chat publicly available to
3:24:03on what you have here is you have a chat
3:24:06URL that you can actually just link to
3:24:08directly. Now you have a hosted instance
3:24:10where you can talk to the
3:24:13model. Now the question is how do we
3:24:16take this hosted instance and then put
3:24:17it on our website. I have a website
3:24:19available over here. This is my content
3:24:21writing company called 1 second copy
3:24:23before chat GBT came out and you know
3:24:25rose rose to prominence. Um, this was my
3:24:27primary income source and this is sort
3:24:28of how I paid the bills. We had a team
3:24:31of very high quality journalists. We
3:24:32used some GPT2 and GPT3 uh much older
3:24:36models to basically help pre-draft a lot
3:24:37of the content and yeah, it was a pretty
3:24:39solid business. What I want is I want in
3:24:40the bottom right hand corner there'd be
3:24:42a little chat widget that pops up like
3:24:43you guys saw. So, in order to do this,
3:24:45if we go back to our anen chat agent,
3:24:48what you'll see is there are a couple of
3:24:49settings on your mode. Just change
3:24:50hosted chat to embedded chat. Okay? and
3:24:53then head over to this link. You scroll
3:24:56down a bit, you'll see that there's an
3:24:58option for installation called CDN
3:25:00embed. That stands for content delivery
3:25:02network. And basically what it gives you
3:25:03is it gives you a snippet of code that
3:25:05you can add to any website, whether it's
3:25:07customcoded site, a WordPress site, a
3:25:09web flow site, a Wix site, Squarepace
3:25:11site, whatever the hell you have. And
3:25:13all you need to do is copy and paste
3:25:14this in and then replace the web hook
3:25:16URL and you'll actually have a little
3:25:18chat widget built to spec that runs the
3:25:22rest of your flows. If we go back over
3:25:23to my actual website config, which I'm
3:25:26doing in something called netlifi, if I
3:25:28go to site configuration and then scroll
3:25:29down to postprocessing, there's actually
3:25:31a setting for me to add a snippet of
3:25:33text over here. So, what I'm going to do
3:25:34is I'll call this nadn chat agent. Paste
3:25:37in the HTML and all I need to do is go
3:25:40back here and get this web hook URL.
3:25:43and then paste it here where it says
3:25:45your production web hook
3:25:47URL. Okay. Now, the way that you do this
3:25:50is going to depend on the service that
3:25:51you're running. I mean, I'm running this
3:25:52custom website on Netlifi, so it's
3:25:54pretty easy for me. All I do is I just
3:25:56refresh the site. And now, what you'll
3:25:58see is in the bottom right hand corner,
3:25:59you have your little chat widget. Hi
3:26:01there, my name is Nathan. How can I
3:26:02assist you today? So, what's really cool
3:26:06about this is this is now running. I
3:26:08mean, you know, it's asking me the same
3:26:09thing because it doesn't have access to
3:26:10this, but this is now pinging the same
3:26:13AI agent flow that we just set up. We
3:26:16actually have two-way communication. And
3:26:17so, you can actually test this. You can
3:26:19run this. It's live. And the changes
3:26:20that you make over here are going to be
3:26:22reflected back over there. Now, a couple
3:26:24of other minor changes that we want in
3:26:26order to actually have this thing be
3:26:27useful for us. The first thing I'm going
3:26:29to want to do is I'm going to want to
3:26:30adjust the prompt a little bit because
3:26:31the way that AI agent prompts work, it's
3:26:33kind of unfortunate in N. If you use the
3:26:35default prompting behavior, what you're
3:26:37doing is you're always taking the prompt
3:26:38from the previous node and just
3:26:40recycling it over and over and over and
3:26:41over again. There's also sort of a
3:26:43hidden prompt that you don't really see,
3:26:44which can muck up the quality of what it
3:26:46is that you're trying to do. So, what I
3:26:47recommend is to use this template that
3:26:49I'm about to show you to define what's
3:26:51called a system message instead, which
3:26:53is a static fixed prompt the model will
3:26:55always have access to and then having it
3:26:58take the input from the previous node
3:27:00automatically and recycling it. This is
3:27:02the best of both worlds. I've seen a lot
3:27:04of people try to use the define below
3:27:06section. Um, just my my understanding of
3:27:08the way that these technologies work
3:27:09under the hood make me feel like this is
3:27:11not the ideal way to do it. So, I've
3:27:13saved a prompt over here which I'll run
3:27:14you through in a
3:27:15moment. And if you want to set this up
3:27:18for yourself, I highly recommend just
3:27:19using some variant of this prompt. Now,
3:27:21it's dynamic. So, you're going to have
3:27:22to go to
3:27:23expression. We're going to need to
3:27:25reopen this. And basically the way it
3:27:27works is we say you're a helpful
3:27:29intelligent website chatbot for 1second
3:27:31copy a content writing company. The
3:27:33current date is now format y mmdd. This
3:27:37is just an naden javascript function
3:27:39that converts the current date into ISO
3:27:448601 format. It's just a very simple and
3:27:46easily interpretable um current date.
3:27:48You are in the Edmonton MT time zone.
3:27:50You're male and your name is Nick. So
3:27:51we're going to have to change the
3:27:52chatbot so it doesn't say my name is
3:27:53Nathan. I'll show you guys how to do
3:27:54that in a second. Here's a bunch of
3:27:56context about the business. We offer
3:27:57extremely fast turnaround times, 4 to 6
3:27:59hours at affordable rates, 10 cents a
3:28:01word. Our work has been published in
3:28:02Forbes, BI, TechCrunch, and most major
3:28:04magazines. We've worked with some pretty
3:28:06big names like CO, Wise, Upwork,
3:28:07NordVPN, HP, and more. Our team is
3:28:09composed of award-winning journalists,
3:28:10writers from all over the world. We use
3:28:12AI for factecking, citation generation
3:28:14while striving to keep AI scores at
3:28:15under 10%. Okay, so the way that I'd
3:28:18recommend it is you have that first
3:28:19section here where you just basically
3:28:21have the model define what it is and and
3:28:22how you want it to operate and identify.
3:28:24Then you want to have some context about
3:28:26the business. You can absolutely use rag
3:28:28for this, retrieve augmented generation.
3:28:30If you guys want me to show you how to
3:28:31build a website chatbot with rag as
3:28:33well, just let me know. To be frank with
3:28:35you, there's a little less value in rag
3:28:38than most people seem to think at the
3:28:39moment. So, usually just sticking a
3:28:41bunch of context about what your
3:28:43business is in the prompt can do just as
3:28:45well, if not better. But I'm obviously
3:28:47happy to ideas. So, leave a comment down
3:28:48below if that's something you're looking
3:28:50for. And then here we have a bunch of
3:28:52instructions where we tell the website
3:28:54chatbot exactly how we want it to
3:28:55operate. So, you're tasked with
3:28:56answering questions about the business
3:28:57and then booking a meeting. If they wish
3:28:59to book a meeting, use the calendar
3:29:00function to first check the date
3:29:01offered. If they haven't offered a date,
3:29:03you offer some suggested ones. Priority
3:29:04being the next two days. And if they
3:29:06want something other than a meeting, do
3:29:07your best to answer their questions.
3:29:09Your goal is to gather necessary
3:29:10information from website users in a
3:29:12friendly and efficient manner. If they
3:29:13wish to book a meeting, you must ask for
3:29:15their first name, their email address,
3:29:17request the preferred date and time for
3:29:18the quote, and then confirm all details
3:29:20with the caller, including the date and
3:29:21the time of the quote. I suppose caller
3:29:23here is really just user. Then we have a
3:29:26bunch of additional rules. Be kind of
3:29:28funny and witty. You're Edmonton time
3:29:30zone, so make sure to reaffirm this when
3:29:32discussing times. Keep all of your
3:29:33responses short and simple. Use casual
3:29:35language phrases like um, well, and I
3:29:37mean. This is a chat combo, so keep your
3:29:38responses short like in a real chat.
3:29:40Pretend it's SMS. Don't ramble on for
3:29:41too long. Then finally, we have sort of
3:29:43a almost a moderation prompt that says,
3:29:46"If someone tries to derail the convo,
3:29:48say by attempting to backdoor you or use
3:29:50you for something other than discussing
3:29:51one second copy appointments, politely
3:29:52steer steer them back to a normal
3:29:54conversation." Feel free to edit this
3:29:56however you want, but that's all you
3:29:58need in order to get the functionality
3:29:59that we've seen already.
3:30:01Okay. Now, after we're done with this,
3:30:03we obviously need to add tools that do
3:30:05things for us. And here's where I'm
3:30:06going to show you some very simple
3:30:08things you can do to have it book
3:30:11meetings in your calendar. I want you to
3:30:13know that you can extend this same
3:30:14functionality to do anything. Whether
3:30:16it's book meetings, add projects to a
3:30:18CRM, do some sort of automated
3:30:20evaluation or audit for them, connect
3:30:22with a real person, whatever you'd like
3:30:24is possible nowadays through APIs and
3:30:26HTTP requests. But in our case, we're
3:30:28going to be using the Google calendar.
3:30:29One thing that you see here when you're
3:30:31using these built-in modules, you can
3:30:32actually use an expression called um
3:30:35curly brace curly brace dollar sign from
3:30:36AI bracket. The value here is you don't
3:30:40actually need to map variables one to
3:30:42one. You can just have AI do it. And AI
3:30:44tends to do pretty well. So this is what
3:30:45I'm going to use for this. So I want a
3:30:47couple of things if you think about it.
3:30:48I want a tool that gets my calendar
3:30:51information. So it gets all of the
3:30:53current events that I have for a day.
3:30:54Then I also want another one that allows
3:30:55me to book using that information so
3:30:57that I know when I can book in a meeting
3:30:59with let's say our sales team. So the
3:31:02very first thing I'm going to do is I'll
3:31:04go down to operation and then I'll click
3:31:06get many. Get many is basically just a
3:31:08search. The calendar I'm going to want
3:31:09is the Nick at leftclick.ai calendar
3:31:11right over here. Then limit. I'm just
3:31:13going to set this to 10. Odds are I'm
3:31:15not going to have 10 more meetings in a
3:31:16day. Now, what I'm going to need to do
3:31:18is I'm going to have to select the
3:31:20specific date and time that the um
3:31:22meetings are going to be pulled from. So
3:31:25after a date and then before a date.
3:31:26What you can do is you can just select
3:31:28after a current date before a current
3:31:29date. Um if you set like the same date
3:31:32and time, it'll just pull you all the
3:31:33events for that day. So I'll go to
3:31:34expression. I'll paste in from AI and
3:31:36then I'll say after date. Then I'll go
3:31:39to before. I'll paste this in and go
3:31:41before
3:31:43date. Down here I'll go order by query
3:31:48show deleted hidden invitations. Oh,
3:31:49time zone. Sorry. And then what I'm
3:31:52going to select is just my own time zone
3:31:54for simplicity. So remember how I
3:31:55mentioned there we were Edmonton time
3:31:57zone. I'm Edmonton or America Edmonton
3:31:59which I think is GMT minus 7. It's
3:32:01important to have your time zone
3:32:02configured exactly or you're going to
3:32:03have some issues with the workflow
3:32:05obviously because the times that you
3:32:06tell people are going to be different
3:32:07from the times that obviously people
3:32:09tell you. And then we're going to add
3:32:11one more calendar tool. That's going to
3:32:12be the create. I'm going to be creating
3:32:15in the same calendar I'm checking. The
3:32:17start date is going to
3:32:19be from AI start date. The end date is
3:32:22going to be from AI end date. And
3:32:25there's there's one more thing I'm going
3:32:27to want to do. Let's move down here to
3:32:29summary.
3:32:31and then go expression meeting
3:32:36summary. That way when the AI creates
3:32:38the event, we're going to have some sort
3:32:40of meeting summary associated with it.
3:32:43Oh, and there's actually one more. We'll
3:32:45do attendees, which is right over here.
3:32:47Now, I'm always going to be the
3:32:49attendee, and we're always going to have
3:32:50some other attendee, which is going to
3:32:53be the user email.
3:32:57Okay, AI is coming up with all this
3:33:00stuff based off of the context of our
3:33:02conversation, which is pretty cool.
3:33:04Okay, sweet. So, given everything that
3:33:06we know now and given how it's set up,
3:33:08first I'm going to test this right over
3:33:10here. And I'm actually going to move
3:33:11over after making some changes and test
3:33:12it in the 1 second copy website.
3:33:15Anybody's on my website right now, that
3:33:17means they're currently seeing it, which
3:33:18is pretty neat. So, let me let me
3:33:20actually just delete all this. Let me
3:33:22pretend I'm interacting with an agent as
3:33:24if I want to do something.
3:33:26Hello, thanks for this. I'm interested
3:33:29in 1 second copy. Tell me a bit about
3:33:31it. It's now going to be pulling in data
3:33:34from the context. Because it's pulling
3:33:36in data from the context, aka the
3:33:38samples that we provided directly in the
3:33:39prompt. It's going to operate very
3:33:40quickly. Now, in my case, it's just
3:33:42pulling data directly from there and
3:33:44just listing them line item by line
3:33:45item. You can have it respond to these
3:33:47sorts of queries in a specific way if
3:33:49you want. The context window is big
3:33:50enough that you can write whatever the
3:33:51hell in that system message.
3:33:55Let's see how it works with the calendar
3:33:56functionality. Do you want to set up a
3:33:58meeting to discuss details? If so, I can
3:34:00help you book that. Sure thing. You got
3:34:0230
3:34:03minutes sometime in the next few days.
3:34:07What's your time
3:34:09zone? I'm in Edmonton. I can check our
3:34:12calendar for the next couple of days to
3:34:13find a 30-minut slot. Just give me your
3:34:14first name, email. Let me know your
3:34:15preferred date and time. Sure thing,
3:34:17Nick. Let's do my main email here.
3:34:22And sometime after 300
3:34:26PM tomorrow or the next day when I call
3:34:30this, what's it going to be doing? It's
3:34:32obviously checking my calendar
3:34:33availability and responding through the
3:34:34model. Looks like tomorrow after 3 p.m.
3:34:37is booked up for our team. However, I do
3:34:38have a spot available the day after
3:34:40tomorrow, March 2nd at 3:30 p.m. Does
3:34:42that work for you? Now, it's checking my
3:34:44current calendar and I do indeed have a
3:34:46spot there. Um, does that work for you?
3:34:48Sure thing. Could you
3:34:49book? And now it'll go through and it'll
3:34:52actually complete the booking. Well,
3:34:54before it does that, it's going to
3:34:55confirm with me. Great. Just to confirm
3:34:57Nick nicholas arrive atgmail.com date
3:34:58and time. Shall I go ahead and book
3:34:59that? Absolutely. Thank you. Now, if we
3:35:02enter that out, it's now going to be
3:35:04pulling the Google calendar event and
3:35:05actually going and creating it in my
3:35:07calendar. What's really cool is it's
3:35:09going to offer me a meeting link that I
3:35:11can then take a look at. So, in order
3:35:12for me to do this, I do need to open up
3:35:14the specific account that I'm
3:35:15in. And voila, we now have it right over
3:35:19here. meeting with one second copy. Now,
3:35:21in my case, it's getting nicks arrive
3:35:23twice because my other email address was
3:35:26nicholas@gmail.com. I fed that details
3:35:28in and then it got my picture from
3:35:30Google. But, um, yeah, as you can see,
3:35:32it's that easy to set up an AI agent
3:35:33that actually does something.
3:35:34Realistically, all this takes is a few
3:35:36minutes. Now, there are a couple changes
3:35:38that we're probably going to want to
3:35:39make to the AI agent on our live
3:35:40website. Obviously, we're going to want
3:35:42to brand it a little bit differently.
3:35:43And the agent says that his name is
3:35:45Nathan. How can it assist you today?
3:35:46Now, if you want to change the default
3:35:48messages and all of that, what you can
3:35:49do is you can actually just add this
3:35:51directly in that code snippet that I
3:35:52showed you guys a moment ago. And so,
3:35:54you can do things like have some initial
3:35:56messages in an array. You can do things
3:35:58like add some metadata, the mode, and
3:36:00and so on and so on and so forth. If I
3:36:02go back in my case to this, you can see
3:36:04the create chat function right over
3:36:06here. So, this is basically what I'd be
3:36:07editing. Now, unfortunately, I don't
3:36:10believe I can access the like I don't
3:36:13think I can edit this. I think I
3:36:14actually just create a new snippet.
3:36:15Okay. Okay, so I just went back in and
3:36:16pasted in initial messages array being,
3:36:19"Hi Nick here, let me know if you have
3:36:20any cues." And then if we go back here,
3:36:22what you see is we've now changed the
3:36:24text in the chatbot. Very simple and
3:36:26straightforward. Super easy to do. If
3:36:28you want adjust to adjust more
3:36:29configuration settings, just check it
3:36:31out over here. You can do things like
3:36:33change the text, add an input
3:36:34placeholder. Believe you should also be
3:36:36able to change the color. Yeah, right
3:36:38over here with some customization using
3:36:39CSS variables. You can make this window
3:36:41look however the hell you want. You can
3:36:42brand it entirely on your own. And I
3:36:44think you can also remove that little
3:36:46pesky NAD message, although I don't know
3:36:48exactly where that would be. Anywh who,
3:36:50I hope in this video I've at least shown
3:36:51you how to get started with the simplest
3:36:53version of an NADN AI agent website
3:36:56chatbot. It's nowhere near as hard as
3:36:58most people make it out to be. If you're
3:36:59smart about how you put this stuff
3:37:00together, you know, you can take this
3:37:02approach that I just showed you and you
3:37:03can make a couple of minor adjustments
3:37:04to it, but within 13 minutes or so, you
3:37:07can actually have something on a website
3:37:09that you could charge money for. You can
3:37:10run custom functionality for you can
3:37:12actually have access a calendar or
3:37:14adjust a CRM or actually do something
3:37:16with tools. Cool. You've now built a
Social Media Content Repurposing Engine
3:37:18website a agent that qualifies prospects
3:37:19and books meetings automatically.
3:37:21Hopefully, your lead genen or the lead
3:37:22genen of your clients now working on
3:37:24autopilot. Next up is we're going to be
3:37:26building an AI content repurposing
3:37:28engine to take any YouTube video or
3:37:30podcast and automatically generate
3:37:31Instagram posts, LinkedIn content, and
3:37:33Facebook posts as well, all formatted
3:37:35and beautiful and ready to publish. This
3:37:36system is pretty valuable for coaches
3:37:38and consultants as well as content
3:37:39creators. Basically, anybody who needs
3:37:41to maintain an active social media
3:37:42presence and agencies typically charge
3:37:44anywhere from one to two,000 bucks for
3:37:45this automation because it solves a
3:37:46major time sync problem which is
3:37:48repurposing long form content. Okay, so
3:37:50now let's build that system to turn, you
3:37:52know, 1 hour of content into days or
3:37:54weeks of social media posts completely
3:37:57autonomously. So the way that this works
3:37:59is we start with a form submission where
3:38:01I put in the URL of a podcast. I then
3:38:04get the transcript via a thirdparty
3:38:06service which costs 1 cent per
3:38:08transcript something like a hundred
3:38:10podcasts per dollar. Then we will use
3:38:12OpenAI to get a bunch of data spin
3:38:15different transcript sections and do
3:38:18different things which I'll run through
3:38:19in a moment. We'll then split that out,
3:38:21loop over each item and then here we
3:38:22will generate Instagram posts, LinkedIn
3:38:24posts, Facebook posts before finally
3:38:26generating the the conccomment images as
3:38:28well. We'll then do some data processing
3:38:31then we'll add it to a database. Then
3:38:33finally we'll just do some merge and
3:38:34then update a form. And what happens on
3:38:37the back end is once we've done all this
3:38:38posting what we're doing is we're
3:38:40essentially updating a database looks
3:38:41something like this. Okay, very simple
3:38:43and easy to manage four column database
3:38:45called date added post body post image
3:38:47posted on with the platforms that we
3:38:49want to post to down below. And our
3:38:51system is essentially once a day going
3:38:54to set this to run every morning at 7
3:38:56checking through this database to see
3:38:57what new additions we've made. So in
3:39:00this way, our system is entirely dynamic
3:39:02and um it never overwhelms the service
3:39:04that we're posting on. We can generate
3:39:0610 or 20 or 50 new posts across all
3:39:08these platforms and then we can just
3:39:09drip them out according to some schedule
3:39:10that we predefined. After we've checked
3:39:13the Instagram posts, I then upload to
3:39:14Instagram using their graph API, which
3:39:16I'll run you guys through before
3:39:18updating the Google Sheets database. And
3:39:19we do the exact same thing with the
3:39:21LinkedIn posts. It's just we need to do
3:39:22an HTTP request for that. And then the
3:39:24Facebook posts as well. In terms of what
3:39:26this looks like live, let me actually
3:39:28test this puppy out. Let's test this
3:39:30workflow. See a new form that just
3:39:32opened. I'm just going to feed in a
3:39:33podcast right over here to this insert a
3:39:35podcast get content
3:39:36endpoint. Second, that's done. As we see
3:39:39in the background, we are now getting
3:39:40the transcript via a third party web
3:39:42service, one of my favorite web
3:39:43services, Ampify, which I'll cover over
3:39:45the course of the video. This transcript
3:39:48is going to come to us very nice and
3:39:49perfectly manicured. And then after
3:39:51that, we feed that to this OpenAI
3:39:53module. This open module's job is
3:39:55basically outputting a very big um JSON
3:40:01that contains an index with the number,
3:40:03the paragraph transcript, some context
3:40:05and feedback, and then a deep
3:40:06explanation of what the section that I'm
3:40:08talking about is along with an image
3:40:10description that we can use to generate
3:40:11some JPEGs, and I have some rules down
3:40:13here. Because we're feeding in a
3:40:15relatively long transcript to a model
3:40:16that has a context of 128,000 tokens,
3:40:19takes a fair amount of time to do this
3:40:20run. It's usually about 30 seconds or
3:40:22so. Uh but after that we're we're going
3:40:24to split it out and continue. And then
3:40:25as you can see we are now generating the
3:40:27posts and then adding them. So we just
3:40:28did Instagram, now we're doing LinkedIn
3:40:31and finally we'll do Facebook as well.
3:40:34If we go back to our
3:40:35database, you can see that we're
3:40:37actually adding these as we
3:40:38speak. And so this is populating that
3:40:41sort of middle ground database which I
3:40:42like. Now on the back end, now that
3:40:45we've added these, what we can do is we
3:40:46can test this workflow pretty easily. So
3:40:48we're going to upload to Instagram
3:40:50first.
3:40:51We're going to post on Instagram and
3:40:54we're also going to update the Google
3:40:55Sheets database to tell us that it's
3:40:58posted. We're going to do the same thing
3:40:59with
3:41:00LinkedIn. And LinkedIn, we need an HTTP
3:41:03request to do. And we're going to add
3:41:04that there as well. And we can actually
3:41:06see these live. We'll just wait for this
3:41:08to finish posting. But if I refresh my
3:41:10LinkedIn company page, you can see the
3:41:11post has actually been made. Actually,
3:41:13I've done two cuz I just did one other
3:41:15test. But I chose like a pretty friendly
3:41:17kind of style here. I figured that I
3:41:19would I don't know some company that did
3:41:20watercolor styles. Obviously, my actual
3:41:23brand Leftclick is not like that at all.
3:41:24But, uh, yeah, just wanted to give you
3:41:26guys some freedom here. You guys can
3:41:27generate these images however you want.
3:41:28Alex Ramos is doing a lot of this stuff
3:41:30recently, which I find interesting.
3:41:31He's, um, applying a specific style to a
3:41:33specific type of content. And then,
3:41:34yeah, we've now posted them across all,
3:41:36you know, Instagram, Facebook, and
3:41:38LinkedIn, which is pretty cool. And then
3:41:39if we go back to our database back over
3:41:42here, you'll see that we now have the
3:41:44posted on fields as done. Um, which
3:41:46means that we have essentially just ran
3:41:48through our database and, you know,
3:41:49posted and dripped these out over time
3:41:51as opposed to all at
3:41:53once. Okay, so I've yet to actually
3:41:55build the system at this point in the
3:41:57video, but first thing I always like to
3:41:59cover before I actually do the system is
3:42:00why am I doing the system? Is the system
3:42:02important? Does this solve a problem?
3:42:04Ideally, you would start with the
3:42:05problem and then you build a system that
3:42:07solves that problem, not the other way
3:42:08around. I think a lot of people are kind
3:42:10of putting the cart before the horse and
3:42:11they're building the the system before
3:42:13actually having a need for it. So, I
3:42:14know for sure that the system is
3:42:16worthwhile and solves problems because I
3:42:18talk with people all the time that have
3:42:19these exact customer problems and you
3:42:21can sell the system or you could build
3:42:23the system yourself to solve those
3:42:24problems in your own business. What are
3:42:26some issues? Well, AI podcast
3:42:28repurposing engine solves the content
3:42:30need. So, it allows us to generate a
3:42:31large amount of content from just one
3:42:32long form episode. Allows us to reach a
3:42:34much larger audience with the same
3:42:37marginal amount of effort. Zero
3:42:38additional recording time, which is
3:42:40cool. We get to maximize the content
3:42:41investment. And then if you wanted to
3:42:43sell this, it's why we put this in a
3:42:44different color here. Um, you know, you
3:42:46could do so for a$1,000 to maybe $2,000
3:42:49service, I would say, just because it's
3:42:50very simple. It runs in the background.
3:42:52I'll show you guys a simple input method
3:42:53to like make all this stuff work and
3:42:54look hunky dory. And yeah, very
3:42:56straightforward, not at all difficult.
3:42:57So that gets us to the more important
3:42:59question, which is how. And the how is
3:43:00what we are going to be dealing with in
3:43:02this video. What I'm thinking of doing,
3:43:03and I, you know, I got like two or three
3:43:05nodes in for I was like, you should
3:43:06probably record a video on this, is
3:43:07we're going to start with some YouTube
3:43:08podcast URL input. Okay. So, what I'm
3:43:10thinking is we're going to have some
3:43:11form or something, probably a form where
3:43:13I can fill in the URL of the podcast
3:43:16that I want to generate content for. And
3:43:18this is the simplest way I can think of
3:43:19doing this. Sure, you could do this
3:43:20automatically. You could track podcast
3:43:22posts on a YouTube channel, whatever.
3:43:24But I'm just going to do a form. So,
3:43:25we'll we'll trigger it manually. Then,
3:43:27from there, we're going to grab the
3:43:28transcript somehow. So, there variety of
3:43:30different ways you can grab transcripts
3:43:31in actuality of videos. Um, the simplest
3:43:33is Ampify, but you could also do
3:43:35something like OpenAI's Whisper. I mean,
3:43:37to be honest, there's like 500 of these,
3:43:39so I'm not going to go super in-depth
3:43:40there. But, um, what I'm going to do is
3:43:41I'm going to I'm going to grab the
3:43:42transcript of the YouTube video, and
3:43:43then I'm going to feed it into a big
3:43:45content router. And this is where the
3:43:47rest of my system is sort of going to
3:43:48come into play from. So, what I'm
3:43:50thinking is we're going to start. We're
3:43:51basically going to need like some sort
3:43:52of GPT call, some AI call. Let's just
3:43:54call it like a large language model
3:43:56call. Probably use GPT4 or maybe 4.5.
3:43:59And then this is going to generate me
3:44:01some specific like Instagram content.
3:44:03Okay. I'm going to do the same thing
3:44:05with, you know, another GPT4 call. And
3:44:08then I'm going to generate probably like
3:44:10some Facebook content. As of the time of
3:44:12this recording, the Twitter API or the X
3:44:15API, I should say, is uh like 200 bucks
3:44:17a month or something like that. So, I'm
3:44:18not going to pay for that um for this
3:44:19video, and I don't think a lot of people
3:44:21will either. So, we're just going to
3:44:22skip Twitter or X for now. But then
3:44:24we're going to do like some LinkedIn
3:44:26content. And also, what I think would be
3:44:28really cool is if we um if I give you
3:44:30guys everything you need to actually
3:44:31like clip. So, there's a couple of
3:44:33platforms out there. One's called Opus
3:44:34Clip, and there are a few other ones
3:44:36where basically you can feed in a longer
3:44:38video. Then you can actually generate
3:44:40clips from that video um using AI
3:44:43timestamping and stuff. Now,
3:44:44unfortunately, these guys don't have an
3:44:45open API, so you can't actually just
3:44:46like have your API call and then use
3:44:49that to generate, but um I'm going to
3:44:50give you everything you guys need in
3:44:51order to do so. And I'll actually walk
3:44:52through the API most likely. So, what
3:44:54I'm thinking is we're going to use a GPT
3:44:56and then maybe we'll like generate
3:44:58timestamps. And for now, we're just
3:44:59going to like have all those timestamps
3:45:01be generated with all the rest of the
3:45:03content you need, maybe like some
3:45:04hashtags and everything. And then, you
3:45:07know, you can either feed this into some
3:45:08sort of flow for an editor or whatever,
3:45:10and then have it generate a bunch of
3:45:11stuff. Okay? So, there's nothing really
3:45:13magic here. I mean, I'm just recombining
3:45:15components of different things that I've
3:45:16built before in the past, but I just
3:45:18wanted to run you guys through what my
3:45:19thought process is at this point in the
3:45:20process. This is what I think it's going
3:45:21to look like. Okay? And everything
3:45:23sounds nice before you actually get into
3:45:25the building, but uh yeah, let's start
3:45:27there. Okay, so I'm just going to use
3:45:29this as our road map. And then for now,
3:45:31we're actually just going to jump back
3:45:32over here to NADN. I have a little NAND
3:45:35workflow set up called AI podcast
3:45:36repurposing engine. And so really, if
3:45:38you think about it, like what is the
3:45:39first step? Well, what a lot of people
3:45:40like to do is they like to start at the
3:45:42beginning and then work their way
3:45:43forward, but I actually kind of like to
3:45:44start at the end and then work my way
3:45:45backward. Now, the end is relative in
3:45:47this case, but I just I actually want to
3:45:48go scrape the thing with Apify first.
3:45:50Like I I want to scrape the YouTube
3:45:51video and I want to verify or guarantee
3:45:53that I can actually generate the
3:45:54transcript. That's kind of the first
3:45:55thing that comes to mind. like maybe
3:45:56it's intuition or just because I've
3:45:57dealt with a lot of these projects but
3:45:58that usually is the rate limiting step.
3:46:00It's like, hey, can we get the data that
3:46:02we are planning on doing all this fun
3:46:04stuff with? Because if you can't get the
3:46:05data, you can't really do anything else,
3:46:07right? So, let's first of all verify we
3:46:08can actually get the data. So, in order
3:46:10to do so, I'm on this platform called
3:46:11Appify. Basically, this is just like a
3:46:13big marketplace for scrapers that other
3:46:14people purpose-built that allow you to
3:46:16do things like get YouTube transcripts,
3:46:18and they build out all the logic for
3:46:19you. You don't have to do any of the
3:46:20math yourself. Um, what I'm going to do
3:46:21is I'll just type YouTube transcript.
3:46:23And then there are a variety of uh
3:46:24scrapers that come up here that say that
3:46:26they could do our job what we're looking
3:46:27for. But I'm just going to go to pricing
3:46:28models, go pay per result, just cuz you
3:46:30could rent scrapers. You could pay for
3:46:33usage, but in my case, I like to pay for
3:46:34the end result. I care most about the
3:46:35deliverable. So, how much money am I
3:46:37going to spend per transcript? And
3:46:38usually what I do at this point is I
3:46:39just open up two or three of these and
3:46:41then I just very quickly compare them.
3:46:42So, that's what we're doing now. Let's
3:46:44see. Um, this one allows us to extract
3:46:47one or thousands of YouTube transcripts
3:46:48fast. Save time and effort. Okay. JSON
3:46:51XML HTML. The reviews are pretty low,
3:46:53but this is $750 per thousand. That
3:46:55seems okay. Let's check out this one.
3:46:57Same idea, $10 per thousand. All right.
3:47:00This one, $7 per thousand. All right.
3:47:02Well, I mean, to be honest, seems like
3:47:03kind of a wash. They're all about the
3:47:04same. I mean, they all have one or two
3:47:06reviews. So, let's just scroll down a
3:47:08bit and see if I can get some
3:47:09information on what I get. Looks like
3:47:12they will return me a big list of all of
3:47:15the captions. So, that's cool. Um, is
3:47:19there one that just gives me the whole
3:47:20thing in one big block? Like that would
3:47:21be
3:47:22nice. This would be pretty nice. Yeah.
3:47:24Yeah. So, include timestamps. No. And
3:47:26then I just get a giant list. Let's do
3:47:28that. Yeah. Yeah. Clean transcript.
3:47:30Okay. I like this one more now. And then
3:47:32do I just get one big transcript here?
3:47:34No, I get the time stamps and stuff.
3:47:35Listen, I think the time stamps are
3:47:37valuable, but I think that the first run
3:47:38I'm not going to use that. I'm just
3:47:39going to use the without the time
3:47:40stamps. So, let's give these guys a go.
3:47:42$10 per thousand results. I don't know
3:47:44if this is going to work, so I'm
3:47:44actually just going to try it out on a
3:47:46YouTube video. Why don't I do it on one
3:47:47of mine? Let's just go to Nick Sarif.
3:47:49Yeah, let's do the prompt engineering
3:47:51video. And that's 53 minutes. This one's
3:47:5440. I mean, like the longer the video is
3:47:56probably the longer the transcripts are
3:47:57going to take, but whatever. For testing
3:47:59purposes, this is probably fine. So, I'm
3:48:01going to paste in my own here. No
3:48:03timestamps. So, I'm just going to get
3:48:04like the whole thing in one big block
3:48:06hopefully. And then I'm just going to
3:48:07click save and start. And so, Appify uh
3:48:09the way that it works is it'll spin up a
3:48:10server actually in the background. So,
3:48:12this is now like a server somewhere on
3:48:13the internet that has been spun up that
3:48:15is now running this scraping script that
3:48:16this other person put together. And I'm
3:48:18basically going to be charged uh what I
3:48:20think is 1 cent if my math is is
3:48:22correct. Um per video that I get the
3:48:24transcript for. So, obviously very
3:48:25economical for testing purposes. And
3:48:27then uh you just pay either a monthly
3:48:29amount or something else and then um
3:48:30they bill you. So, in my case, I use a
3:48:32lot which is why it's at 100 bucks so
3:48:34far. But yeah, let's see if this one
3:48:36works. And and of course, sometimes it
3:48:38doesn't work. I mean, these are scrapers
3:48:39other people build, right? I mean, this
3:48:41looks pretty good. All right. Now, yeah,
3:48:42this looks pretty good to me. So, now
3:48:44that I have this, let's just export this
3:48:45result. Let me just see what this looks
3:48:47like with all fields in a Google sheet
3:48:49first. Again, my whole goal is I just
3:48:51want to verify, hey, you know, can I get
3:48:53the data that I'm looking for? If I can
3:48:54get the data I'm looking for, everything
3:48:55else is really easy. So, now I'm going
3:48:57upload and I'm just going to drag and
3:48:58drop this. And I'm doing it manually
3:49:00first and then we'll worry about the
3:49:01automating part later. We're probably
3:49:02going have to call some APIs, right?
3:49:04Okay. So, it looks like it returns the
3:49:06URL, returns the video title. Okay,
3:49:07that's cool. And then boom, we have the
3:49:09whole transcript. How many words is
3:49:11this? Really? Now I'm starting to think,
3:49:13okay, there's a lot of words. 8,000
3:49:14words. Okay, so let me think about this.
3:49:16Usually people speak at about like 200
3:49:18words a minute, approximately, 150, 200
3:49:20words a minute. So if I were to feed in
3:49:24an hourong podcast, which is pretty
3:49:26standard. My content's kind of like
3:49:27that. I'd probably have like 10,000 or
3:49:30so words. That's a lot of words. Is AI
3:49:32going to actually be able to deal with
3:49:33this? So, I'm starting to think, all
3:49:35right, there are probably some edge
3:49:36cases here where I might feed in like a
3:49:382-hour long podcast and there's going to
3:49:40be too many words, too many tokens for
3:49:41the context window. So, I'm kind of
3:49:43keeping that in mind. But anyway, I'll
3:49:44kind of shelf that for now and we'll
3:49:46cross that bridge if and when we get to
3:49:47it. Um, obviously, I've shown that this
3:49:48works. So, what do we actually do now?
3:49:50Well, um, the way that Appify works is
3:49:52you can actually just get a web hook
3:49:53call like when the actor is completed,
3:49:56you will get a notification. There's
3:49:58also an API. Um, and I don't think that
3:50:00Naden has a built-in appy node yet,
3:50:02right? Okay. So, I'm just going to go to
3:50:03the Appify API. I'll go Appy API. And
3:50:06then, you know, API stands for
3:50:08application programming interface.
3:50:09Obviously, um if you guys are unfamiliar
3:50:11with how to use APIs and stuff like
3:50:12that, I got a bunch of videos where I
3:50:13walk you guys through what that looks
3:50:14like. But essentially, what I'm looking
3:50:16for, so I think I'm looking for run task
3:50:19synchronously and get data set items. I
3:50:21think I'm not 100% sure. This looks good
3:50:24to me. I mean, there's so many dang um
3:50:26endpoints on the lefth hand side that's
3:50:28honestly pretty difficult for me to say
3:50:30for sure what's what. I see a couple
3:50:32that look similar. Actor tasks, run
3:50:35tasks synchronously, and then there's
3:50:36run actor
3:50:38synchronously. Huh. Not really sure what
3:50:40the difference is here. Return output or
3:50:43get data set items. I feel like it's
3:50:46probably going to be get data set items,
3:50:47right? All right. Anyway, I I think I
3:50:48think I'm going to do this now. Um that
3:50:50I have the API call here. What's really
3:50:51cool is in NAN, you can just copy all of
3:50:53this, right? So, I see there's this
3:50:55little copy button. I'm just going to
3:50:56click that. I'll go back here and then
3:50:58I'll go um HTTP request. I'll go import
3:51:01curl, feed this in. Okay. And it'll
3:51:03actually map the whole API request for
3:51:05me. So, it's already done all the work.
3:51:07All I need to do is I need to swap in my
3:51:09authorization token. And then I think I
3:51:11need to do one more thing. I need to
3:51:13feed in an input right over here. Okay.
3:51:15So, first things first, I'm going to get
3:51:17my authorization token. Now, how do I do
3:51:18that? Well, Appify probably has an API
3:51:21key thing somewhere, right? So, I'll go
3:51:23settings, I guess. Yep. API and
3:51:25integrations right over here. Let's
3:51:27create a new token. Let's just call this
3:51:28YouTube temporary cuz I'm just going to
3:51:30delete it
3:51:31afterwards. Do I want to limit the
3:51:33permissions? No, I don't think so. I'm
3:51:34just going to click create and see what
3:51:35happens. Uh, okay. YouTube temporary
3:51:37right over here. Let's copy this. Let's
3:51:39um let's delete a couple of these cuz
3:51:42odds are I probably totally forgotten to
3:51:44delete them on previous videos. So, I
3:51:45have so many. Anyway, uh I'll paste the
3:51:47the token right over here. That looks
3:51:49good. And then if you think about it,
3:51:51like what do I need? Looks like I need
3:51:53an actor ID here.
3:51:57So, where is that going to be? That's
3:51:59probably, you know, most of the time
3:52:01actors will put the ID up here. Yeah, I
3:52:04think so. So, that's probably the ID.
3:52:06That's usually the ID for most of these
3:52:08services. So, I'm just going to grab
3:52:09this, paste this in, and then I need to
3:52:11feed in the actual website that I'm
3:52:13going to use, right? So, I don't know
3:52:14how that looks, but usually on Appify,
3:52:16they'll show you if you go to JSON,
3:52:17they'll show you what the data looks
3:52:19like. Okay, so check this out. Include
3:52:20timestamps, no start URLs website. So,
3:52:22what I'm actually going to do is just
3:52:23copy this. Then I'll go back to my N8
3:52:25endflow. Sorry, been jumping around a
3:52:27lot. And then under body content type,
3:52:29I'll go using JSON. And then I'll just
3:52:31paste this in. Okay. Okay. So, this is
3:52:33fixed right now, right? I'm just feeding
3:52:34in one URL, but um I'm okay with that. I
3:52:36just want to test and see if this works.
3:52:37Let's see if there's any issue with my
3:52:39syntax or something. Let's see. And if
3:52:41there are any bugs, I keep all of them
3:52:42in the video so you guys could see what
3:52:43my thought process is. Uh it's taking
3:52:45quite a while to do, which I think is
3:52:46positive. If I go back to Appify, we go
3:52:49to runs. Okay, looks like it's starting
3:52:51the crawler. So, I've actually initiated
3:52:52the crawler using my API call. Looks
3:52:55like it is now done. Okay. If I go back
3:52:57here. Oh, nice. Looks like I got the
3:52:58data. Awesome. So, I have the transcript
3:53:00done. All right. So, I mean, that was
3:53:01really easy, right? Super super easy.
3:53:03Very straightforward. Why don't I rename
3:53:04this and then I'll just call it get
3:53:06transcript via ampify. There you go. And
3:53:10now I can go back here and if you think
3:53:11about it, I could actually kind of like
3:53:13just check this first box. Okay. So, or
3:53:16check both of these box. Uh, actually,
3:53:17I'm not done that. I'm just done this.
3:53:19Let's make this really thick. There you
3:53:21go. So that step is done. So the YouTube
3:53:24podcast URL input step now. So if you
3:53:26think about it now, what do I need to
3:53:27do? I need to verify that I could
3:53:28actually get input in. Right? So in NAN,
3:53:30as you guys know, there there a bunch of
3:53:31different triggers I could do. This
3:53:32one's just a test workflow trigger. What
3:53:34I'm going to do is I'll go back here and
3:53:35then what I want is I want um just a
3:53:36form. So N form and I'll go on a new
3:53:39form event. So what I'll say is insert a
3:53:43podcast get content.
3:53:47Hey, this is a AI podcast repurposing
3:53:51engine. If you insert a YouTube link to
3:53:54a
3:53:56podcast, we'll generate a bunch of
3:53:58formatted content for you and post to
3:54:02relevant social media platforms. Okay,
3:54:04what here I will say is YouTube, maybe
3:54:07podcast. Uh, let's just go YouTube URL,
3:54:09right? Field type will be what do we
3:54:12got? I guess we'll just do
3:54:14text. And then I'll say it's required.
3:54:17And then I think that should be good.
3:54:20Yeah. Let's now test
3:54:22this. Let's uh where was that URL a
3:54:25moment ago? Oh, here we
3:54:26go. Let's copy this link. I got it right
3:54:29over here. So, I'm going to paste this
3:54:32in now. Insert a podcast. Get content.
3:54:34Very cool. Going to submit it. Okay,
3:54:36cool. So, I can get the content, which
3:54:38is nice. So, now I'm just going to feed
3:54:40this in as my variable. Uh, I should
3:54:42probably keep the one clicking test
3:54:43workflow actually because that'll just
3:54:45allow me to test the flow really easily.
3:54:46But anyway, um, as you can see, I got
3:54:47the form submission. So, what do I have
3:54:48to do now? Well, now I'm just going to
3:54:49make this dynamic. I'll go expression.
3:54:51Then I'll open up this big thing in an
3:54:53editor. And then right over here where
3:54:54it says start URLs, I'm actually just
3:54:56going to feed in one start URL. It's
3:54:58going to be this YouTube URL. So, this
3:55:00is the result. This is what it's going
3:55:01to look like. That looks good to me.
3:55:02Cool. Automation is mapped. We are good
3:55:04to go, baby. Everything should be fine.
3:55:06Awesome. And I think what I'll do here
3:55:08is I'll probably pin the output as well
3:55:09just so I can always run this on the
3:55:11exact same um video. Okay, cool. All
3:55:14right. So now what we have done is we
3:55:17have submitted our form and we've also
3:55:20gotten the transcript. Now the next
3:55:22question is how are we going to generate
3:55:25content for Instagram, Facebook,
3:55:28LinkedIn? Then also maybe some
3:55:30timestamps or some hashtags or something
3:55:32like we just need some way to generate
3:55:34uh video ideas. Maybe we could even use
3:55:36h genen. That might be pretty cool,
3:55:37actually. That' be pretty interesting.
3:55:39Maybe I'll maybe I'll screw around with
3:55:41that. If you guys have seen the demo
3:55:42already, you guys are like, "Well,
3:55:43obviously he's going to use Hey Gen,
3:55:44right?" But I I'm not at that point yet.
3:55:46Um, okay. Uh, Instagram content here.
3:55:49Let's think about this. So, I I need to
3:55:51now create um I need to have some sort
3:55:54of way to spin up three or four
3:55:56different model calls. Then for each
3:55:57route, I need to produce something. So,
3:55:58I need to produce some Instagram
3:55:59content, some Facebook content, some
3:56:01LinkedIn content, some timestamps,
3:56:02hashtags, whatever.
3:56:03I guess what I'll do here is uh do they
3:56:05have a router here? No, they don't
3:56:08really have a router. So, I think I have
3:56:09to use a merge node. Yeah, I think I'm
3:56:11going to have to do this. I don't know
3:56:12for sure, but whatever. Let's do um
3:56:15OpenAI. So, go to OpenAI and then I'm
3:56:18going to message a model right over
3:56:20here. Then I have all my credentials
3:56:22already connected, so I'll just use the
3:56:23YouTube February 4th one. But, um you
3:56:25know, if you don't know how to do this,
3:56:26it's pretty easy. You just go like to
3:56:27your OpenAI dashboard and then you grab
3:56:31the API key and then you don't need the
3:56:33organization ID anymore which is nice
3:56:35and then just do the connection. So once
3:56:37I have this, let's think resource text
3:56:39message model. Okay, I'm just going to
3:56:41select a model right now and I'm going
3:56:42to make it like let me check model
3:56:44context
3:56:45windows. Um, open a do we have a list? I
3:56:49just want the one with the biggest
3:56:50context window right now to be
3:56:52honest. Okay, we got a we got a couple.
3:56:55Let's just check. Let's just check all
3:56:57of
3:57:00them. Let's just compare all
3:57:04these context. Okay, there you go. So, I
3:57:07can see it says context window. So,
3:57:09128,000 128,000
3:57:11200,000 128,000 128,000. All right.
3:57:14Well, I mean, if you think about it,
3:57:15they're all 128,000. How many tokens is
3:57:17uh 10,000
3:57:18words? 7,000. So, we should actually be
3:57:21good. I maybe I was a little bit ahead
3:57:22of myself here. We should be good. I'm
3:57:24going to use the GPT40 for now and then
3:57:25I'll figure the rest out later. So, um,
3:57:29yeah, let's go to that. So, I'm going to
3:57:30use GPT 40. This is the one. Let's go
3:57:32back to my init flow and let's just go
3:57:3440. Zoom in a bit for all
3:57:38y'all. What I think makes the most sense
3:57:40at this point is we should probably have
3:57:43one model generate a bunch of things to
3:57:46talk about first based off the
3:57:48transcript. Then we feed those things to
3:57:50talk about to other models and then
3:57:52they'll take those items and then
3:57:54they'll use them to generate stuff. I
3:57:55think that makes the most sense. So you
3:57:57are a helpful intelligent um let's say
3:57:58content writing assistant that works
3:58:00with transcripts. What I always do is I
3:58:03start with a system prompt. Okay, system
3:58:05is just how the model identifies. And I
3:58:07find that when you make the model
3:58:08identify really good at something, it's
3:58:10very, you know, you're helpful and
3:58:11intelligent and you work with
3:58:13transcripts, it's just more likely to do
3:58:14a slightly better job working with those
3:58:16things. Next up, I add a user prompt.
3:58:18So, here's where I actually define the
3:58:19task. So, you take as input a long
3:58:22meandering transcript and you identify
3:58:24the most
3:58:27interesting, let's say, um, the 10 most
3:58:30interesting, engaging points. You then
3:58:33generate a JSON containing those
3:58:36interesting, engaging points in this
3:58:39structure. Let's do this. So, now we're
3:58:41going to go JavaScript object notation.
3:58:44And what I want to do is I want to give
3:58:46it um a good structure. So the first
3:58:49thing I'm going to do is I will say
3:58:51sections. Let's do that. Now I'm going
3:58:53to generate an array. Okay, we're going
3:58:56to start with this array over here. And
3:58:58I know this isn't like actually proper
3:58:59proper formatting, but that's okay. Now
3:59:02what I want is I want another
3:59:05object inside of
3:59:07that. Uh I'm sorry I was wrong where
3:59:11basically I generate this. We're going
3:59:14to have number and then I'm just going
3:59:16to put
3:59:18one. Then over here I'm going to
3:59:23say
3:59:25paragraph transcript.
3:59:31paragraph
3:59:34of the relevant part of the transcript
3:59:38goes here. Okay, this is actually
3:59:40getting really annoying. I thought I
3:59:42could like make this look nice, but I
3:59:44can't. So, I'm just going to go to JSON
3:59:45formatter. It's a lot easier. Just
3:59:47format it. It'll automatically take care
3:59:48of this for you. Okay. Uh, cool, cool,
3:59:51cool. Let's just copy this and we can
3:59:52paste this back as the intro. So, number
3:59:54one, paragraph transcript paragraph the
3:59:56relevant part of the transcript goes
3:59:56here. So, basically, I wanted to clip a
3:59:58part of the transcript. Then I also
3:59:59wanted to like generate some something
4:00:01else. Description of
4:00:04section, a description of why this point
4:00:08is
4:00:09interesting and some direct and some
4:00:11ways to make it even better. And then in
4:00:15addition, I also I love um having AI do
4:00:17this sort of like meta stuff where you
4:00:19give it a piece of content and then it
4:00:20actually takes the piece of content and
4:00:21does something with it like it provides
4:00:23critique. It comes up with some new way
4:00:24to do it better or something. And then I
4:00:25also want one other thing. I want like
4:00:27deep explanation and I'll
4:00:30say a one paragraph write up based on
4:00:35the transcript section that expands upon
4:00:39its
4:00:41points, clarifies any
4:00:45ambiguities, generally fills in the
4:00:49blanks. Okay, let's just run with that.
4:00:52I think this is going to work pretty
4:00:53well. So, this is going to be the JSON
4:00:54structure that it's going to generate,
4:00:56right? something like this. Is this an
4:00:58optimal or ideal prompt? No, not really.
4:01:00It's pretty lengthy to be honest, but
4:01:02that's
4:01:04okay. Generate 10
4:01:07points. The transcript,
4:01:10okay, is below. I'm going to add another
4:01:13message. And here's going to be the
4:01:15user. And what I'm going to do here is
4:01:16I'm actually just going to feed in the
4:01:17transcript. So, we can't get it out. So,
4:01:19we actually have to run it one more
4:01:20time. So, let me just test this while
4:01:22this is testing. Uh, basically what I'm
4:01:24going to do is I'm going to put the
4:01:25actual transcript right over here. Then
4:01:27I'm going to have the assistant return
4:01:28the message afterwards. Let's go. Output
4:01:30content is JSON. Let me see if there's
4:01:32anything else I need. Temperature I
4:01:33always like to set a little bit lower. I
4:01:34just find it gets kind of too
4:01:37interesting. And then let's actually add
4:01:39some Let's put some rules down
4:01:42here. Write in a
4:01:45Spartan Conic tone of voice.
4:01:49Copy the transcript sections exactly as
4:01:52they
4:01:56are. Look for unorthodox or interesting
4:02:01ways to
4:02:12make. Let's change this to context and
4:02:14feedback um to make the content better
4:02:16in the context and
4:02:20feedback object. Cool. Now, what I'm
4:02:23going to do is I'm just going to feed in
4:02:24the transcript right over
4:02:27here. Let's actually feed in the video
4:02:29title, too. That'll provide even more
4:02:31context. Cool. And then, uh let's just
4:02:34run this and see what happens. This is a
4:02:36very long transcript, right? It's a long
4:02:37ass transcript. So, we want to make sure
4:02:39that the content that it generates is is
4:02:41good. So because of this, you know,
4:02:43think about it from my perspective. I'm
4:02:44at the point where I'm trying to do
4:02:45this. I need to make sure that I
4:02:47understand what the video is about if
4:02:49I'm using it as a test and that I can
4:02:51meaningfully evaluate the output to see
4:02:53that it's good and not just like total
4:02:55make believe stuff. Now, this is very
4:02:57long. Because it's very long, it's
4:02:58obviously going to take a while to do.
4:02:59It's also going to cost a fair number of
4:03:01um input tokens. So, let's actually
4:03:03figure out how much this would cost
4:03:05realistically. Inputs $2.50 per what is
4:03:09this? per million per million tokens.
4:03:12All right. Well, that's really not that
4:03:12big of a deal. I just fed in like uh
4:03:1412,000 tokens or something. So, one
4:03:1812,000 is 1 uh 10,000 is 1/100th of 1
4:03:21million. So, 1/100th of this is 2.5
4:03:24cents, I believe. So, it cost me 2.5
4:03:25cents a that's not a big deal at
4:03:31all. Okay, we got the
4:03:37output. Very interesting.
4:03:41Very cool. Very cool. I want it way
4:03:43longer. I don't like how long the um the
4:03:45the section is right now. I think that
4:03:48we could do a lot better if it was
4:03:55longer. Yeah. I mean, these are just
4:03:57this is just like five
4:04:02words. Okay. Well, it's very interesting
4:04:05because I've uh I'm the one that created
4:04:07this content so I understand what I was
4:04:08talking about and uh it actually
4:04:10basically went through top to bottom and
4:04:11just extracted the various points I was
4:04:13making. It's like okay point one this
4:04:14point two that point three that. Make
4:04:16sure your paragraph
4:04:19transcript string is
4:04:21long longer than just one
4:04:23sentence. Try and capture at least one
4:04:26whole
4:04:27paragraph of the transcript. Okay. So,
4:04:30I'm just going to test this again. And
4:04:32while it's running, which is going to
4:04:33take a little bit of time, I'm going to
4:04:35um go next. And now that I have this, I
4:04:38think what we can do is we just have
4:04:39another three or four depending on the
4:04:41content. And then I'll just I'll paste a
4:04:45bunch in. So, this might be like
4:04:47Facebook, this might be Instagram, this
4:04:49might be LinkedIn, this might be another
4:04:51one. Then I'll combine them all with a
4:04:53merge node just into like one big
4:04:55object. Or hold on a second. Actually,
4:04:57what I think I'll do, we should probably
4:04:58add these to a Google sheet or something
4:05:00instead of just post them, right? Like,
4:05:02it'd be silly to post all these
4:05:04immediately. So, we should probably just
4:05:05add them to a Google sheet. What are you
4:05:06going to do? Post 10 pieces of content
4:05:08immediately on all
4:05:10platforms. You you'd need some some
4:05:12serious nuts to do that. So, it's
4:05:15probably not the best move. Um, okay.
4:05:16Well, let me cross our bridge when I get
4:05:18to it. I guess for now, what I'm going
4:05:19to do is I'm just going to generate a
4:05:20bunch of content. So yeah, you can
4:05:21actually have multiple routes like this
4:05:23pretty easily that just stretch and then
4:05:25as long as you have a merge node at the
4:05:26end that combines the outputs, it'll
4:05:27it'll just run them all. So I guess we
4:05:29could do this. We could post post or we
4:05:32could just add all these to a Google
4:05:34sheet or something afterwards. Anyway,
4:05:37this looks good. Yeah, this is a lot
4:05:41longer. Cool. Nick introduced the first
4:05:44major hack. Okay, Chad GBT to write a
4:05:46story about peanuts. Cool. Cool. Cool.
4:05:47Um, all right. So where we at right now?
4:05:49We just generated the transcript that
4:05:51we've just generated something which we
4:05:53can use to route the content later. So
4:05:55that's good. So now we just need to go
4:05:57through our routes. So I'm just going to
4:05:58do an Instagram content route first,
4:06:00then a Facebook content route, then a
4:06:01LinkedIn content route, and then finally
4:06:02um yeah, we'll figure that out
4:06:04afterwards. So why don't I go over here
4:06:06and I'll click
4:06:07rename Instagram post generator. Now the
4:06:11first thing I'm going to want to do is
4:06:12I'm just going to want to figure out
4:06:13what the guidelines are for this. So,
4:06:15what are Instagram post length
4:06:18restrictions or
4:06:20something? Looks like we can write 2200
4:06:23characters. We caption, we truncate the
4:06:25caption at 125. We have 30 hashtags.
4:06:28That seems pretty reasonable. So,
4:06:30basically what I need to do is I just
4:06:31need to shorten it and then say write
4:06:32under 2200 characters. How many words is
4:06:35that? 300 words. So, I'll just have it
4:06:38generate me like a short snippet like a
4:06:39like a paragraph basically. Two
4:06:40paragraphs or something. That sounds
4:06:42good. I'm back over here. So, Instagram
4:06:44post generator. Uh, what I'll do is I'm
4:06:46going to write a new prompt. Your
4:06:48helpful, intelligent content writing
4:06:49assistant that generates Instagram
4:06:52posts. You take as
4:06:56input information about a point. I just
4:06:58realized I'm going to have to change the
4:06:59structure here because we can't just
4:07:00feed in all this, right? a section of a
4:07:03transcript along with some
4:07:05observations about that section and some
4:07:09points of
4:07:11feedback and use it to
4:07:14generate clean, beautifully formatted
4:07:17Instagram posts in this
4:07:22format. We will do Instagram post. We
4:07:26will then do uh we're only going to do
4:07:28one
4:07:30post a clean beauty format Instagram
4:07:33post in this format. We'll do Instagram
4:07:35post and then since it's just
4:07:37one I think we can actually just go
4:07:40Instagram post
4:07:42copy then we'll go copy goes here. Then
4:07:45what I'll do is I will take this and
4:07:47maybe we'll we'll generate an image with
4:07:48this as well and then feed that back. So
4:07:50write in Spartan Lonics and a voice.
4:07:51Copy any transcript sections. Uh no
4:07:54let's not do that.
4:07:57Instagram posts truncate after a
4:08:03paragraph write an engaging first
4:08:06paragraph and then context around the
4:08:08rest of the point underneath that
4:08:12paragraph. At the end of the post, add
4:08:17hashtags. Let's say five relevant
4:08:21hashtags. And then yeah, that should be
4:08:23pretty good. Just leave that
4:08:26there. Then I'll
4:08:30say right over here. Oh yeah. So I can't
4:08:34actually map this until I figure out the
4:08:35structure. Right. So basically what
4:08:37we're going to have to do um if you
4:08:39think about it is we just need to we
4:08:40need to loop over all these. So a
4:08:42variety of different ways you could do
4:08:43the looping. You could
4:08:45um uh we're going to have to aggregate
4:08:49this I
4:08:50think because it outputs one item as you
4:08:54see up here and we needed to output like
4:08:56a more than one item if we wanted to do
4:08:58the loop automatically. Also just in um
4:09:01historically uh if we hit all these up
4:09:04immediately and we just try and do 10
4:09:06API calls uh simultaneously it usually
4:09:09just breaks the NAN flow because we hit
4:09:10rate limits and stuff. N doesn't have
4:09:12very good like built-in rate limits. So,
4:09:14I'll probably do the loop over item
4:09:15split in batches. If you've never used
4:09:17this before, the way this works is you
4:09:18feed in the item, and then what it'll do
4:09:21is it'll loop over all of that data over
4:09:24and over and over and over again until
4:09:25you reach the last item, and then it'll
4:09:27go down the route. So, yeah. Um, I think
4:09:32what I'm going to do is this replace me
4:09:36thing is about to be a replaced.
4:09:39So, I just want to make sure I can
4:09:40actually feed multiple routes into this.
4:09:43Can I? Does it work? Yeah. Okay, I
4:09:46should be able to do this. Cool. This is
4:09:47going to be a very complicated looking
4:09:49um system. Sure, it's going to sell well
4:09:52uh on YouTube anyway. So, I'm going to
4:09:54loop over now. And what I need to do in
4:09:56the loop over items uh node is I need to
4:09:59feed in just this array. So, how do I
4:10:02feed in just the array? Uh well, as
4:10:04input to this loop over items node, I'm
4:10:06going to use the the split out. Yes, we
4:10:08need this. So, the fields that we're
4:10:10going to split out are going to be this
4:10:12sections array. We feed in the sections
4:10:15array. If we test this now, we should
4:10:17get 10 items. 1 2 3 4. Perfect. Now that
4:10:21we have these 10 items, we can actually
4:10:22feed that output into the loop over
4:10:23items. So, we're going to split out
4:10:25these 10 items. And then we're going to
4:10:26go one at a time, basically calling all
4:10:28of these APIs. Okay. Now that we've kind
4:10:31of figured all that stuff out, awesome.
4:10:32We can actually get going with the
4:10:34Instagram post generator. Let's click on
4:10:36this again. And then well we need to
4:10:37execute the previous nodes if we want to
4:10:39get all the data. So we have those 10
4:10:41items. Now what am I going to do? Well
4:10:43I'm just going to feed in the specific
4:10:45item. So I will say transcript going to
4:10:48feed this
4:10:49in. Um oh we need to index the item now.
4:10:52Uh the reason why we have to index the
4:10:53item is this just doesn't know which
4:10:54item we're specifically referring to.
4:10:57What we're going to have to do is we're
4:10:58going to have
4:11:00to going to grab this first.
4:11:05It's not able to get the
4:11:08specific one, is
4:11:10it? I don't know. I guess we'll find
4:11:12out. Way that Naden does their items is
4:11:17um always sort of interesting. I did
4:11:20execute the previous node, so I'm not
4:11:21getting this preview, which is annoying.
4:11:23Let me go back over
4:11:28here. Yeah.
4:11:31Okay. Yeah. So you can uh it's just when
4:11:34you use the split in batches sometimes
4:11:37there's a problem with um the way that
4:11:38it's rendered. Anyway, uh cool. So we're
4:11:41just feeding in these variables directly
4:11:43one at a time, right? Because we only
4:11:45receive one item as an output. Cool,
4:11:47cool, cool. So uh awesome. Well, let's
4:11:49just give this a try and let's see what
4:11:50happens. All right. I don't want to feed
4:11:51in all 10 items. So what I'm going to do
4:11:53is I will just test this out on one
4:11:56item. So, I think if I just click test
4:11:57tab, we're only going to run this once,
4:11:58not 10 times, which is
4:12:01nice. Okay. Unlock the full potential of
4:12:03GBD models. My top three prompt
4:12:04engineering hacks from my journey since
4:12:062019 with GBD2. Leveraging these tools
4:12:07in every business. I've gathered
4:12:08insights that will transform your
4:12:09approach ready from your tool to
4:12:11autonomous team player. Let's dive in.
4:12:12No, I do not like this. I think this is
4:12:14written pretty poorly.
4:12:18So, and
4:12:20points, no leading
4:12:23questions,
4:12:26emojis. Write like
4:12:29a business professor talking bluntly to
4:12:34his students. Let's try this one more
4:12:36time.
4:12:42except
4:12:43simpler. Favor words with fewer
4:12:49syllables. Cool. Let's try that one more
4:12:55time. Okay. I mean, this looks
4:12:57substantially better already, which is
4:12:58nice. Cool. Um, now we've generated an
4:13:00Instagram post. We can do uh a couple
4:13:02things with this if you think about it.
4:13:04We could also like generate an image
4:13:06with this. So, I don't believe we're at
4:13:08the point where the image generator that
4:13:10is being used is the new GPT4 image
4:13:12generator. I think we're still using
4:13:14Dolly. What I'm going to do though is
4:13:16I'll see if I could feed in the previous
4:13:20description, an image that represents
4:13:22the
4:13:23concept. Let's see if we generate an
4:13:25image. What's going to
4:13:28happen? See how trash this
4:13:31is. There are a variety of other things
4:13:33that we could do as well. Or we could
4:13:35like generate some branded stuff. Cute
4:13:37little kawaii anime like cartoon
4:13:40characters or something. That'd be
4:13:42sweet. Um, unfortunately I can't just
4:13:44use the I can't use the um OpenAI API
4:13:47like the awesome one. Yeah, I'm not I'm
4:13:49not a fan of this stuff. It's kind of
4:13:52trashy. Um, an
4:13:55image handdrawn cartoon
4:13:59style should have one character in the
4:14:02middle.
4:14:04That's all. Let's just try that. My
4:14:07prompt engineering has gotten
4:14:10substantially simpler over the course of
4:14:12the last few months. Let's put it that
4:14:14way. Uh unfortunately getting spoiled
4:14:17talking to these extraordinarily smart
4:14:18models. So when you talk to a dumber
4:14:20one, uh takes a little bit of time to
4:14:22get up and
4:14:25running. Okay, let's view this puppy.
4:14:28What are we looking at here? hip H
4:14:30Spanishpanic
4:14:33speakers. Um
4:14:36h handdrawn cartoon
4:14:41style. Let's just say handdrawn
4:14:45um
4:14:48cartoon. And let's go over here and have
4:14:50this just generate one additional
4:14:52object.
4:14:59Short image
4:15:05description. A one-s sentence
4:15:10description of an
4:15:13image that illustrates the concept. The
4:15:16description must have one simple
4:15:19character like a
4:15:21bunny or an animal.
4:15:26and B be catered
4:15:29to kids audience to a younger
4:15:32audience. Let's do that. Looks good to
4:15:35me. So now I'm just going to have to
4:15:37test this and I'm actually going to have
4:15:38to produce the outputs here because I'm
4:15:42then going to need to split them out and
4:15:43then loop them over the items and then
4:15:44do my my post generation, which is nice.
4:15:46Give that a try.
4:15:49And this done route I'll probably end up
4:15:51putting underneath to be honest because
4:15:54this is going to be pretty chunky. Uh
4:15:56maybe I should just do all of this here.
4:15:58Yeah, you know what? I'll probably do it
4:16:00all over here actually. We'll have an
4:16:01Instagram post
4:16:03generator, open AI image. Or maybe we
4:16:06should just generate the open AI image
4:16:07before the Instagram post generator now
4:16:09that I'm thinking about it because then
4:16:10we can just use the Instagram post and
4:16:12all the other stuff that we need to
4:16:14do. H anyway, let's see how that goes.
4:16:18Just testing these one by one
4:16:20here. And then let's now test this. Oh,
4:16:25sorry. I used the wrong one here. What
4:16:26we want is we want um loop over items.
4:16:29And we
4:16:30want Oh, yeah. Sorry. I I need one more
4:16:33piece of instruction. No
4:16:37text. Description should should never
4:16:40talk about text.
4:16:43Okay. All right. Uh so what are we going
4:16:46to do here? We are going to handdrawn
4:16:48cartoon
4:16:49style. Then we're going to feed this
4:16:52in. Maybe we'll
4:16:55go colorful
4:17:00watercolor. Colorful soft watercolor
4:17:04of a bunny stacking colorful blocks.
4:17:07This isn't going to be ideal because
4:17:08it's going to say a bunny um with text
4:17:11in it. That's not really what we want
4:17:13the image to do.
4:17:16Let's turn on respond with image URLs.
4:17:18By the
4:17:19way, can we go
4:17:21style hyperreal and dramatic? No, we
4:17:23want
4:17:25natural. I just made some changes. So,
4:17:28um, that looks pretty cute. Yeah, I
4:17:30think we could probably do
4:17:32that. And then what we want for
4:17:35quality, standard or HD? H, no, we'll
4:17:37probably go with standard. And then we
4:17:39want resolution. Got a couple of
4:17:41different options here. Let's go
4:17:42Instagram post
4:17:43resolution 1080 x 1080. So 1024 x 1024
4:17:47is reasonable. Like it's not going to be
4:17:49uh as pretty, but I think it's going to
4:17:50be pretty good. And yeah, this one has
4:17:51text in it, but like imagine we're just
4:17:53going to get rid of most that text in
4:17:54future ones. So that should actually be
4:17:56pretty fine. Maybe you have some branded
4:17:58channel that does something like this or
4:18:00I don't know. Uh like if you think about
4:18:02it, there's like three or four major
4:18:03styles that you could have AI generate,
4:18:04right? You could do like some sort of
4:18:05handdrawn stuff if you want to be
4:18:06serious. You could do if you just check
4:18:08out like Alex
4:18:09Hormos's Let's check this out here. Hold
4:18:12on. Hold
4:18:15on. Yeah. Stuff like this. Right now,
4:18:18he's using GPT40 image to do that. But
4:18:20as as I'm sure you can imagine, if you
4:18:22just have some style like this and it's
4:18:24like a standardized style, then you can
4:18:26generate like an almost infinite amount
4:18:27of content with a podcast clip. There's
4:18:29another one in Simpson style. I think
4:18:32he's publishing a ridiculous amount of
4:18:33content. I mean, this is like a week ago
4:18:35and he is like 50, right? So, that that
4:18:37would probably be my thoughts. That's
4:18:38probably how I'd do it. Since we're
4:18:39using Dolly, it's not going to be as
4:18:42clean, but I imagine we're probably
4:18:44going to have access to that API pretty
4:18:45soon. Okay, so Instagram post generator.
4:18:47And then here, we will call this
4:18:49generate image. Now, this will also
4:18:51return an image link. So, if I generate
4:18:54this new one now, we should have an
4:18:55image URL, right? The image URL we can
4:18:57just feed directly into the Instagram
4:18:59post node. We're feeding in some
4:19:01additional parameters here. So, it's
4:19:02going to change how long it takes to
4:19:04generate. Looks like it did some
4:19:06revisions. Oh, that's cute. I like this.
4:19:09Yeah, nice. Okay, we have everything. We
4:19:11can actually go to I think what we need
4:19:13is the Facebook graph API. Could be
4:19:17where we make a post. Yeah, most likely.
4:19:20So, okay. I'm probably going to have to
4:19:22muck around with this for a bit before I
4:19:23can figure out
4:19:26exactly. And I think in order to do
4:19:29this, the credential that we set up, we
4:19:31have to get an access token which we
4:19:32generate from something else. So it's
4:19:34going to take me a minute to figure that
4:19:36out. And I'm just gonna I'm just gonna
4:19:37allow that to be the last thing that I
4:19:40do. From here though, as you can see, we
4:19:41have a pipeline that we can use to
4:19:42generate everything else. So now I just
4:19:44duplicate these. Right. So Instagram
4:19:46post generator. Very cool. Let's go over
4:19:49here and then let's go LinkedIn post
4:19:52generator. Then down over here, let's go
4:19:54uh what else did we have? Facebook post
4:19:56generator.
4:19:58Now we just have to like very lightly
4:19:59change the parameters
4:20:01um the prompt
4:20:04basically. So instead of Instagram post,
4:20:06but we'll say Facebook
4:20:09postcopy, Facebook
4:20:11post, then no
4:20:14hashtags, Facebook post. Let's say
4:20:16Facebook postcopy
4:20:27guidelines. Okay, this is what looks
4:20:29like a landscape photo. So we're going
4:20:31to have to generate a slightly different
4:20:32image size for that.
4:20:34Okay. And then I don't really think
4:20:35there's any text restrictions. You
4:20:37probably go pretty long. Um, this one is
4:20:39not wired up right now, which is why
4:20:41we're getting that. So, let's go
4:20:42here. Oh, sorry. Was this the LinkedIn?
4:20:45Was I just editing that on the LinkedIn
4:20:46one? Probably. Oh, yeah. My bad. Uh,
4:20:50well, let's go LinkedIn post.
4:20:53Copy. LinkedIn
4:20:57post. And then this one here is
4:20:59LinkedIn. Anything Anything else here
4:21:01say Instagram? I don't think anything
4:21:02else here says Instagram. We're probably
4:21:04good. LinkedIn post. Uh, okay. Well,
4:21:07what's the LinkedIn post guidelines? So,
4:21:08LinkedIn post. First of all, let's check
4:21:11the dimensions. So, it's widescreen as
4:21:14well. Let's see when it
4:21:16truncates. All right. So, honestly, this
4:21:18is very similar to Instagram.
4:21:20Realistically, I'm just not going to
4:21:21make any adjustments to this. This is
4:21:22going to be a good nugget that anybody
4:21:24could use to build out like more nuanced
4:21:25or higher quality systems, I would say,
4:21:27by mucking around with the prompt,
4:21:28making it a little bit better. And then
4:21:30here, we're going to generate a LinkedIn
4:21:32image.
4:21:33Um, just because this doesn't allow you
4:21:35to change the
4:21:37uh have multiple of the same titles, I'm
4:21:40just going to like add some acronyms
4:21:42here like Facebook image and stuff just
4:21:43so that we can have different um titles
4:21:45on them. This LinkedIn image is not
4:21:47going to be at 1024. Uh, we're going to
4:21:49have to make it like wider screen,
4:21:50right? So, sorry, I've already forgotten
4:21:52this one. LinkedIn post
4:21:55resolution. This
4:21:58is Well, actually, we can we can do
4:22:00both. We can do 1080 x 1080 pixels. So,
4:22:02actually, I'm just going to do 1080. So,
4:22:03yeah, I'm just going to do square. I
4:22:05think Facebook was the one that was
4:22:06wider screen,
4:22:08right? Yeah. So, I'm going to go 1024 x
4:22:101024. That looks fine to me. It was the
4:22:12Facebook one that I think was different.
4:22:16It was
4:22:171792. So, this is about as wide as we
4:22:20can get. It's not the best, but I think
4:22:21we'll just deal with it for now. Okay,
4:22:24I'm going to do that here. Okay, cool.
4:22:26So, now we're basically going to be
4:22:27generating three. And then we need to
4:22:30change this. Go LinkedIn. Do this.
4:22:33Create a post. Very cool. We got to add
4:22:35credentials and stuff. I'll deal with
4:22:36all that stuff afterwards. Um, I think
4:22:38that's I think that's basically good,
4:22:40honestly. And so, if you think about it,
4:22:42what we're going to do is one, two,
4:22:45three. We're going to have to do after
4:22:47this, we're going to have to merge all
4:22:48the outputs of the stuff together. By
4:22:51merging the outputs of all the stuff
4:22:52together, um, we're going to get stuff
4:22:55that we could put in like a Google
4:22:56sheet, for instance. Actually, maybe
4:22:57maybe instead of us um doing the posting
4:23:00directly in here, we should add them to
4:23:01a queue. Hey, because if you think about
4:23:03it, like yeah, what are we going to do?
4:23:04Post all 10 posts immediately? No, we
4:23:06should we should just add them to the
4:23:07queue. So maybe we should do the posting
4:23:09and stuff like that in a different
4:23:10scenario or a module or workflow, I
4:23:12should say. Maybe for now what we
4:23:15do so we just merge all
4:23:18these merge all these outputs. We'll do
4:23:21three
4:23:23inputs. Thank you kindly. And this is
4:23:26number three. And now that we're merging
4:23:28these, basically what I'm thinking is we
4:23:30make a database of posts for all these
4:23:32different platforms and then every day
4:23:34or whatever, just go through and post.
4:23:36That way they'll be relevant to the
4:23:37previous podcast. And that logic is
4:23:39pretty simple to put in place and
4:23:40probably makes the system a lot more
4:23:42valuable cuz if you just have a fragile
4:23:43system where you put a form thing in and
4:23:45then it just forces you to post 10
4:23:46times, I think that'd be kind of dumb.
4:23:47No, no other way to like verify that the
4:23:49posts will always be different. Yeah, I
4:23:51think this is what people want. Okay.
4:23:52Anyway, there's a variety of different
4:23:53ways you could do things here. We could
4:23:54just we could just append. Oh, is it
4:23:55going to have to execute all the
4:23:56previous ones? Right, it will cuz we
4:23:58haven't generated the images yet. So,
4:24:00let's generate image three. That one's
4:24:01going to take longer cuz it's bigger if
4:24:03you think about it. The other ones
4:24:04were,024 by,024. This one was like 17
4:24:07something. So, I think that's like
4:24:08mathematically it's not like a 1.7
4:24:11times, it's like a three times or
4:24:12something. Um, just because there's so
4:24:14many more like total pixels in the
4:24:16image. Okay, that's the LinkedIn post
4:24:18generator. Let's see what an example of
4:24:19this appending looks like. We should
4:24:21just get an object with like all of the
4:24:24LinkedIn, Instagram, Facebook,
4:24:27right? Okay. So, the output is we get
4:24:30three items. Yeah. I don't like the
4:24:31three items being all here because if
4:24:34you think about it, what am I going to
4:24:35do with these three items? I got one
4:24:36item here, one item here, one item here.
4:24:38Well, I don't want three items. I just
4:24:39want one item as an output. And then I
4:24:40want the one item to be like Facebook
4:24:42post, Instagram post, whatever. And then
4:24:43I can map them a lot easier, right? So,
4:24:45I'm pretty sure we're going to have to
4:24:46do the combine. I think I just want to
4:24:47combine all of them.
4:24:50Oh, can I only do
4:24:53two? I don't know what this last item is
4:24:57here. Yeah, it doesn't look like I can
4:24:59actually do three, unfortunately. Yeah,
4:25:01sorry. We could just use a set. That'd
4:25:03be way easier. Let's go set here. We're
4:25:06going to take in the previous image.
4:25:08Okay, I'm just going to do it all in
4:25:10JSON. So, I'll say image
4:25:14URL. Image URL is going to be right over
4:25:16here. Then right over here in the
4:25:19middle, um, we'll have the post body. It
4:25:23looks like I'm still outputting an
4:25:24object called Instagram post copy.
4:25:27Trash. That's not very good. Should
4:25:29probably go back here and then adjust
4:25:31that,
4:25:33eh?
4:25:35Yeah. Oh, you know what? I just left it
4:25:37as Instagram
4:25:40everywhere. My bad. You guys probably
4:25:43all saw that and were like, man, Nick is
4:25:44such a
4:25:48Um, it's true. I am. But the best part
4:25:52of it all is you can make
4:25:54mistakes. Just a little happy accident.
4:25:56Then you can go back here and you can
4:25:57fix it. I think I need to change the
4:25:59LinkedIn um object as well, right? Okay.
4:26:02No, I did. All right. Anyway, that's my
4:26:04happy accident. Cool. So, now that we
4:26:05are editing the fields, what are we
4:26:06going to do? We're going to have this
4:26:09actually be Instagram post
4:26:12copy. So, I'm going to feed that in. If
4:26:14you guys aren't sure why I'm doing this,
4:26:16um, basically I need a way that I could
4:26:18reference this later
4:26:20on. Just going to call Facebook post
4:26:23copy. It's not going to do anything
4:26:24right now, but that's okay. And then
4:26:26here we'll say
4:26:28um
4:26:30platform and here we'll go like
4:26:33Facebook. Okay. So I'm basically
4:26:36remapping stuff here so that I have the
4:26:38copy, the image URL, the post body, and
4:26:40then the platform. So now I'm just going
4:26:43to copy this
4:26:44Well, I guess I can't copy just yet. I
4:26:46have to copy the whole uh node. Then
4:26:48right over here, I'm just going to
4:26:49delete this. And then I'll connect this
4:26:51to my edit
4:26:52fields. Then now what I'll have
4:26:55is I just deactivated that, but um it's
4:26:59okay. We're going to go platform
4:27:01LinkedIn. That should say LinkedIn post
4:27:05generator, right? LinkedIn postcopy.
4:27:10Doesn't look like I can get that path
4:27:12back to the node cuz it's under Oh,
4:27:13right. There you go. Okay. So, we'll
4:27:16have the image URL, the post body, the
4:27:18platform here. That's good. Let's uh
4:27:20reactivate that. Then up top, let's copy
4:27:23this. Paste this over
4:27:26here. Feed this in. And then, if you
4:27:29think about it now, what are we going to
4:27:31get? We're going to get
4:27:32[Music]
4:27:33um the ability
4:27:36to
4:27:39automatically determine in subsequent
4:27:43nodes why
4:27:45uh sorry which platform the data is
4:27:47coming from. So, I'm just going to call
4:27:50this set
4:27:53Facebook. And here, I'll call this
4:27:57set LinkedIn JSON. And here, I'll call
4:28:00this set IG JSON. Okay. So, now what's
4:28:04going to happen if we append these
4:28:05together? Oh, I think I need to do one
4:28:07thing. Um, invalid JSON. Odd. H. Well,
4:28:12let's do a little bit of
4:28:13debugging. Okay. Uh, we're getting
4:28:15invalid JSON because the new lines.
4:28:17Yeah. So basically what we're going to
4:28:19have to do is we're going to have to
4:28:19remove new lines. So we could just
4:28:23replace all
4:28:26instances. Can we just do new
4:28:28line like a reg x with a new line or
4:28:31whatever? Or we could just have it not
4:28:32generate any new lines in the initial
4:28:34data. Yeah, that probably makes more
4:28:36sense,
4:28:37right? Like one, it'll be easier, but
4:28:40two, uh, it'll make sure that our source
4:28:42data is as clean as possible. So, why
4:28:44don't I go over here and then under
4:28:46rules, we'll
4:28:48say generate your new lines as back
4:28:51slashn characters instead of full line
4:28:55breaks. There should be no actual line
4:28:59breaks, only n
4:29:03characters. Cool. This will work 90
4:29:05whatever% of the time. It's not going to
4:29:08be perfect. Sometimes the model will
4:29:09probably misinterpret it. Maybe one out
4:29:11of 100 or something like that. or maybe
4:29:13one out of a thousand. Realistically,
4:29:14these models are getting pretty smart.
4:29:16So,
4:29:19still. Okay. So, now if I go over here
4:29:22and I'm I'm just going to retest this
4:29:24step because I want it to output the
4:29:25thing with the known new line. Let's
4:29:27just see what it looks like. Cool. We do
4:29:29have the Awesome. Awesome. All right. We
4:29:32should be good just to test this now.
4:29:33So, it's going to run three
4:29:34simultaneously and then it's going to
4:29:36run these. I guess not simultaneously,
4:29:38iteratively, which is nice. So, we're
4:29:39going to minimize the likelihood of us
4:29:41calling one of the APIs and then
4:29:42screwing it all up. Then from there, we
4:29:44should be able to do our node. Uh, looks
4:29:47like we were not able to service the
4:29:49request. Why would that be?
4:29:51H could it be an API
4:29:54call? Maybe it got rate limited.
4:29:57Probably got rate
4:29:59limited. Images take way more of your
4:30:01rate limit than um anything else. So
4:30:04generally good just to the second that
4:30:05you have a working thing pin the
4:30:07response so you just never have to do
4:30:09this again. Also if you think about it
4:30:10how much more time is it taking when I
4:30:12do it? It's taking a lot more
4:30:14time. So looks like it had an error
4:30:17while processing my request. H not
4:30:19entirely sure where that error is coming
4:30:20from. It probably is a rate
4:30:23limit. Let's go open AI E3 rate limits.
4:30:27See how many of these puppies I can
4:30:29generate. Do I have coins or tokens?
4:30:34and I go doll
4:30:37E. Go images
4:30:44maybe. Let's go per model. Let's just
4:30:48see. Dolly 3
4:30:54here. No, I should be good across the
4:30:57board. That's way more images than I
4:30:59need. I can do 10,000 images a minute,
4:31:01right? That's a lot. So, I don't know.
4:31:03Maybe I'm misformatting the data. Maybe
4:31:06I can't feed new lines in or something
4:31:07like that. Let's see. What is this? A
4:31:10bunny stacking colorful blocks labeled
4:31:11markdown CSV, XML, and JSON. No, that
4:31:13looks good to
4:31:14me.
4:31:16H. Too big. Could be too
4:31:19big. Or it could also just be a service
4:31:24outage. That's how I um typically do my
4:31:26debugging.
4:31:29Yeah, looks like there are some issues
4:31:31recently with Sora. I don't know if
4:31:33those issues extend back to me. Okay.
4:31:36Well, let's just try another module or
4:31:38another node then and let's see if it's
4:31:39the dolly or if it's just um my current
4:31:42approach with the Facebook node because
4:31:44the Facebook node is the only one that's
4:31:45had the issue that I've seen so far. So,
4:31:46I'm starting to think, hm, is it the
4:31:48Facebook node or is it just um Dolly in
4:31:52general? Fact that I haven't got an
4:31:54error yet, it's a pretty good sign that
4:31:57it's just the Facebook node. If it is
4:31:59the Facebook node, just got to ask
4:32:00ourselves why. Okay, no, it's not. It's
4:32:02actually just all of these dollies. Um,
4:32:04interesting. So, I'm not really sure
4:32:05what's going on with the image there. We
4:32:07saw that it was working a moment ago.
4:32:09Unfortunately, when you are working with
4:32:10the microservices economy, there are
4:32:12going to be situations like this with
4:32:14pretty inexplicable errors. Let me
4:32:16think. How do we proceed with this build
4:32:17regardless of the fact that there's some
4:32:19issue with Dolly? Well, I think what
4:32:21we'd probably want to do, hold on, let
4:32:25me change my API
4:32:27key just before I proceed. Really
4:32:30just throw it away. What we probably
4:32:33want to do is we probably want to go
4:32:34through the execution history and then
4:32:35we can just pin the outputs and that'll
4:32:36allow us to continue regardless of the
4:32:39fact that one of the APIs that we're
4:32:40using might not be working. That's
4:32:42typically what I do. So, we just changed
4:32:44my credential. Haven't got an issue yet.
4:32:47Spoke too soon. So what I'm going to do
4:32:50is I will go to my execution history.
4:32:52Let's see the last good
4:32:58execution. Looks like the last good
4:33:00execution was not here. Let's do this
4:33:03one. What is the output of this? Looks
4:33:06like we have JSON that looks like that.
4:33:08So I'm actually just going to copy this.
4:33:10Okay. I just want everything. Can I just
4:33:12copy
4:33:15everything? Yeah, that looks good. Now
4:33:17that I have this, um, why am I doing it?
4:33:19Because I can actually go here. Uh,
4:33:22uh, can I just, oh jeez, I don't
4:33:24actually believe I can pin the output of
4:33:26a broken node. Okay, so realistically,
4:33:29what I have to do is delete this. Go
4:33:31back here, pin this like this. There you
4:33:34go. Then go over here, pin this like
4:33:37that. And go over here, pin this like
4:33:40that. Okay, I'm now believe I could set
4:33:44everything else except for that pinned
4:33:48output. So I've just deleted the entire
4:33:50thing. So I I have to go through the
4:33:51whole generation again unfortunately.
4:33:53But just part and parcel. And now um
4:33:57that we will have dealt with that we
4:33:58could actually merge the outputs and
4:34:00continue.
4:34:02I think when debugging it's important
4:34:04just to like keep a level head and note
4:34:06that um you know most of the time it's
4:34:09your fault you've done something wrong
4:34:10but there are some situations that are
4:34:12just pretty inexplicable and I wouldn't
4:34:13allow that to slow down the rest of your
4:34:15build. Like I'm kind of in my head I'm
4:34:17thinking there's a probability that this
4:34:18is some inexplicable issue that I have
4:34:21no control over. I could if you think
4:34:24about it just stop developing and then
4:34:25be like well I'm done with the system.
4:34:27This sucks. I'm not going to work on it
4:34:28and get really frustrated, but uh I'd
4:34:30rather continue
4:34:32developing a different part of the
4:34:34system and then I can always circle back
4:34:36to that at the end. I think that's an
4:34:38important principle of just systems in
4:34:39general. If something isn't working,
4:34:41take a breather and then focus on a
4:34:43different section for a little bit. Then
4:34:44you can always double back to that
4:34:46initial section that was causing you
4:34:47problems after you've sorted out the
4:34:49rest of
4:34:50it. Okay, so transcript is currently
4:34:52being pulled. I'm going to go back to
4:34:55YouTube transcript ninja. Looks like
4:34:57that will have just wrapped up. Cool.
4:34:59Looks like it did. We're now feeding it
4:35:00into OpenAI. The
4:35:03transcript currently being
4:35:05generated. Maybe it's just an OpenAI
4:35:08problem though. The entirety of OpenAI
4:35:10is down. That would be pretty rough. We
4:35:11may maybe we've been hacked. Got some
4:35:14spyware competitor that's come in and
4:35:16just destroyed the servers. No, they
4:35:19didn't destroy the servers. Okay. Uh All
4:35:22right. What in item zero contains valid
4:35:24JSON? Exactly.
4:35:28I'm not seeing
4:35:29anything. Looking pretty good to me, my
4:35:32man. So, looks like we have some issue
4:35:34here where we do not have valid JSON and
4:35:37JavaScript object notation. Just opening
4:35:40this up here. And this
4:35:42looks right. It's a new line thing
4:35:44again. Uh, why are we getting new lines
4:35:48here? It's not giving me any new lines.
4:35:50Oh, what's
4:35:52this? We have a quote.
4:35:56No, we don't have a
4:35:59quote.
4:36:01Odd. All right. Uh, well, I guess I am
4:36:04going to have to replace all Can we just
4:36:07replace all special curs? No, that
4:36:10doesn't count.
4:36:11Um, could replace all
4:36:19uh I don't know if I could just
4:36:24do a
4:36:26backslash. Could I? Let's see. So,
4:36:30uppercase any occurrences of blue or
4:36:32car. So, what do we have to
4:36:35do? I think we got to use the G flag,
4:36:38right?
4:36:45back
4:36:48slashn.
4:36:50Then could I just go
4:36:53space? Is that going to work? I don't
4:36:56actually know this going to work.
4:36:57Probably not. Oh, yeah, it did work. All
4:36:58right. So, I just replaced back
4:37:01slashn with a
4:37:04space. So, basically, instead of these
4:37:06new lines, um, we just have a space. All
4:37:08right. Well, that's fine. I guess I'm
4:37:09just going to have to do this for
4:37:11everything. Oh
4:37:14well. Glad that you just throw some
4:37:16stuff at the wall and have it stick,
4:37:18huh? Me, too. Okay, so let's do that.
4:37:20Let's do that. Let's do that. So, this
4:37:23test is
4:37:24done. Let's just see this
4:37:27test. Oh, and I realize I should
4:37:29probably not be doing this line by line
4:37:30by line. I should probably be doing this
4:37:32all um at once. Okay, looks like we got
4:37:35the same issue here. So, what's going on
4:37:39now? The fact that we just can't get
4:37:41good JSON is worrying to
4:37:43me. Okay, it's simple. We just didn't
4:37:45have a comma
4:37:48here. Cool. We got that. And then what
4:37:51about over here? Do we not have a comma?
4:37:52No, we have a comma. Awesome. So, I'm
4:37:53just going to test the merge node now.
4:37:54We should be good. I mean, we we we're
4:37:56pinning the outputs of these three,
4:37:57right? So, it's just going to skip over
4:37:58this and then set the JSON. I'm going to
4:38:01run this. Skip over this. Set the JSON.
4:38:03Cool. All right. So, what does this
4:38:04actually look like in practice? We have
4:38:05three. We have image URL, postbody,
4:38:08platform, Instagram. Then we have
4:38:10another one that says platform LinkedIn,
4:38:11another one that says platform Facebook.
4:38:13So now you're probably wondering why the
4:38:14hell why the hell are you doing all
4:38:15this? Well, now hopefully it makes
4:38:16sense. Um because we have these three
4:38:18items and they all have different types,
4:38:19we can actually match the column based
4:38:21off the type, and then we can add it to
4:38:22a Google sheet. So I'm going to go
4:38:24sheets and I'll go add row to or append
4:38:27row to
4:38:28sheet. Um, air table is actually better
4:38:30to use um for stuff like this just cuz
4:38:34uh otherwise um rate limits and stuff
4:38:37can be pretty rough. Let's just go new
4:38:40sheet over here. What I'm going to do is
4:38:42I'll call this uh my AI podcast
4:38:45repurposing
4:38:47engine content calendar. Maybe we'll
4:38:50just call this our content. Ah, let's
4:38:51just do that. Okay. And then what am I
4:38:54going to do? Uh well, if you think about
4:38:58it, we can actually map this,
4:39:01right, with an expression. Yes, we can.
4:39:06Perfect. So, so now what I'm going to do
4:39:08is um inside of my Google sheet, right,
4:39:10which we've now done this, done that,
4:39:12done that. We haven't done that last
4:39:13part yet, but I've done this, done this,
4:39:15done this. We're now just combining all
4:39:17these. Um if you think about it, what I
4:39:20need now is I just want like content.
4:39:22So, what I'm going to want is um I'm
4:39:24going to need some sort of
4:39:28like date added. Then I'm going to need
4:39:31post body. And then I will go post
4:39:33image. This isn't going to be perfect
4:39:36because sometimes you're going to have
4:39:37to download the image first, but we can
4:39:39deal with the downloading um on some
4:39:40platforms later. And then I'm going to
4:39:42go Facebook. I'm going to add another
4:39:44sheet which is going to be called
4:39:46Instagram.
4:39:50And then finally, we'll have one called
4:39:52LinkedIn. Okay, we'll paste all these
4:39:54three in. All right, so now uh if you
4:39:57think about it, the document, sorry, the
4:39:59document that I'm going to do is fine.
4:40:01Uh the document is just going to be this
4:40:03document. So I can actually just grab
4:40:05the ID in the document, which is
4:40:06positioned up here. And then I can just
4:40:08pop that in. The sheet though, the sheet
4:40:10is what's going to change depending on
4:40:11the platform. Okay, so the sheet, if
4:40:14it's
4:40:15Facebook, we'll feed in Facebook. If
4:40:17it's Instagram, we'll feed in Instagram.
4:40:19if uh it's LinkedIn will feed in
4:40:22LinkedIn and then it'll automatically
4:40:23find the specific one to do. Now there
4:40:26are three columns. There's date added,
4:40:27post body, post image. Post image post
4:40:30body is right over there. Post image is
4:40:32the image URL. Okay. Then the date added
4:40:35uh is just going to be date. So we
4:40:37should just be able to go Can we go
4:40:39dollar sign now? Yeah. I don't really
4:40:41like the way that that's formatted,
4:40:42though. So can we format this
4:40:44differently? Uh let me see.
4:40:52Hm. Let's see here.
4:40:58Um, how should we format
4:41:01this? Can we do day day month year year
4:41:05or should we go year year year month day
4:41:07day? We do that. Oh. Oh, the formatting
4:41:11is a lot easier than I thought already.
4:41:13April 9th, though. Do we just
4:41:16go DD, I
4:41:20guess? Yeah, we'll just go DD. That
4:41:22looks good. Cool. Um H. Yeah, that
4:41:25should be okay. So, let's test this
4:41:28now. Oh, boy. That's a fat ass
4:41:31transcript. Wrong one. My bad. Uh, what
4:41:34did we have there? We had Instagram.
4:41:35Okay, cool. So, we just had three
4:41:37Instagram posts.
4:41:39And should we have three Instagram
4:41:41posts? I don't think we should have
4:41:42three Instagram
4:41:44posts. All right. So, I feel like some
4:41:46some error occurred there, right?
4:41:49Because we should have three items each
4:41:51with their different platforms. But what
4:41:53ended up happening? Looks like we fed
4:41:57all of these just to
4:41:59Instagram. So, this is Instagram right
4:42:01now, but it should be dynamic, right? It
4:42:04should change depending on what we are
4:42:05putting
4:42:06in. Um, well, that's annoying. All
4:42:09right. So, slight issue with the
4:42:10recording there. Um what ended up
4:42:12happening was for whatever reason when I
4:42:14was pumping the data through that
4:42:16dynamic remapping flow with the merge uh
4:42:18just it just didn't work. I think it has
4:42:20to do with the underlying way that the
4:42:22nadn node functions. So anyway
4:42:25completely unrelated issue but my
4:42:26recording just stopped so I had to
4:42:27restart this. Basically what I ended up
4:42:29doing was I just hardcoded the logic in
4:42:30the sheets. So if I go to the first
4:42:32sheet for Instagram so you can see here
4:42:34it is hard coding the sheet of
4:42:36Instagram. Okay. If I go to the second
4:42:38one here for LinkedIn, it's hard coding
4:42:40the sheet for LinkedIn. And for the
4:42:42third, if I do Facebook, then it's hard
4:42:44coding the sheet for Facebook. Is this
4:42:45his most elegant solution? No, not
4:42:47really. I'm kind of annoyed that I have
4:42:48to do this to be honest, but is what it
4:42:50is. And I don't really care too much
4:42:51about the elegance of a solution. I care
4:42:52more about just like whether or not it
4:42:53works. So, testing this now. Going to my
4:42:56sheet, which is over here. If I go to
4:42:57the Facebook post, um, as you see that
4:42:59one populated, then Instagram and
4:43:01LinkedIn, because this is happening
4:43:03sequentially, not all at once, you know,
4:43:04we got to wait a little bit. LinkedIn
4:43:05there. Then finally, Instagram over
4:43:07here. And uh yeah. Yeah, this is more or
4:43:09less how I how I went through and I
4:43:10solved the flow. And then at the end
4:43:12here, let me just recreate this for you
4:43:14guys. Now that I'm done it, I I want
4:43:16some sort of user input. I want some
4:43:18sort of, you know, experience where the
4:43:20person that submitted the form knows
4:43:22that the form is good to go, right? So
4:43:23in NAN, you can actually add this over
4:43:27here as a form ending. So you can
4:43:30actually generate a form ending. You
4:43:32could say, "Congratulations, your
4:43:34content has been produced." Then I'll
4:43:36say, "Check your content calendar for
4:43:40the specific posts." Then maybe I'll
4:43:42even link the content calendar
4:43:45here. You know, you can imagine a client
4:43:47experience that'd be a lot simpler and
4:43:49easier for them to see. Okay, cool. So,
4:43:51yeah, that's the flow in a nutshell. Um,
4:43:53the thing is this is just the first part
4:43:54of the flow. He was like, "Are you
4:43:56serious, Nick? You're an hour and is the
4:43:58first part of your flow?" Uh, yeah, but
4:43:59the second part of the flow is really
4:44:00simple. But we just actually do the
4:44:01posting. So now that we have like our
4:44:03asset, which is basically just a list of
4:44:05posts, what we have to do is we just
4:44:07need some sort of logic that checks all
4:44:08of these once per day. Then it basically
4:44:10sees, hey, has this thing been posted
4:44:11yet? So I've added a posted on column to
4:44:13double check for that. Then if it hasn't
4:44:15been posted yet, it'll just go and it'll
4:44:16add a posted on column. It'll say, hey,
4:44:18uh, this was added on the n posted on
4:44:19the 10th. If you think about it, if we
4:44:21have a bunch of these and you know we
4:44:24have some columns, let's say 9th, 9th,
4:44:269th, 9th, but then this one's empty, um
4:44:29what we're going to do is we're just
4:44:30going to filter to only look for the
4:44:31ones with empty and then those are the
4:44:33ones that we're going to fill in the
4:44:34next day and actually go through and
4:44:35post. So in this way, we're going to
4:44:36have like a dynamic um a dynamic tracker
4:44:38basically. Uh that doesn't make much
4:44:40sense to you right now, don't sweat it
4:44:41too much. Let's actually go ahead and uh
4:44:42let's just build out the second half of
4:44:43this. Okay. So, I'm going to click um
4:44:46back to my home and then I'm going to
4:44:48add AI content repurposing engine 2.
4:44:51Just change the title to two. And then
4:44:55what do I need to be the um start of
4:44:58this? Well, if you think about it, I'm
4:45:00probably just going to do a test for
4:45:01now. Well, actually, I should do a
4:45:02schedule trigger. Let's just run this
4:45:04once every day. Okay. Do I want to post
4:45:06this at midnight? Probably not. Let's do
4:45:087 a.m. or something at minute
4:45:10zero. So, we got a bunch of data in
4:45:12here. Okay, which is nice. And then that
4:45:14supposedly is going to initiate our
4:45:16flow. What do we do next? Uh let me just
4:45:17pin this. What do we do next? Well, now
4:45:20we got to uh look through the Google
4:45:21sheet. So we got to filter and we got to
4:45:23post a
4:45:23bunch. And so the way I'm going to do
4:45:26that is I'm going to get rows in
4:45:30sheet. Okay. So I'm going to connect my
4:45:32credential. What is the document I'm
4:45:35going to be using? Uh well, AI podcast
4:45:37repurposing calendar. And we have three.
4:45:39We have Instagram, LinkedIn, Facebook.
4:45:41Okay. So I'm just going to go the first
4:45:43first. The filter I'm looking for, if
4:45:45you think about it, is I want to see if
4:45:46this column posted on is empty. If this
4:45:49is empty, then I want to return the
4:45:52value. Okay, so let's just test this
4:45:53really quickly. Doing a call, we've
4:45:56returned one because posted on is empty.
4:45:57But what if I said x is posted on x? If
4:45:59I click test, I'll say, oh no, no output
4:46:02data is returned because there's no um
4:46:04content with posted on equal to x. So I
4:46:06just verified that my filter worked
4:46:07right there, right? Easy peasy lemon
4:46:09squeezy.
4:46:10Okay. Now, another thing we have to
4:46:12think about is, well, we've just done
4:46:13that once with um the Instagram stuff,
4:46:15but we're going to have to do this again
4:46:16with the Facebook and LinkedIn as well.
4:46:19So, I'll say check Instagram posts. This
4:46:22one will be check LinkedIn
4:46:26posts. This last one here will be
4:46:29check Facebook posts.
4:46:35And here, this one has to be
4:46:39LinkedIn. Here, this one has to be
4:46:42Facebook. The column logic should be the
4:46:44same for each. Let me just make sure.
4:46:45Post it on. Good. This one should be
4:46:47posted on. Yeah, good. Okay. So, now
4:46:51that we have this, we have everything
4:46:53that we need in order to go and and do
4:46:55the posting. So, if you think about it,
4:46:56what we're going to have to do now is
4:46:57we're going to implement posting logic.
4:46:58Post on Instagram, post on LinkedIn,
4:47:00post on Facebook. Simplest way is
4:47:01obviously 1x per day, but you can change
4:47:03this to be whatever you want. That's
4:47:04what I get for not using my pen. And
4:47:06then um after the post, what are we
4:47:08going to do? We're just going to mark it
4:47:10as done inside of our Instagram post and
4:47:13then LinkedIn post and then Facebook
4:47:15post, Google Sheets. And then at the
4:47:17end, I'm probably just going to merge
4:47:19them together again. And then that's it.
4:47:22So the question is, how do we actually
4:47:23go about posting on these platforms? And
4:47:24that's a great question. Let's uh let's
4:47:26go through and let's figure this out.
4:47:27Okay, so I just did a bunch of
4:47:28authentication. Now, this authentication
4:47:30in NAND is non-trivial. It is honestly
4:47:33pretty involved to get through. Let me
4:47:34walk you guys through what I did. I just
4:47:36don't obviously have the ability to
4:47:38share all my access tokens and stuff
4:47:39like that, but I'll still run you guys
4:47:40through what I did and walk you guys
4:47:41through the workflow. So, essentially, I
4:47:44mentioned earlier we have that schedule
4:47:45trigger, right? And we're checking the
4:47:47Instagram, LinkedIn, and Facebook posts.
4:47:48And then we sort of have three routes
4:47:50here. The first is Instagram. And so,
4:47:53the way that the Instagram route works
4:47:54is what we need to do first is connect
4:47:56to a graph account. The graph account is
4:47:58just the way that Facebook deals with
4:48:00all their API calls. I'll talk about
4:48:02that specifically, but first, if you
4:48:03guys wanted to set this up alongside me,
4:48:05if you guys didn't have the template,
4:48:06which you guys can obviously get in
4:48:07Maker School, you would have to go
4:48:08through the following. The host URL
4:48:09would just be default. HTTP request
4:48:11method would be post. Graph API version
4:48:13would be 17. The node would depend on
4:48:16your Facebook or your Instagram account
4:48:18ID. I'll cover that in a moment. The
4:48:21edge would be media. I set ignore SSL
4:48:24issues to false. Then underneath this,
4:48:26we'd have two options. There'd be a
4:48:27caption option with the body of the
4:48:29post. there would be an image URL option
4:48:32which I actually just hardcoded here um
4:48:34as like a uh I don't know a silly image
4:48:37because I just cuz I wanted to test it
4:48:38out a couple of times in my account to
4:48:39make sure that it worked first. But I
4:48:41can actually go through it and I can fix
4:48:42it um afterwards. Okay, great. So yeah,
4:48:44that's all of the stuff that you need.
4:48:46The node the way you get that is you go
4:48:48to
4:48:49business.fas.com. Obviously I'm posting
4:48:50this on a business account. Then you go
4:48:53down to settings and then you have to do
4:48:55is go to Instagram accounts. Right next
4:48:57to Instagram accounts you have the ID of
4:48:59the Instagram. Okay, so that's that's
4:49:00where you would go. That's the very
4:49:02first place that you would go to get the
4:49:03ID of the node and yeah, just make sure
4:49:05the edge is media and so on and so
4:49:06forth. To actually connect this to a
4:49:08graphic account to actually create a
4:49:09credentials, as I mentioned, quite an
4:49:10involved process. What you have to do if
4:49:12I go to the documentation here. So you
4:49:14have to first make a meta app with the
4:49:17products that you need to access and my
4:49:18recommendation is just do all products.
4:49:21Okay, so I'm just going to open up a
4:49:23bunch of tabs here as naden guides me.
4:49:25What I ended up doing was I made one
4:49:26called
4:49:28nick_rive_na_post machine, but I'm just
4:49:29going to create a new one
4:49:31here just to show you guys where it's
4:49:33at. This is where your I don't know um
4:49:37app name is going to be. Then your use
4:49:40cases. What I always uh what I do is I
4:49:42just do um
4:49:44other. And then it'll ask which business
4:49:47specifically you want to work with. I
4:49:48have no idea why it's in Spanish, but
4:49:50it's in Spanish.
4:49:53and then your app name and then the app
4:49:55contact email and then your business
4:49:56portfolio. You would just select the
4:49:58business portfolio that has access to
4:50:00all the other stuff. Now, I mean, I'm
4:50:02pretty good at all this stuff and the
4:50:04way that Meta and Facebook does all of
4:50:07their different business portfolios and
4:50:08ad accounts and ad managers and stuff,
4:50:10that's still like really really crazy um
4:50:13to me. And you know, I'm somebody that
4:50:15works with technology like this on a
4:50:16daily basis. So, don't feel out of the
4:50:19loop or don't feel incapable if you guys
4:50:22don't know what that means. Um, it took
4:50:24me a very long time to figure this out.
4:50:26An embarrassingly long time, I should
4:50:28say. Uh, I'm authenticated through SMS,
4:50:31so I just had to get myself a text
4:50:33message. And I just confirm this. After
4:50:36you're done with this, you will have an
4:50:38an app. It's going to take a second. Um,
4:50:40and they're going to verify the hell out
4:50:42of you. Okay, great. So once you're done
4:50:44with that, um you need to So I'm going
4:50:45to set up both Facebook and Instagram at
4:50:47the same time, but then you need to set
4:50:48up um obviously the the Instagram. So
4:50:50click setup here. Oh, sorry. Before we
4:50:52do all this, actually, we need to do two
4:50:54things. Go over to app settings basic.
4:50:56Then what you need to do is you need to
4:50:57enter a privacy policy. So I just
4:50:59entered this as my privacy policy. Okay,
4:51:01so that's number one. Next, go to
4:51:04tools, then go to graph API explorer.
4:51:08Then what you need to do, okay, is you
4:51:09need to generate you need to go to the
4:51:11specific app that you just did. So, in
4:51:12my case, NAN access. Then, under
4:51:15permissions, you have to add, go to
4:51:17other. Um, I mean, I just added all of
4:51:19the permissions. I think you would be
4:51:21smarter than me and maybe just add the
4:51:23ones that are specific to Instagram, but
4:51:25the way that I typically do these things
4:51:27is, um, I just scroll through and then I
4:51:30find anything related to Facebook or
4:51:31Instagram. Then I click okay. So, as you
4:51:34see here, this very helpful bright red
4:51:35bubble, it's assisting
4:51:38me. Um, I don't do any of that. and I
4:51:41don't do any of that. Okay. So, now once
4:51:43I have all these and you click this um
4:51:45generate access token button, you're
4:51:48going to have to sign in to your account
4:51:50again. You can opt into the current
4:51:53applications. So, I'm just going to do
4:51:54all of them. Going to do all of them.
4:51:57I'm going to do all of them. I'm going
4:51:58to do all of
4:52:01them. Then the application that you just
4:52:04created is going to uh request centrally
4:52:06access to your account. Once you have
4:52:08that, you will have your your access
4:52:10token up here. Then you're also going to
4:52:11have a bunch of Instagram permissions.
4:52:12So access token is what you want to
4:52:13copy. Okay? And that's what you go and
4:52:16paste in here. That access
4:52:18token is that big fat beautiful access
4:52:22token. Um, and I just realized this
4:52:25probably isn't going to work now because
4:52:26I'm I have a bunch of different settings
4:52:28with my other access token. So I'm
4:52:29actually going to go back and I'm going
4:52:30to I'm going to put in my previous
4:52:31access token. Uh, where am I here? Let's
4:52:35go back to this one.
4:52:38I'm going just copy that. Go back here
4:52:41and then paste that in. Let's save that.
4:52:43Okay. Anyway, once you have the access
4:52:45token for the specific thing you want.
4:52:47So, in my case, oops, I'm doing it
4:52:49again. It says nadn access. Go back to
4:52:55developers.fas.com/apps and then go back
4:52:57here to the main app. For whatever
4:53:00reason, it duplicates your apps if you
4:53:01add a portfolio like I did. Then uh down
4:53:04where it says Instagram, you can go to
4:53:06settings and then where it says API
4:53:08setup with Instagram login. This is when
4:53:11you would add your Instagram
4:53:17account. We've now just given it access
4:53:19to everything. Still getting
4:53:20insufficient developer role. H why is
4:53:23that? Not entirely sure. It might be
4:53:25because of
4:53:31this. Yeah. So, you need to make it
4:53:33live. Then you click
4:53:34allow. The app will now have access to
4:53:37your Instagram. Beautiful. And once
4:53:39that's done, you just take that GraphQL
4:53:41or Graph um API token, access token, I
4:53:44should say, feed it in here, connect it,
4:53:46then you're good to go.
4:53:48Okay. So, after that, what you do is you
4:53:50feed in the post body and then you feed
4:53:51in the image URL as I mentioned earlier.
4:53:53Now, um I'm actually going to fix this
4:53:55right now. So, I'm just going to test
4:53:57this. Pull some Instagram
4:53:59posts. Okay. Now, as you can see, we
4:54:02have the image URL, which I will feed in
4:54:05right over here. Let me just make sure I
4:54:09can actually see this. Uh, no, we can't.
4:54:11Right. Right. The reason why is because
4:54:13um, OpenI will automatically time these
4:54:15out after a while. So, I can't actually
4:54:17see that image, which is unfortunate.
4:54:18What we need to do is we need to
4:54:19download it and upload it um, again.
4:54:21Okay. So, I'm just running the new image
4:54:24generator just so that I have access to
4:54:26all of the um, new images. Otherwise,
4:54:29OpenAI will time out the images if you
4:54:31haven't opened them or accessed them in
4:54:33a while. Looking pretty good to me. And
4:54:36it looks like now this is working as
4:54:37opposed to before where I wasn't. So,
4:54:39that's just a good example. Focus on
4:54:40solving the problems that you can solve
4:54:42at the time of the development. Um, you
4:54:45know, I just went and took my attention
4:54:47elsewhere and then whatever problem that
4:54:48the API had is now resolved. Okay, so
4:54:50now we're adding stuff to the sheet.
4:54:53There's the Instagram one, LinkedIn one,
4:54:54and the Facebook one. Let's just access
4:54:56the image here.
4:54:58Look at that. That's really
4:55:00interesting. Fascinating. Here's the
4:55:03post image. Thank you, rabbit. Here is
4:55:06the other post image. Wow, that rabbit
4:55:09is having a go. I really like that.
4:55:10That's cute as hell. Little little
4:55:12tongue is out. Okay, great. Um, so now
4:55:14we've added that to the sheet. So now if
4:55:16we go over here to the other uh
4:55:18scenario, what do I want to do? I just
4:55:19wanted to test this. So I'm just going
4:55:20to test the Instagram post. Pull in the
4:55:22new Instagram post here. Looks like we
4:55:24got that one post image. Beautiful.
4:55:26Let's now upload that one to the
4:55:27Instagram.
4:55:28[Music]
4:55:29So, let me just feed in post image here
4:55:31to image URL. There we go.
4:55:34Oops. So, do not
4:55:36delete do not delete the image URL.
4:55:39That's not what you want to do. All
4:55:40right. Should be good. I'm going to test
4:55:42this step. It's now executing the node,
4:55:44meaning it's uploading. And what
4:55:46happens? It returns an ID. What does the
4:55:48ID do? The ID is actually what allows
4:55:50you to take something that you uploaded
4:55:52and then post it afterwards. Okay. Now
4:55:54on the post on IG node, what you need to
4:55:56do is you need to reference the specific
4:55:58page that you're using, okay? Which is
4:56:011784144. That's uh the data that we got
4:56:04previously. And then yeah, the rest of
4:56:06these settings, I'll just leave you guys
4:56:07here to uh to take them. But the main
4:56:09one in consideration is creation ID
4:56:11where you paste in this ID here. So I'm
4:56:14going to post this. We're going to get
4:56:16good output, which is nice. Uh guess I
4:56:19need to like go to that, right?
4:56:22Yeah, let's view this on Instagram now.
4:56:25So, I just posted my little bunny rabbit
4:56:27live. Be the first to like this. I'm
4:56:29just going to delete it because that's
4:56:30on my actual uh account. But hopefully
4:56:33you guys can see what that flow looks
4:56:34like from start to finish. Pretty easy.
4:56:36Lemon squeezy. Uh then we're going to
4:56:38check the LinkedIn posts. HTTP request
4:56:40and then publish to LinkedIn. Now,
4:56:41you're probably wondering, why do you
4:56:42have to do that? Well, the reason why
4:56:44you need to do this in the LinkedIn row
4:56:45is because uh LinkedIn actually needs
4:56:46the the image file itself. Uh so let me
4:56:50test the im the LinkedIn route now. So
4:56:52I'm click
4:56:53test. It's not enough to get the URL
4:56:55like we had before. Okay. What we need
4:56:57to do is we actually need to get the
4:56:58image file. Now just because I don't
4:57:00want to go through a bunch of annoying
4:57:01stuff. Um what I'm doing is I'm just
4:57:02getting the image file from post image
4:57:04right over here. No authentication. I
4:57:06click test step. Now it's actually going
4:57:08to go and it's going to redownload the
4:57:09image. So I know it's a fair amount of
4:57:11bandwidth going back and forth, but now
4:57:12the image is in nad. Then the LinkedIn
4:57:15module works pretty easily. All you need
4:57:17to do to create a connection is you just
4:57:18click on this button and then uh if you
4:57:21wanted to create a new one. Let me
4:57:22create a new one. Just go to standard
4:57:24and then click connect my account. It'll
4:57:26actually just log into your LinkedIn for
4:57:27you. Okay. So you just accept that
4:57:29LinkedIn and then you're good to go. So
4:57:31I'm just going to close this and go back
4:57:32to my first account which I think was
4:57:34this one hopefully. And then the
4:57:36resources post operations create post is
4:57:38organization. The organization you are
4:57:40in. This is interesting. But basically,
4:57:41if you go to your LinkedIn account and
4:57:44then you go to the pages that you have
4:57:45control over right over here. Give that
4:57:47a
4:57:48click. The URL is going to be the ID of
4:57:50the page. Basic. You see that up there?
4:57:53That's what you're going to want to
4:57:54paste down here. The text in my case is
4:57:56just the post body, the image category
4:57:58here, and then the input binary field
4:58:00will just automatically pull from the
4:58:01previous one. So, if I now map this to
4:58:03my LinkedIn, if I drag this over here,
4:58:06you'll see I now get a URN li. So, if I
4:58:09then refresh this, I will have my little
4:58:11bunny
4:58:11rabbit having been posted with my
4:58:14content, which is cool. All righty. All
4:58:16righty. And then, uh, what's that last
4:58:18one here? The last one is the Facebook
4:58:20route. So, let's test this
4:58:21out. So, I'm just going to pull all the
4:58:24data. I have the post image as per
4:58:26usual. If I want to publish this to
4:58:28Facebook, same flow that I had before.
4:58:30Okay, we connect the Facebook graph
4:58:31account, but here are the details
4:58:33instead of the node ID. So first of all,
4:58:35HTTP request is a method. Graph API
4:58:37version is 17. The node is me instead of
4:58:40the node. Um, and then edges photos.
4:58:43This is false. Message post body then
4:58:47post image. Okay. When I post this,
4:58:49what's going to happen is it'll go on my
4:58:51Facebook account. It'll go and it'll
4:58:54create the post ID. So, uh, where the
4:58:57heck is that Facebook
4:58:59account? I don't really want that to be
4:59:01posting. Let's view this on Facebook.
4:59:06see that new little bunny post I made
4:59:08and then uh oh, how do I actually get
4:59:10rid of that? That is the question. Think
4:59:12of all my fans. They're going to see the
4:59:13bunny. They're going to be like, "Nick,
4:59:15what the hell's this bunny all about?"
4:59:16All right, we just click on this and
4:59:18then should be able to delete it. I
4:59:20think it's Yeah, there you go. Cool. So,
4:59:23I've just proven that this works
4:59:25essentially. Um, feel free to trust me.
4:59:28Uh, what's better than trusting me is
4:59:30actually going out there and doing it.
4:59:31Now that we publish in all three, what
4:59:32do we want to do? Well, if you think
4:59:33about it, we now want to update that
4:59:35last uh that last record that we just
4:59:37gotten. And then we want to just write
4:59:39posted on. Then we want to have that
4:59:41date. Since we're doing this once per
4:59:43day, what I'm going to do is the
4:59:44operation is going to be update a row.
4:59:47This one
4:59:48here, the one we are going to
4:59:51update column that we're going to match
4:59:53on is going to
4:59:56be let's do post image. I'm going to
5:00:00do is I'll go back to check Facebook
5:00:03post. I'm just going to match the post
5:00:05image to the same post image that we
5:00:07had. The only difference I'm going to do
5:00:09here, everything else will be the same.
5:00:12Okay. Only thing that I'm going to
5:00:14actually meaningfully change is posted
5:00:16on. So, I'll just I'm just going to map
5:00:17the rest of these fields in. And what
5:00:19I'm going to do is I'm only going to
5:00:20update a postit on so that it doesn't
5:00:21show up in the next search. How do I do
5:00:22that? I'm just going to go back to the
5:00:24formula where I got the exact formula
5:00:25for posted on. There you go. change that
5:00:28to an expression. All right. And then
5:00:30instead of check Facebook post, this is
5:00:32update uh update Google Sheets DB. Okay.
5:00:37Oh, I should probably do that one more
5:00:38thing here. I should call it
5:00:40Facebook. Facebook. There we go. All
5:00:42right. So, that's the Facebook one.
5:00:45We'll go over here now. Connect this to
5:00:47the LinkedIn
5:00:49one. We got to change this to
5:00:52LI. And all of this data is going to be
5:00:55different as well. Um, I'll change that
5:00:56in a sec.
5:00:59Just I really like being able to quickly
5:01:02and easily map this stuff out by copying
5:01:04and pasting it. So, just now going to
5:01:06move this to
5:01:07Instagram. Then I just want to rename
5:01:10this to Instagram. Cool. And I basically
5:01:14just have to go, you know, unfortunately
5:01:15I have to go through this um this
5:01:16rigomeroll
5:01:19again. So, let's test this. Let's pull
5:01:22that out over here. Yeah, I can't, you
5:01:25know, actually need to execute the
5:01:26previous node. It's kind of annoying.
5:01:27Whatever. Let's give it a
5:01:30try. Look like all my LinkedIn fans are
5:01:33going to have to
5:01:34wait. All right. Uh, post image was
5:01:36right over
5:01:37here. Date added was right over
5:01:41here. One more
5:01:43time. Then post body was right over
5:01:46here. Looks good. And then posted on
5:01:49format looks good. That's fine. And
5:01:52then let's test this
5:01:55now. Should update good for this
5:01:59one. Just test everything first. This is
5:02:01going to error out, but it's okay. I'm
5:02:03going to get the Facebook
5:02:06post. Then we can now update the post
5:02:10image.
5:02:14One thing I don't like about N&N's
5:02:16interface is that
5:02:17uh the expression field covers the
5:02:22subsequent field that you're working on,
5:02:23which is
5:02:25unfortunate. Anyway, give that a
5:02:27go. Cool. And then this one here, I've
5:02:31already verified that works, I believe.
5:02:33Cool. And then now, if you think about
5:02:35it, if we go back to our Google sheet,
5:02:36we now have a fully kind of like self
5:02:39annealing system. The system just checks
5:02:41to see when the posted on date was last
5:02:44and then it'll just go through once a
5:02:45morning and check to see which one to
5:02:47post next. So you can generate 10 new AI
5:02:50podcast posts and then you can go
5:02:52through and just check these off one by
5:02:53one automatically which is pretty neat.
YouTube Video Trend Detector
5:02:55All right, you now have a content
5:02:56repurposing engine again that transforms
5:02:57long form content into multiple social
5:02:59media posts automatically. We're now
5:03:01building a YouTube trend detector that
5:03:02automatically monitors channels in any
5:03:04niche. It identifies videos that are
5:03:05going to be performing way above
5:03:06average. Then we're also going to hook
5:03:08that up to an email system to send daily
5:03:09digest emails with trending
5:03:11opportunities. The whole idea is to give
5:03:12content creators and agencies the
5:03:14ability to jump on trends early, then
5:03:15ride the wave of viral content. You can
5:03:17easily charge over a,000 bucks a pop for
5:03:19this system because it provides genuine
5:03:21competitive intelligence. And it also
5:03:23replaces a couple of very popular
5:03:24services out there like Vid IQ and one
5:03:26of 10. We're just rebuilding all of that
5:03:27in our run back end. Okay, let's dive
5:03:31in. All right, so this is future me
5:03:33doing a demo of the system. I've gone
5:03:35through a bunch of rigomeroll in order
5:03:37to get this put together and you guys
5:03:39are going to see all of that. In a
5:03:40nutshell, this is going to be two
5:03:42separate workflows. One to add or update
5:03:45new trending videos and the other to
5:03:48take everything that you've added and
5:03:50updated and then to send it in a nicely
5:03:52formatted email that I'm calling the
5:03:54daily digest. So, if I click test
5:03:57workflow, the first thing that's going
5:03:58to happen is it's going to pull from a
5:04:00Google Sheet database of channel IDs.
5:04:03It's then going to grab YouTube videos
5:04:06from the YouTube API before dumping
5:04:08those into the Google sheet. And then
5:04:10what we're going to end up having is
5:04:12just a list of new videos here alongside
5:04:14view counts. Now, I'm doing this for a
5:04:17couple of channels, but essentially
5:04:18after we're done with this, this YouTube
5:04:20trend detector can then turn on. And
5:04:23when this happens, what we're doing is
5:04:25we are then subsequently reading through
5:04:26this on a schedule, maybe once every
5:04:28couple of days or something. If I go to
5:04:30my Gmail, you'll then see that we now
5:04:33have a list of high quality videos over
5:04:36certain multiples that are then
5:04:38organized really, really nicely for us.
5:04:40And you know, we put in the channels
5:04:42that we want to track ahead of time and
5:04:43so on and so forth. But yeah, this is
5:04:44more or less like a simple and easy way
5:04:46to do things. I'm going to run you
5:04:47through exactly what the logic for this
5:04:49looks like. Maybe if you wanted to
5:04:50extend it, I don't know, build a website
5:04:51doing this, recreate one of 10 or
5:04:53whatever. Okay, so let's do the live
5:04:56build.
5:04:58Okay, so let's start with the live
5:04:59build. Here's the current road map and
5:05:01what I'm thinking about how to get
5:05:02started and then finish this. What I'm
5:05:04thinking is we're actually going to
5:05:05divide this into two separate flows. The
5:05:07first flow is going to be the ad and the
5:05:09update flow where we're actually going
5:05:10to grab the data directly from YouTube.
5:05:12And then the second flow is going to be
5:05:13the daily digest flow where we basically
5:05:15just send a summarized version of all of
5:05:17the trending content. And in this case,
5:05:20I'll just use an email, but in reality,
5:05:21you can think of this as being
5:05:22deliverable through more or less any
5:05:24means that you want. You could do like a
5:05:25Slack update. You could do SMS. You
5:05:26could spin up a beautiful user
5:05:28interface. You could have a website. And
5:05:30I'll run you through each of these in
5:05:31kind, but I just wanted to mention that
5:05:33I got the initial idea from Leonardo
5:05:35Gregorio. He showed me a trend detector
5:05:37that he was using to identify AI and
5:05:39automation related content to find
5:05:40trends that he could, you know, jump on
5:05:42trends. And he's taken a very sniper
5:05:43rifle approach to all this stuff. The
5:05:45guy's grown from basically zero subs all
5:05:47the way up to 20K extraordinarily
5:05:48quickly, much quicker than I did when I
5:05:50started. So, um, he developed this idea
5:05:53of a YouTube outlier detector based off
5:05:55multiples. Um, and I believe he got the
5:05:58his idea from this website here, one of
5:06:0010, which basically does all this stuff
5:06:02in the background. And it's like a SAS
5:06:03product. And the idea is what we're
5:06:05going to do is we're going to rebuild or
5:06:06recreate a lot of the same functionality
5:06:08of this app. And then Leonardo's, except
5:06:10instead of using, in his specific case,
5:06:12he used I think it was like SQL. I'm
5:06:14just going to do it all inside of a
5:06:15Google sheet just cuz I think SQL is
5:06:16kind of scary and intimidating to a lot
5:06:17of beginners. And I just want everybody
5:06:18to like I want everybody to have as
5:06:20simple and as easy and as
5:06:21straightforward a time as humanly
5:06:22possible with this stuff. I personally
5:06:24don't really think we need to use SQL
5:06:25for it. So with all that said, here is
5:06:27more or less what I'm thinking. For the
5:06:29add or update flow, we're going to start
5:06:30by getting all of the videos for a
5:06:32specific channel. So basically, we're
5:06:34going to have to add a list of channels
5:06:36that we're monitoring. From there, we're
5:06:38going to grab the individual video data
5:06:39using the YouTube API. And that's just
5:06:41how the YouTube API works. You can get
5:06:43all videos in one call, but then you
5:06:45don't get a lot of information about
5:06:46each video in that call. you just get a
5:06:48list of IDs. The second step here
5:06:50requires us then to ping each individual
5:06:52video to grab data like views. What I'm
5:06:54going to do next is I'm going to filter
5:06:55all long form videos. So you know how
5:06:57YouTube you can do shorts or you can do
5:06:59like longer videos like my style. Well,
5:07:01you know, we kind of need to compare
5:07:02them apples to apples. So I'm just going
5:07:03to filter out shorts. Unfortunately,
5:07:04there's no built-in way using the
5:07:06YouTube API to do this. So I'm going to
5:07:08do a heruristic or sort of like a proxy
5:07:10for shorts. And I'll run you guys
5:07:11through what all that looks like later.
5:07:12Then I'm going to check if it exists in
5:07:14the database. Database being the Google
5:07:15sheet here. And that's just a fancy term
5:07:17for that. If it doesn't exist, we're
5:07:19obviously going to add it. If it does
5:07:20exist, we're going to update the metrics
5:07:21and stuff like that with the new view
5:07:22count because presumably views change.
5:07:25And then once we have our little
5:07:26database set up like our Google sheet,
5:07:27what I'm going to do is, you know, once
5:07:29a day or once an hour or I guess just
5:07:31however often we want, we're going to
5:07:32send over some sort of digest. And a
5:07:34digest again can be anything. In my
5:07:36case, I'll just do a quick little email
5:07:37just cuz I think that's the straightest
5:07:39line path. So what's that going to look
5:07:40like? Well, because I'm using a Google
5:07:42sheet, I'm going to store all this data
5:07:43on different sheets. So, I'm going to
5:07:44grab all the sheets. Then I'll grab the
5:07:45videos in each sheet. And then for each
5:07:47video list, I'm going to calculate the
5:07:49average number of views. This is sort of
5:07:51how you determine the multiple or how
5:07:53trending a piece of content is. You
5:07:55compare the view count of a specific
5:07:58video against the average view count of
5:08:01all of the videos. Then for each video,
5:08:03we're going to determine the multiple on
5:08:04that. And then if the multiple is over
5:08:05the threshold, we're going to include in
5:08:07the email. So, I like this idea because
5:08:08if we combine these two systems, right,
5:08:10we have something on the left here
5:08:11that's automatically updating the
5:08:13metrics and then something on the right
5:08:14here that automatically checks to see if
5:08:15a multiple is below some threshold.
5:08:17Presumably, these two things are going
5:08:18to make the system evolve and be
5:08:20dynamic. The videos that come in on day
5:08:21one aren't necessarily the videos that
5:08:23are going to come in on day two. And far
5:08:24from being like a negative of the
5:08:26system, I think that's actually a
5:08:27positive cuz sometimes videos get
5:08:29rediscovered later on. And I think that
5:08:30if you want to really assess the
5:08:32performance of a video, you can't just
5:08:34look at everything static like, you
5:08:35know, today or tomorrow. You actually
5:08:36have to look at it as it evolves over
5:08:38time. All right, so that is the whole
5:08:39idea here. Let's actually jump in and
5:08:41build this puppy. So, I got my little
5:08:42YouTube trend detector here. I was just
5:08:44doing a little bit of um wireframing
5:08:46beforehand to make sure that like the
5:08:47YouTube API worked and like logically I
5:08:49could actually hook up my credentials.
5:08:51But aside from that, this is going to be
5:08:52entirely lively build. So, I'm going to
5:08:54create a new Google sheet here and I'll
5:08:56run you through how to do all the
5:08:57connections and everything like that you
5:08:58need as well. Let's uh remove that. I'm
5:09:01just going to call this like YouTube
5:09:03trend tech. Let's just say database.
5:09:06Okay. All right. That seems pretty solid
5:09:08to me. Uh what I have to do is I have to
5:09:10connect this database now. So what I'm
5:09:11thinking I'm going to do is you know how
5:09:13I mentioned we're going to have a list
5:09:14of channels that we're monitoring. So
5:09:15the very first thing is I'm going to
5:09:16make a table called channels. And over
5:09:18here I'll just have it say channel ID on
5:09:21YouTube. What you do in order to get all
5:09:23the data about a channel is you need you
5:09:24need their ID. And if you're unfamiliar
5:09:26with how that works, I'm going to go
5:09:27over to my channel here. You can grab
5:09:30the ID of Sorry about that. You can grab
5:09:32the ID of a YouTube channel just by
5:09:33going uh I think more and then all the
5:09:36way down to the bottom share channel,
5:09:38copy channel ID. Okay, most people now
5:09:40use like little acronym versions like I
5:09:42do at Nixxive as opposed to channel ID.
5:09:44So you can't grab that through the URL
5:09:45for a lot of channels, but if you find
5:09:46yourself in that situation, you can get
5:09:47it from there. Okay, so what I'm going
5:09:49to do is I'm just going to test all this
5:09:50stuff out on one channel because, you
5:09:52know, that's really all that matters to
5:09:54me to start and then once I've tested it
5:09:56on one channel, then I can worry about
5:09:57dealing with all the other channels and
5:09:59I'm just going to brainstorm everything
5:10:00that I'm thinking about live. so that
5:10:01even when I do end up in a detour in
5:10:03some sort of crappy hole, you know, you
5:10:05guys will see how I do the debugging of
5:10:07this as well. So, first thing I'm going
5:10:08to do is add a trigger where when I
5:10:10click this test workflow button, it runs
5:10:12the flow and that's pretty simple.
5:10:13Second, I'm going to use a Google Sheets
5:10:15node. And what I want is I just want
5:10:16some way to grab the data. So, I'm going
5:10:18to use the get rows in sheet node. Here,
5:10:21I have the ability to add my
5:10:22credentials. Now, if you haven't added
5:10:23credentials before, I'm going to show
5:10:24you how to do it for YouTube in a
5:10:25second. In Google Sheets, all you do is
5:10:27you click oath 2 and then click sign in
5:10:29with Google. Okay, very straightforward,
5:10:30very simple. I've already done this, so
5:10:32I'm just going to close this out and
5:10:33then select the credential that I have,
5:10:35which I'm just calling YouTube. The
5:10:36resource is going to be sheet within
5:10:37document operation get rows. And then
5:10:39the document that I want, it's going to
5:10:41be this one I just created, YouTube
5:10:42trend detector database. The sheet that
5:10:44I want, if you think about it, is
5:10:45channels because I'm just going to
5:10:46select from this list of channels that
5:10:47I'm monitoring. And that's how we're
5:10:48going to build the flow. Okay, then I
5:10:50click test step. Okay, what am I doing?
5:10:52I actually now have got the data from
5:10:54the Google sheet into NAD. So, we are
5:10:56good. Next, I'm just going to pin the
5:10:58data. And the reason why I'm pinning the
5:10:59data and I always recommend pinning
5:11:01Google Sheets steps is just because you
5:11:02know when you turn it from green to
5:11:04purple um instead of having to do the
5:11:05API call to the Google Sheets API again
5:11:08what you can do by pinning it is just
5:11:09like cache or persist the data directly
5:11:11in NAN which means that for all future
5:11:13runs of this like if I want to test the
5:11:14workflow it actually just automatically
5:11:16grabs that data and then runs it
5:11:18through. I don't actually have to like
5:11:18physically make a request to Google. The
5:11:20reason why this is valuable is because
5:11:22they tend to be very fragile these APIs.
5:11:24So, if you always test every 3 seconds
5:11:26like I normally do, I'm very um
5:11:27incremental with my testing for good
5:11:29reason, which I'll tell you about in a
5:11:30minute. You know, sometimes the API gets
5:11:31overwhelmed and then you end up just
5:11:32having to like wait like 5 minutes. Who
5:11:34the hell wants to wait 5 minutes, right?
5:11:36Okay. So, next up, now that I have the
5:11:38channel ID, if you think about it, I
5:11:39kind of want to grab the video. So, I'm
5:11:40going to go YouTube right here. And uh
5:11:41there are a lot of different functions I
5:11:43grab a channel, get many channels,
5:11:44updated channel uploaded, channel
5:11:46banner, playlists here, playlist items.
5:11:48Okay, so what I want is the get many
5:11:50videos. Now you see it'll say credential
5:11:52to connect with YouTube account. So I've
5:11:54already done this but I'm going to
5:11:55pretend that I have an set it up from
5:11:56scratch for you. Okay. So when you click
5:11:58add connection it'll say oath redirect
5:12:00URL and then you'll grab the URL here
5:12:02and it'll have this little callback
5:12:03thing. Don't worry too much about this.
5:12:05This is just like a way that it opens
5:12:06the window up in NAN. What you need to
5:12:08fill is you need to fill this client ID
5:12:10and then this client secret section. If
5:12:12you don't know how to do any of this
5:12:13stuff, just click open docs. Naden
5:12:14actually has pretty good docs on how to
5:12:16get up and running with like service
5:12:17accounts and whatnot. I'll run you
5:12:18through what this actually looks like.
5:12:19What you have to do is you have to go
5:12:20like
5:12:21console.cloud.google.com just like this.
5:12:23And then what you have to do is you have
5:12:24to make a project. Now I've already made
5:12:26a project. So I'm at my first project
5:12:28here. Okay. But what making a project
5:12:30does is you basically just give it a
5:12:31name. So as you see my website here's
5:12:32leftclick. I basically just gave it a
5:12:34name and now it says my first project.
5:12:36What you have to do next is you have to
5:12:36go to APIs and services. Then what you
5:12:39have to do is you have to go YouTube.
5:12:40And when you go to YouTube you'll find
5:12:42the YouTube data API. In my case it's
5:12:43V3. Maybe you're watching this video in
5:12:452027 after the robots have won. So uh
5:12:47maybe you are a robot. in which case,
5:12:49please spare me and my family. Those
5:12:50will be a this might be a V something
5:12:53else. Okay. Uh you're going to want to
5:12:54click like I forget what the verbage is,
5:12:56but I think it's like, you know, add or
5:12:58enable or something. Once you're done
5:12:59with that, if you go to manage, then
5:13:02you'll go down to credentials over here
5:13:04on the right hand side. And then what
5:13:07you what you'll have is you'll have two
5:13:08sections. You'll have like um API keys
5:13:09and OOTH 2.0 client IDs. Now, I've
5:13:11actually already created my own
5:13:12credentials here quite a while ago for
5:13:14uh for YouTube and whatnot. What you can
5:13:16do is you can go ooth client ID and then
5:13:18here you actually create your own. So
5:13:20what I'm going to do
5:13:21is was it web application? There we go.
5:13:24And then the name will be whatever you
5:13:25want. Whatever I
5:13:27want. Okay. Um under authorized
5:13:30JavaScript origins and authorized
5:13:32redirect URIs. We're going to go back to
5:13:35here. Go back to the YouTube or other
5:13:39Google specs. And then what we want is
5:13:42we want this OOTH single service. So now
5:13:45it's going to walk us through all these
5:13:46steps. Figure out OOTH consent screen.
5:13:49Let me see. Let me see. From your NAN
5:13:51credential, copy the OOTH redirect URL.
5:13:54Paste into the authorized redirect URIs
5:13:56in Google console. Okay, great. So what
5:13:57that means is we go back here. You see
5:13:59how it says OOTH redirect? You got to
5:14:00give that a copy and then go back over
5:14:02here to where it says authorized
5:14:03redirect URIs. We have actually to paste
5:14:05that in. Okay, once you're done, click
5:14:08create. Now you're going to have two
5:14:09things. You have a client ID up here at
5:14:11the top, which we're going to copy. And
5:14:12then I also have a client secret. So
5:14:14what I'm going to do is I'm going to
5:14:15paste in the client ID here and go over
5:14:17here and I'll paste in the client secret
5:14:19here as well. And you'll get this signin
5:14:20with Google box. Now after you're done
5:14:22with that, this will now open up a
5:14:24Google signin window. Then click the
5:14:26email that's associated with the account
5:14:27that you just created. Go down to allow.
5:14:30All
5:14:31right. From here it is now connected.
5:14:33You can close your window and you've
5:14:34actually now done the connection.
5:14:36Remember that first step where you have
5:14:38to set up that cloud account. What you
5:14:40have to do is you I think they give you
5:14:41like 300 bucks in free credits or
5:14:43something like that. You functionally
5:14:44will not run out of credits. I mean you
5:14:45know your free trial is over but your
5:14:46cloud platform journey doesn't have to
5:14:48be. I think you can like continue doing
5:14:50your API calls below a certain limit or
5:14:51something like that. Anywh who uh from
5:14:53there credential to connect with is
5:14:54YouTube account 2 resource video
5:14:56operation get many return all. I'm just
5:14:58going to have the limit be like three
5:14:59videos for now. Filters we'll leave
5:15:02channel ID. And then what I want to do
5:15:04is just feed in the channel ID directly
5:15:05in here. So, what this is is this is
5:15:07just like hooking me up to a specific
5:15:08channel as we see. I'm just going to
5:15:10click test step and we're going to see
5:15:11what happens. Okay, awesome. And it
5:15:13looks like we've now received a bunch of
5:15:15data. That's pretty cool, right? So,
5:15:17we've now verified that we can do a fair
5:15:18amount here. And if I just go back to my
5:15:21little road map here, we've now verified
5:15:23that we can actually get all the videos
5:15:25for a channel, which is great. Okay. All
5:15:27right. So, now that we've gotten all the
5:15:28videos for the channel, what I want to
5:15:29do, well, not all of them, but three of
5:15:30them. I'm just going to pin this data
5:15:31again. So, now I have access to these
5:15:34three items. And now what I'm going to
5:15:35do is I'll go back to YouTube and
5:15:37logically what I'm going to do next is
5:15:38we're going to get a video just like
5:15:40this. Now you'll already have the
5:15:41credential that we added. So this is the
5:15:43second one, the one that I just created.
5:15:44So I'll go there. And then you see where
5:15:46it says video operation get. Well, now
5:15:47we need to feed in the specific video
5:15:49from the giant list of videos that we
5:15:50just got. And you'll find this I think
5:15:53here at least. Yeah, I'm pretty sure
5:15:55that looks to me like a video ID, right?
5:15:57Okay. So now if I click test step, it's
5:16:00actually going to run on all three of
5:16:01these items. But to be honest, when I
5:16:03test APIs, I only really like to run it
5:16:05at one at a time. So I'm going to click
5:16:06on this button in between. I'll just
5:16:07type limit. And what this does is this
5:16:09basically just limits it. So if there
5:16:10were three items initially, now there's
5:16:11only one item. So we're only grabbing
5:16:13the first in this case. You can also go
5:16:14last if you want. I just go first. Okay.
5:16:17So now what I'm doing is you see how on
5:16:19the purple it said three items up here
5:16:21and then over here it says one item.
5:16:23Well, basically that's what this limit
5:16:24node did. It just like took those three
5:16:26and then it like just converted it all
5:16:28into into just one. It didn't merge them
5:16:30or anything. I guess what I'm trying to
5:16:31say is it just like deleted the last
5:16:32two. So now that there's just one item
5:16:34as input, when I run this this video ID,
5:16:36it should only run once. So click test
5:16:38out. So I'm going to grab a specific
5:16:40video. And that's what it did. It just
5:16:42ran once for one item. Now what's
5:16:44interesting, I'm going to go to see
5:16:45schema view here. It's probably easiest
5:16:46for you guys to understand. So we go
5:16:48back to schema view. What we see now is
5:16:50we're getting a ton more data about the
5:16:51specific video. Like on the left hand
5:16:53side, do you see how there's like no
5:16:54data about the specific video views or
5:16:56anything that I could use to determine
5:16:57if it's an outlier? Well, on the right
5:16:59hand side, we get that data. So, there's
5:17:00a bunch of thumbnail BS. I'm just going
5:17:02to close that. Tags, which is fine.
5:17:04Category localized. This is the title
5:17:06and
5:17:07description. Content details. Okay, so
5:17:09this is um this over here is going to be
5:17:11important for us. PT32s. This is
5:17:13interesting. Uh this is like a timestamp
5:17:16string basically showing how long the
5:17:18video is. In this case, this is 32
5:17:19seconds. So, I don't know what P stands
5:17:22for. I think T stands for time and then
5:17:2432 is obviously the number of seconds.
5:17:26Uh, but this could also be like PT 5
5:17:28minutes, PT3
5:17:30hours. This is just like the specific
5:17:32timestamp formula that uh for whatever
5:17:35reason YouTube uses. I don't know why
5:17:36they didn't just do the number of
5:17:37seconds. That make everybody's life so
5:17:38much easier, but they use a five um
5:17:41character string for seconds, which is
5:17:42annoying. But the thing is, if you think
5:17:44about it logically, like I don't want to
5:17:45grab shorts, right? So, I'm going to
5:17:46have to do a little bit of math here to
5:17:47uncouple this. And I'll run you through
5:17:48what the math looks like later. But
5:17:49anyway, the statistics are what we want,
5:17:51right? See how it says 12,690 and this
5:17:53one says 382 likes. So you can run out
5:17:55liar detection in a number of ways.
5:17:57Probably the simplest way is just views.
5:17:58But if you think about it, you could
5:18:00also run it on like views and likes. You
5:18:01could run it on just likes. You could
5:18:02run it on some multiplicative number
5:18:05here. You could like I don't know maybe
5:18:07mathematically you think that one like
5:18:09is worth 10 views just in terms of like
5:18:11its viral power. So what you do is you
5:18:13actually take likes, you multiply them
5:18:14by 10, and then you add them to views.
5:18:16And that's what you do to score them,
5:18:17right? This is totally for free. This is
5:18:20up for grabs. You can do whatever the
5:18:21heck you think based off of your
5:18:22knowledge determines whether a thing is
5:18:24more viral than something else. In my
5:18:26case, you know, I just want to give you
5:18:27guys a simple nugget system. I'm just
5:18:29going to use the view count. But anyway,
5:18:30so yeah. Okay, we we get a ton of data
5:18:32here. So, what I'm going to do is I'm
5:18:33going to pin this output. And what I
5:18:34want to do now is I actually want to
5:18:35filter out all the shorts cuz I hate
5:18:36shorts. I think shorts are not
5:18:38representative of this stuff at all,
5:18:40right? Like you could have two systems,
5:18:42one that operates off shorts and one
5:18:43that operates off long form, but you
5:18:45can't compare them apples to apples.
5:18:46They're so different. There's so many
5:18:47like discoverability issues and stuff
5:18:48like that. So, what does that mean? Uh,
5:18:49basically that means I have to filter
5:18:50out the shorts. There's nothing in the
5:18:52YouTube API, which is really annoying,
5:18:54that says whether something's a short or
5:18:55not, blows, but they they don't just
5:18:57have like a simple type short. So, what
5:19:00you have to do is you just have to infer
5:19:01it based off of the logic. So,
5:19:03realistically, if something's less than
5:19:0460 seconds, I'm going to call it a
5:19:06short. And then if something is over 60
5:19:07seconds, I'm going to call like a
5:19:08regular, you know, normal video for
5:19:10welladjusted human beings. So under
5:19:13content details duration PT32s, I need
5:19:15to somehow take this string and I need
5:19:17to use it to determine whether or not
5:19:19it's a short. Well, the way that this
5:19:20works, I know for a fact S means second
5:19:23and then if it's a minute, it'll be like
5:19:26PT5 minute 32 seconds. So this here,
5:19:29this string would mean the video is 5
5:19:31minutes and 32 seconds. I think if it's
5:19:33like 3 hours, it would be 3 hours 5
5:19:35minutes and 32 seconds. What does that
5:19:36mean? I can actually just use the length
5:19:38of this thing. If this thing is like
5:19:39five characters and then the last letter
5:19:41is S, odds are this is a short to be
5:19:43honest cuz the second you get over 60
5:19:45seconds it just changes to minute,
5:19:46right? So I think that's the logic I'm
5:19:48going to use. I don't know if it's 100%
5:19:49but we'll give it a try. So how do you
5:19:51actually do this? I'm just going to use
5:19:52the the filter node and then I'm going
5:19:54to feed in
5:19:55the scrolling all the way down here. The
5:19:58duration I'm just going to go.length
5:20:00length here and I'll say if this is
5:20:03equal to five and the last
5:20:08letter. So let's go to
5:20:10expression if this ends with
5:20:14um
5:20:16s then I know that it's not a short uh
5:20:21then I know that it is a short.
5:20:25Okay. So logically I'm actually looking
5:20:27for the inverse of this. Can I do the
5:20:29inverse of this? How the hell do I do
5:20:31the inverse of this? I guess I say is
5:20:33not equal
5:20:35to. So this has to be not equal to
5:20:40five. Sorry, I'm using string here, but
5:20:42I should be using number. There we go.
5:20:44So this has to not be equal to five. And
5:20:46then this last
5:20:47thing has to not end with s. Okay, that
5:20:52makes sense. So assuming that these two
5:20:54are true, odds are it's probably not
5:20:57going to be short. So I just ran it and
5:20:59uh it says kept zero, discarded one. So
5:21:01that means that basically this node
5:21:04returned nothing, right? Because there
5:21:06was one item here and then it hit my
5:21:08beautiful sexy filter, my anti-short
5:21:10terminator and then you know there was
5:21:12nothing that wasn't a short to remain.
5:21:14So if I want to continue testing this
5:21:15flow logically, what do I have to do?
5:21:17Well, I kind of have to fill it with
5:21:18like real data, right? So I'm just going
5:21:20to change the limit node and then just
5:21:22cross my fingers and hope that I can
5:21:23return more than just a short. Let's go
5:21:25three this time. I'm going to unpin
5:21:27it. I'm just going to go where's the PT?
5:21:31Right. PT. Get all videos. Three items.
5:21:35Now we're returning three items. Now for
5:21:36each of these, I'm just going to test
5:21:37three
5:21:38times. Bang. Bang. Bang. Okay, now we've
5:21:41done three. And um underneath this
5:21:44duration, this one's PT32s. If I go to
5:21:47JSON, I should be able to get all them,
5:21:48right? So PT32S. Where is that? Where is
5:21:51that? Okay, so this is that short.
5:21:52That's what number one.
5:21:55This next one is 38
5:21:58seconds. This last one's 59 seconds. Oh
5:22:01jeez. You know what I'm realizing? I
5:22:02think this is like This actually sorts
5:22:04all of my videos by shortest to longest.
5:22:07So obviously the first three are going
5:22:08to be
5:22:09shorts. Uh that's brutal. Can I like not
5:22:12do this? Hm. Is there some way to get
5:22:14all videos and then sort it
5:22:17by what do I order it by? Relevance.
5:22:20Date. You know, screw it. Let's just do
5:22:21date. This is This should fix it because
5:22:22I haven't posted shorts in a while.
5:22:23Let's test this again.
5:22:25Okay. All right. Yes, this is uh
5:22:28relevant. He quit his job after his age.
5:22:30You see, I just I just published this
5:22:31one. So cool. We can now pin this. So I
5:22:33just clicking the node, pressing P. Then
5:22:35I'm going to do
5:22:36limit. And now I know for a fact that
5:22:38the first item is going to be good. So
5:22:40I'm just going to change that to one.
5:22:42All right, I'm liking this. I'm going to
5:22:44go over here. I'm going to test this
5:22:45now. Should run once. Cool. And let's
5:22:47see the duration. You guys see where
5:22:49it's 39 M26s, right? So this should
5:22:52work. I'm not going to pin this. And now
5:22:55when I run my wonderful filter
5:22:57test. Oh, hold on. It's still discarding
5:23:00it. Why is it discarding
5:23:02it? Um h something to do with my math
5:23:06here. So conditions is not equal to
5:23:09five. So that's good. And it does not
5:23:11end with
5:23:14us. Oh. Oh yeah, obviously it ends with
5:23:16us.
5:23:18Duh. Oh, okay. Sorry. I think I can
5:23:20actually just get rid of this.
5:23:22My bad. My bad. My bad on the S stuff,
5:23:24guys. Yeah, don't do the S stuff, right?
5:23:26That makes sense. Cool. Well, I said I'd
5:23:28keep in dumbass detour. So, there's one.
5:23:31Uh, yeah, obviously all of them are
5:23:33going to end with S because that's how
5:23:34they do it. They go like
5:23:37PT39M26s, right? Well, actually, if you
5:23:39think about it, if something's like 4
5:23:40seconds, it's probably going to put in
5:23:41here, right? So, instead of is not equal
5:23:44to, what I should do is I should say it
5:23:46needs to be greater than five because
5:23:48then it'll be at least 1 minute, right?
5:23:50That makes more sense. That's more
5:23:51logical.
5:23:52Okay. Yeah, that's way
5:23:54smarter. Cool. So, now that we have the
5:23:57video, question is, what do we do next?
5:23:59Say, I'm just going to go back to my
5:24:01thing. We now grab the individual video
5:24:03data. We've now filtered out long form.
5:24:05Now, we need to check if it exists in
5:24:06the database. Now, here's the thing. We
5:24:07don't actually have the database set up.
5:24:08So, it's kind of like uh chicken or the
5:24:11egg, right? So, first of all, I'm going
5:24:13to change this to one, and then I'll
5:24:15call this add update. Then later on I'll
5:24:19change um I'll add the other workflow
5:24:20and that'll be like daily
5:24:22digest. So if I go back to my little
5:24:25database over here my fledgling DB. Uh
5:24:27what is it that we have to do
5:24:30logically? Well I think what you should
5:24:33probably
5:24:36do
5:24:38is we have to check to see okay so
5:24:41here's here's how we can do this. you
5:24:42know this channel
5:24:44ID what we could do is we can make this
5:24:46the
5:24:47title in here we'd store all of the data
5:24:50of the video right right um I don't know
5:24:54even multiple and stuff like that but we
5:24:56need some way to like add the channel ID
5:24:59automatically so I'm just going to go to
5:25:00sheets I don't actually know if you can
5:25:01do this can you just like get all the
5:25:04sheets or
5:25:06something looks like you can create a
5:25:09sheet so that's interesting
5:25:12You can also get rows in a sheet, delete
5:25:13rows or columns in a sheet. Is there
5:25:15some way that I could like check to see
5:25:16the
5:25:18sheets? Logically, that would make
5:25:19sense, right? Can I just get rows in
5:25:21sheet check this out for me? Yeah, I'm
5:25:24not seeing a way to, which kind of
5:25:25blows.
5:25:27H I think what we'd have to do
5:25:33realistically. So we have to do one or
5:25:34two is
5:25:36one we rebuild the whole database every
5:25:39single time that we run this which would
5:25:42be very computationally expensive. It
5:25:44would hit the API a lot. It would just
5:25:45not be smart. Or two, we need like an
5:25:49initialization thing where every time we
5:25:52initialize it, like we feed it in a list
5:25:54of channels, then it initializes the
5:25:55whole sheet for us. And then we do that
5:25:57anytime we want to update it. Or what we
5:25:59do is we just have a simple SOP where
5:26:00anytime I want to duplicate this, I I
5:26:02grab the sheet like this. Okay? And what
5:26:05I do is I just duplicate this and then I
5:26:08change the ID to, you know, new channel
5:26:11ID. That makes sense to me because then
5:26:14the system would automatically just
5:26:15start dumping into the new one. Okay,
5:26:16cool. I think that's probably what we're
5:26:17going to do for simplicity. I want you
5:26:19guys to know there's a million one
5:26:20different ways to do this and I am a
5:26:21very hacky human being so I prefer the
5:26:23hacky approach. Okay, so what am I going
5:26:24to do with the Google sheet? Well, now
5:26:26that we've identified that it's not
5:26:27short. Obviously, we need to add it,
5:26:28right? So, I'm going to go sheets. I'll
5:26:30go append or update row and sheet. I'll
5:26:32go YouTube resource operation. Okay,
5:26:36document from the list. I'm going to go
5:26:37pick my YouTube trend detector database.
5:26:40The sheet I'm I'm curious about. Notice
5:26:41how I have the channel right here.
5:26:43Right? This is where it's going to get a
5:26:45little trickier and this where I'm going
5:26:46to need to go back and update my logic
5:26:47probably, but I'm going to need to use
5:26:49the ID connected to the specific channel
5:26:54where I'm adding the video. Okay, the
5:26:57thing is we don't currently have any
5:26:58columns yet. So, we have to do now is we
5:27:01have to map all of this data or all the
5:27:04data that we're actually interested in
5:27:05that is. So, what data am I actually
5:27:07interested in? Well, I'm obviously I'm
5:27:09interested in a couple things. So the ID
5:27:11of the video, right? So I'm going to add
5:27:12ID here. This is going to be probably
5:27:15like my unique identifier, right? Like
5:27:17this is the one thing on all videos
5:27:18that's always going to stay the same per
5:27:19video cuz if you think about it, people
5:27:21can change their title. People can also
5:27:22change their description. Like this is
5:27:23the thing that I have to like use as my
5:27:25unique thing. And all databases need
5:27:27some sort of unique thing. So I'm going
5:27:29to do the ID for sure. What I want as
5:27:31well. Published at that sounds like it's
5:27:32good to keep track of. Channel ID. I
5:27:35mean like I kind of have it here, but I
5:27:36I don't know. I'll just I'll add my
5:27:38channel ID. Maybe it's just going to be
5:27:39easier for me. Also, I'm realizing that
5:27:41I'm changing my conventions. There's two
5:27:43major conventions in programming.
5:27:44There's um camel case, which is where
5:27:45you
5:27:47go something like that. And then there's
5:27:49I think it's called snake case, which is
5:27:51like
5:27:52this. Uh and I'm changing my conventions
5:27:54right now. Like I'm going from camel
5:27:55case to the other thing. I think most
5:27:58things in nad use
5:28:00um snake case, so I'm going to do that.
5:28:02That seems simpler. Okay. So, next up,
5:28:05what do we need? We obviously need the
5:28:06title. That seems good. Description. I
5:28:08mean, I feel like the description is
5:28:09good to keep track of. Let's see the
5:28:10description. Screw it. Thumbnails. Hm.
5:28:12Looks like there's three types of
5:28:13thumbnails. There's like small
5:28:15thumbnails, medium thumbnails, high, and
5:28:17then standard. So, why don't I
5:28:19do Why don't I just do it like this?
5:28:21Small thumbs, medium, uh, sorry, there I
5:28:25go again. Small
5:28:27thumb, medium thumb, large thumb,
5:28:31standard thumb. This is just going to be
5:28:33the URLs. I don't really care about the
5:28:34heights or whatever.
5:28:37Channel title. Is that
5:28:39necessary? Yeah, I might as well. Right.
5:28:43We'll go channel
5:28:45title. Okay. What else do I want? Uh
5:28:49tags. I could theoretically just dump
5:28:51all the tags. So, I should probably do
5:28:53that. I'm so lazy. I'm like, do we need
5:28:56the tags? Yeah, we kind of need the
5:28:58tags. All right. Category ID. I don't
5:29:00know what the heck that is. I don't
5:29:01really think it's that valuable. I'm
5:29:02sure, you know, you can imagine a world
5:29:04where category ID is valuable, but I
5:29:05don't, you know, I don't really know
5:29:07what that means, so I'm going to leave
5:29:08it
5:29:09up. Okay. Content details, duration.
5:29:11That's gonna be important. So, we'll go
5:29:14duration, dimension, definition. I could
5:29:17see you running some stats on that
5:29:18stuff, right? Like maybe in the future,
5:29:21like you notice that most multiples are
5:29:22HD or something that might give you some
5:29:26data. Okay. And then ultimately, the
5:29:28stats are what we actually care about.
5:29:30So, good god, look how far off this is.
5:29:32Okay, the way that I like to organize my
5:29:34databases is I just like to have like
5:29:35the most important information first and
5:29:37then I stick all the less important
5:29:39information later. So, to be honest,
5:29:40we're going to need to rearrange this.
5:29:41Like, are are you going to care about
5:29:43the thumbnails for most of these? No,
5:29:44obviously not. So, we're just going to
5:29:46dump these all the way to the right.
5:29:48What are we actually going to care
5:29:49about? If you think about the view
5:29:50count, like count, favorite count, and
5:29:51comment count. I don't know what the
5:29:52favorite count is, and I don't know why
5:29:54nobody favored that video. Granted, I
5:29:55did publish it yesterday, but can y'all
5:29:58please favorite my video? I would love
5:30:00you a long
5:30:02time. Okay, so
5:30:05views. Just go views, we'll go likes,
5:30:08we'll go favorites, and then we'll go
5:30:13comments. Now, depending on whether this
5:30:17is normal, maybe we'll go title, views,
5:30:18likes, comments, favorites, and then if
5:30:20you think about it, like channel ID,
5:30:21channel title. Yeah, we don't need these
5:30:22either cuz it's kind of self-evident.
5:30:24Like it's good data to have just because
5:30:26it'll make my life easier when I build
5:30:27out the rest of the stuff, but it's not
5:30:29necessary. And then embed HTML. That
5:30:30sounds fun. Let's go embedd HTML. Cool.
5:30:32So, I'm pretty sure now we have
5:30:33everything that we need, right? I'm just
5:30:35going to rearrange this by selecting
5:30:36everything and then double clicking on
5:30:38the um column tag. So, we have the ID,
5:30:40publish at, it'll say title, then it'll
5:30:41say number of views, likes, comments,
5:30:43and it'll say favorites. Then it'll say
5:30:44the description, tags, duration,
5:30:47definition. Cool. Looks like a pretty
5:30:49good database to me. This is going to be
5:30:50our template DB from now on, right? So I
5:30:52just wanted to make it perfect or as
5:30:54perfect as possible. So now what we have
5:30:55to do is we actually have to add it to
5:30:56the sheet. Actually first thing we have
5:30:57to check if it exists in the database.
5:30:59My bad. My bad. After that though we'll
5:31:00add it. So let's actually just implement
5:31:02the adding functionality right now and
5:31:03then we'll do the checking if it exists
5:31:05functionality afterwards. So we need to
5:31:06map it manually. So I'm just going to
5:31:08fetch the columns by refreshing this.
5:31:10It's not finding it. Why? Uh, I think we
5:31:13might have to
5:31:15go I think I might have to refresh this
5:31:17or
5:31:20something. Kind of
5:31:23annoying. So, I think I got to feed in
5:31:26the channel ID
5:31:31here. Okay, so the way that the append
5:31:34or update row works is there's an ID
5:31:36column that you actually match incoming
5:31:38queries in. So, that's actually cool. We
5:31:40don't actually need to do the logic. I
5:31:42just talked about because it'll just
5:31:43automatically find old entries and
5:31:45update them using the ID column which is
5:31:47incredible. So fantastic. Boy is NAN fun
5:31:50sometimes. Now what we have to do is we
5:31:52have to do this annoying laborious
5:31:54process of just mapping everything. So
5:31:55I'm going to map the title over here. Uh
5:31:58now I'm going to go down to the views
5:31:59cuz I was a little presumptuous and I
5:32:02wanted the views to be first. I wanted
5:32:05all my viral videos to be first, baby.
5:32:07Okay. Favorite. Cool. Now we'll go all
5:32:10the way up to description.
5:32:12Uh tags is going to be interesting if
5:32:14you think about it logically. Like look,
5:32:15there's a bunch of tags here, right? So
5:32:16how do you actually like get a specific
5:32:18tag in there? Um you got to use string
5:32:20logic. So just going to put tags in. And
5:32:22then you see how it's an array right
5:32:24now. You just join the array um with
5:32:25some sort of delimiter. And now we have
5:32:27all the tags here. I like adding a
5:32:29delimiter and a space. I don't know why.
5:32:31I just I think it like works and looks
5:32:33better. It works better with more
5:32:34platforms. So I'm just going to do tags
5:32:35like that. The duration. That was pretty
5:32:37interesting, right? So where's the
5:32:38duration again? Okay. Okay. right over
5:32:41here.
5:32:44PT39M26S. So, h
5:32:49uh okay, I'm just trying to think in my
5:32:51head, what's the simplest way for us to
5:32:52do this that works on arbitrary strings?
5:32:54Let's just open up the expression
5:32:56handler. So, if I split this based off
5:33:00the presence of an H, what do we have?
5:33:01The whole thing, right? If I split this
5:33:03off the presence of an M, what do we
5:33:05get? Is it always going to be PT? Let's
5:33:08just do GBD40
5:33:11[Music]
5:33:12PT3926S
5:33:1439M26S. What is this format called?
5:33:17Let's see if we can get an answer from
5:33:19the lovely Galaxy Brain. ISO 8601
5:33:22duration format. I want to parse
5:33:26this functions and turn it into the
5:33:30number of seconds. Simplest way. Let's
5:33:33see what it tells me. Paris, duration.
5:33:35It matches this PT whatever. Oh, I get
5:33:38it. So, it's actually extracting three
5:33:40types of data. The number of hours, the
5:33:42number of minutes, and the number of
5:33:44seconds. Uh, could I just match this
5:33:46inside of here? Let's see. So, this is
5:33:50reject. No, match. Okay. So, yeah. Yeah,
5:33:52we got a match over here. Can I just
5:33:53copy this? This would be sick if I could
5:33:55just copy this. Maybe I
5:33:57can. This is going to look like magic if
5:33:59you don't know what reax is, but it's
5:34:00actually pretty cool. Yeah. So, it just
5:34:02did that. How neat is that?
5:34:04Okay. So now if I want to get the
5:34:07duration, what I have to
5:34:09do, is this matching globally? I think
5:34:12it
5:34:13is. What I want to do is it looks like
5:34:17this array will always have four
5:34:18elements. Okay, it's always going to
5:34:20have pt what? It's going to have the
5:34:22full string first, then it's going to
5:34:23have null, then it's going to have the
5:34:24number of minutes, and it's going to
5:34:25have the number of seconds. If you think
5:34:26about it, I just multiply the number of
5:34:28minutes by 60 to get the number of
5:34:30seconds times minutes. Uh, right? So 39
5:34:33* 60 would be the number of seconds and
5:34:34then 26 I just add that. So I'm pretty
5:34:38sure what I have to do is I think I have
5:34:42to add this is going to be tough. What's
5:34:45the simplest way for me to do this in
5:34:47such a way that
5:34:48like isn't super complicated. I mean I
5:34:51could just use a code node. I'm just
5:34:52trying to stay away from code nodes
5:34:54because I want to keep this really
5:34:55simple. Okay. So in an array you can
5:34:57index it with square brackets. So zero
5:34:59would actually select the first element.
5:35:02One would select the second element, two
5:35:04would select the third, and then three
5:35:05would select the fourth. It's zero
5:35:07indexed, right? So, it actually goes
5:35:08like there's only four elements. So, if
5:35:09I put four, it's selecting the fifth. We
5:35:11can't see it, but three, we can. So,
5:35:12what does this mean? If we want to get
5:35:13the total duration in seconds, I
5:35:16basically grab the total number of
5:35:18seconds, right? And
5:35:21then let's just actually, yeah, we kind
5:35:24of have to do code here, but anyway, I'm
5:35:26going to grab the number of seconds. I'm
5:35:27going to add
5:35:28it. Oh, it's not allowing me to add it
5:35:31because it's a
5:35:33string. I think we have to go probably
5:35:36two number here. Then we'll go two
5:35:39number. Now it should be 52. Okay, cool.
5:35:41So, what we do next
5:35:43is we go
5:35:46two, we multiply this by 60. That's the
5:35:49total number of seconds in the video.
5:35:502366.
5:35:52If you think about it, you kind of need
5:35:53to do the same thing
5:35:55for
5:35:571 * 60 *
5:36:0160. And voila, we should have a
5:36:04relatively consistent way to always get
5:36:06the number of seconds the video. Sanity
5:36:08check here. Let me go back here.
5:36:093926. 39 * 60 + 26 is 2366, which looks
5:36:14pretty good. Okay, so we did end up
5:36:17doing a little bit of code, and I'll be
5:36:18honest, it's not very pretty. This is um
5:36:21probably one of the uglier expression
5:36:22fields that I think I've made in my
5:36:25life. It's not very maintainable either.
5:36:27But what this is doing logically is this
5:36:29is using a regular expression to parse
5:36:30out three fields. The number of hours,
5:36:34the number of minutes, the number of
5:36:35seconds, and then it's just saying we're
5:36:36adding up seconds plus 60 * the number
5:36:39of minutes plus 60 * 60 * the number of
5:36:42hours. Okay. All right. Now, everything
5:36:44else here should be pretty easy. So,
5:36:45we're going to go definition. That seems
5:36:46good. It's for small thumbnail.
5:36:50I'm just going to feed in
5:36:52the default URL here, medium URL here,
5:36:57large URL here, and then standard URL,
5:36:59which I guess is the biggest. Oops. Um,
5:37:02I think I just deleted a field by
5:37:04accident. Channel ID was next. My bad.
5:37:07Channel
5:37:08title. So, channel ID was uh what? Right
5:37:12over here. Channel title was right over
5:37:16here. and all the way at the end. Embed
5:37:18HTML is over here. Okay. Good god, that
5:37:20took forever. Should now have everything
5:37:22we need,
5:37:23right? I think so. So, let us cross our
5:37:27fingers and add. Going to go over here,
5:37:29click test step, it's not adding. So,
5:37:32okay, it did end up adding. Very cool.
5:37:33Very cool. I don't like how it bumped it
5:37:35and made it really big, though. That's
5:37:36uh going to make looking at my database
5:37:38a pain in the ass. So, what I'm going to
5:37:39do here is I'll select all. I'm just
5:37:41going to drag this column to approximate
5:37:43what I think the normal size of a column
5:37:44is. That's a little short. There you go.
5:37:47So now all future columns will look like
5:37:49that. Also, uh I'm going to rearrange
5:37:52this. I just double tapped on it again.
5:37:54It's a little big. I don't like the
5:37:57description being that big, but I do
5:37:59think it's important that I can like
5:38:00read it at a glance. So I'm just going
5:38:02to rearrange the
5:38:04description. Rearrange the tags as
5:38:10well. That looks fine to me. Duration
5:38:13looks good. Small thumb, large thumb. If
5:38:14I just copy this, paste this, am I going
5:38:16to get the thumbnail? I will. Wonderful.
5:38:17Got the iframe as well. This is just
5:38:19something you can embed in your website,
5:38:20which is kind of neat. But yeah, I don't
5:38:21need the whole thing. So, I'm just going
5:38:23to make this a lot smaller. Okay. So,
5:38:25yeah, now we have the database template.
5:38:26And if you think about it logically,
5:38:27what we can do is we can just duplicate
5:38:28this, right? Just duplicate this over
5:38:30and over and over and over again for
5:38:31every video. So, if I go back here, uh,
5:38:34we've now done two things in one shot.
5:38:36We've actually automatically checked if
5:38:37it exists in the database with the
5:38:39append logic. And then if it does exist
5:38:40in the database, then we don't add it.
5:38:42We update it. And then if it does, it
5:38:43Yeah. So, we've actually finished this
5:38:45first system a lot faster than I thought
5:38:46we would. Very cool. Very cool. All
5:38:47right. So, what I want to do now that
5:38:48I've tested this on one item. Um,
5:38:51basically anytime you're you're building
5:38:53any sort of NAD system or really any
5:38:55automated system, test on one item first
5:38:58and then once you're done testing on one
5:39:00item, test on basically like two plus
5:39:02systems. This is sort of like your I
5:39:04don't know if you want to call it like
5:39:05your order of operations, but one is
5:39:08simple, right? Because it's very easy to
5:39:09get up and running with one example like
5:39:11we did a moment ago. Now, we need to
5:39:12test it on two examples. Odds are if
5:39:14something works on two examples, it's
5:39:15going to work on like n examples where n
5:39:17is the total number of examples that
5:39:18we're feeding it in. Like if it works on
5:39:20two, it's probably going to work on
5:39:21eight. If it works on eight, it's
5:39:22probably going to work on 3,894. Like
5:39:24that's just, you know, a programming
5:39:25thing. Logically, when you go from one
5:39:27to two, what you do now is you implement
5:39:28loop functionality. And that's one thing
5:39:29we have to verify. So we figured it out
5:39:32for one. Why don't we now try running
5:39:33this like on an actual practical test
5:39:35for two? Notice how everything right now
5:39:37is pinned, though, right? So I'm going
5:39:39to do is I'll go all the way back here,
5:39:41unpin. So, I just pressed
5:39:43P. And then this Google sheet here.
5:39:47Should I delete this? Yeah, I'm just
5:39:48going to delete it. Okay. And then I'm
5:39:50just going to save this now. Always
5:39:52save. And then where it says limit, just
5:39:55going to do the limit to two. And
5:39:57actually, I'm realizing that I think we
5:39:58can just set the limit here, right? No,
5:40:00we can just set the limit here. There's
5:40:01no need to do this. That was silly. So,
5:40:02what I'll do now is I'm actually just
5:40:04going to um do the limiting directly in
5:40:07the YouTube node here. Do two. Okay. And
5:40:11I'm not just going to test one. And I'm
5:40:12going to test all because um this is
5:40:14where the looping logic comes into
5:40:17play. Now it's adding or appending. And
5:40:20it looks like we got two. Cool. So let's
5:40:23just verify everything here worked fine.
5:40:25What is the duration of this video?
5:40:26That's like one pretty complicated piece
5:40:28of logic I implemented. So let me just
5:40:29double check. It's actually
5:40:311,628. I pretty sure it
5:40:34is. So 27 *
5:40:3860 and then 08. Yeah, that's true. That
5:40:41is actually it. Cool. Yeah. I mean, you
5:40:43know, I think we did it now. We've we've
5:40:44verified the test. Uh I guess there's
5:40:45one more test that we need to do. If you
5:40:47think about it logically, like we've
5:40:48tested that it works on one
5:40:50channel. So now let's test that it works
5:40:52on multiple channels. Okay. So I'm going
5:40:55to do now is I'm going to copy the ID
5:40:56that I have over
5:40:59here. And then I'm just going to do it
5:41:02for another channel. And then if I run
5:41:03into issues there, I'll I'll, you know,
5:41:05figure out the issues. So, who whose
5:41:06other channel I want to do Leonardo
5:41:09Gregarios just cuz this guy's one of the
5:41:12nicest. Okay, there we go. Okay, so
5:41:14copying this now. What am I going to do
5:41:16next? Well, I'm just going to add it to
5:41:17my channels thing. Paste it in. If you
5:41:20think about it, I have my SOP, right?
5:41:21Like for all the channels I paste in,
5:41:23I'm just going to duplicate this now.
5:41:25And I'm just going to go over here. I'm
5:41:27just going to paste in the new ID. And
5:41:30I'm just going to like delete both of
5:41:31these. Let's delete this. Now when I
5:41:35rerun this um what I should do is if you
5:41:37think about it logically I should grab
5:41:39both of the rows from both of the rows I
5:41:42should then get all the videos for the
5:41:44person then I should get all the
5:41:46specific videos of the all the videos
5:41:49ids and I should filter out all shorts
5:41:51and then I should add or append to the
5:41:52sheet and it should go logically newest
5:41:55to oldest. Okay, I think this is his ID.
5:41:57We're going to give it a
5:41:59go. So it's reading the sheets 2 44. I
5:42:03mean, mathematically looks good to me.
5:42:04Now it's updating all
5:42:06four. No, it didn't end up working. And
5:42:09why? It looks like we just dumped all of
5:42:11Leo's videos into my channel.
5:42:14H, ain't that a metaphor for life?
5:42:19Uh, okay. I think I know where this
5:42:22happened. The appender update right now
5:42:24is probably hard- coding me,
5:42:26right? I'm feeding in
5:42:29JSON.nippet. ID. What I think I need to
5:42:31be
5:42:32doing is I need to be changing this
5:42:35dynamically,
5:42:36right? So, right now we are feeding in
5:42:39this channel ID here. No, this should
5:42:42logically be working. This channel ID
5:42:44should change, right? Should change. So,
5:42:47let me just check the JSON now. I'm
5:42:48checking the JSON of the entries.
5:42:50Channel ID here was UCBO. Whatever.
5:42:52Okay, cool. That's fine. This other one
5:42:55should probably be UCBO as well, cuz
5:42:56that's me. Okay, now for this one, that
5:42:58should be not be mine. Should be UC8.
5:43:02Yeah, UC OB. So that looks good. Is it
5:43:05not finding mine?
5:43:07Maybe
5:43:09H. Maybe I just copy this
5:43:12now. Paste this in. Is this the same
5:43:15thing? Yeah, this is the same thing as
5:43:17this thing. Not really sure where this
5:43:19issue is arising from.
5:43:23Well, there may be like some builtin
5:43:26logic, a built-in that prevents it from
5:43:33iterating. I've seen this happen before.
5:43:36I feel like this has actually happened
5:43:37to me before where NAN does not have the
5:43:39ability to do this, believe it or not.
5:43:44So, what I the way that I saw this
5:43:46before was I added a bunch I created a
5:43:48bunch of new Google Sheets, one for
5:43:50channel. That's not going to work now.
5:43:52That's not going to work at all. So, I'm
5:43:54going to have to find a new solution to
5:43:55this and I'll have to do a live.
5:43:59So, what I'm going to
5:44:02try is naden has an additional piece of
5:44:04functional. This is a bug to be
5:44:06abundantly clear. This should not occur.
5:44:08Logically speaking, we're feeding in new
5:44:10channel IDs to a sheet and that variable
5:44:12should persist should not persist. It
5:44:14should reset at the beginning of every
5:44:16uh loop. But for whatever reason, it's
5:44:18not. So, we have to do
5:44:21is we have to feed we we have to take a
5:44:24fundamentally different approach. I'm
5:44:25going to do this approach using the loop
5:44:26over items um note. Okay? I want you
5:44:29know that stuff like this is going to
5:44:30happen. What's important is that you
5:44:32just don't freak out get super emotional
5:44:34about your system just not
5:44:36working cuz if you do you know the
5:44:39likelihood that it will continue to not
5:44:40work is much higher than if you don't.
5:44:43So what I'm thinking we're going to do
5:44:45is for every item that comes in we're
5:44:46actually going to loop over every
5:44:48individual item. Okay. The loop over
5:44:50items batches is basically a place uh a
5:44:52node that where you can add a loop route
5:44:53and then you can add a done route. The
5:44:55loop route just is whatever you're
5:44:58planning on doing. And then the output
5:44:59feeds back in. And then basically for
5:45:01the number of items you feed, in this
5:45:02case two, as we see, um it'll run once
5:45:05and then a loop and then it'll run twice
5:45:06and it'll loop again. So what I want to
5:45:08do is I want to see if me adding a loop
5:45:10over items node changes anything here
5:45:13materially. So I'm going to go back
5:45:15here. I'm going to delete all four of
5:45:18these.
5:45:19Then I'm going to see if I might need to
5:45:21update the the logic. So I'm going to
5:45:23test this first. Then I'm going to see
5:45:24if maybe there's some way we could reset
5:45:25the data because this, you know, it
5:45:27seems logical to me that we should be
5:45:28able
5:45:29to. Okay, so we're still dumping this
5:45:32in. We're still dumping everything,
5:45:33which is
5:45:34unfortunate. So let's see why. At least
5:45:36now we can actually logically run
5:45:38through both the items that are fed in.
5:45:40Okay, so this was run one, which will
5:45:43have two items, which is for me. This is
5:45:46run two, which will have two items for
5:45:47Leo.
5:45:50So the input should be the channel
5:45:53ID. Oh. Oh, I'm actually hard coding
5:45:56this now. My bad. My bad. Uh, we should
5:45:57actually be able to dynamically encode
5:45:59this now, right? So maybe maybe I
5:46:01actually screwed up here. Maybe I wasn't
5:46:02using a variable here. It's not over.
5:46:04It's not over just yet. We might have
5:46:06already fixed this. Okay. Now, what I
5:46:08don't like doing is I don't like doing
5:46:10what I'm showing you guys here where I'm
5:46:11constantly hitting the APIs over and
5:46:12over and over again. So, my
5:46:13recommendation is don't get yourself in
5:46:15this position to begin with because if
5:46:17you're constantly hitting these APIs,
5:46:18it's just a matter of time before one of
5:46:19them rate limits you and says, "Hey, you
5:46:20know, you've done this way too many uh
5:46:22way too many times." If you think about
5:46:23it, we're doing two API calls to this,
5:46:25another two API calls to this per API
5:46:27call, right? It's like four API calls
5:46:29total. Okay, I'm seeing um a missing
5:46:31parameter here now. This is good. It
5:46:33means that we're actually moving
5:46:35forward. Oh, what the hell's going on
5:46:38here? We got to re do I have to remap
5:46:41all
5:46:43this. I don't really know what's
5:46:45happening there. I think what happened
5:46:47is when I changed this out for the
5:46:49snippet
5:46:51variable, it momentarily pulled it off
5:46:55and then when it pulled it off, the
5:46:57variables here just stopped. They like
5:47:00disappeared. So that's not good. I
5:47:02wonder if that's going to happen every
5:47:03time. This took me a quite frankly
5:47:06stupid amount of time. So that's
5:47:07annoying. Um, but I'm just going to cut
5:47:09through this to save yall a little bit
5:47:12of time. Okay, I just ran this with a
5:47:14subset of the data so that I didn't have
5:47:16to remap it all if and when it
5:47:18inevitably broke and it worked. So, we
5:47:20actually got it. As you see, we have one
5:47:21here and then another here. So, what
5:47:23I'll do now is I'm just going to fill
5:47:24out the rest of this. Pretty stoked
5:47:25about it, though. I knew there'd be some
5:47:28issue and I'm glad that we got to work
5:47:29through it live. Okay, this has taken me
5:47:32a fair amount of time to do. So as
5:47:34opposed to trying to work it out
5:47:35logically, I'm actually just going to
5:47:36paste the code that I'm currently
5:47:37working on to try and uh recreate that
5:47:39duration match directly into chatbt and
5:47:42then say building this inside of N8
5:47:45TLDDR. I'm processing an ISO
5:47:498601 duration code and trying to turn it
5:47:53into a number of seconds. Here's what I
5:47:56have above. Debug why it isn't working.
5:47:59also need it to work even if there are
5:48:03no elements found. Let's try that. H I
5:48:06see. Well, that's very
5:48:09good. They're giving me a little snippet
5:48:11of code here. I don't know if this is
5:48:13true. H does look very good. Yeah, that
5:48:17is the number of seconds that I was
5:48:18looking
5:48:20for wrapped in this little function
5:48:23execution thing. So, it can be used
5:48:24directly inside of NAD. It's not as good
5:48:26as a code block, but this allows me to
5:48:28not have to use a code block. So, okay,
5:48:30I think I'll leave it there. This seems
5:48:31somewhat robust. I don't know for sure.
5:48:32Sometimes AI code just blows, but this
5:48:35is enough for me to actually run the
5:48:36test, which is what I care about. And
5:48:38then instead of me worrying about like
5:48:39whether or not it's perfect or complete,
5:48:41I'm actually just going to run the test
5:48:42and I'll let the test tell me. Okay, so
5:48:44let's test it. And you know, in reality,
5:48:46your systems won't cover all edge cases.
5:48:48The idea is that they just cover most
5:48:49edge cases. That's number one. That's my
5:48:51channel. And this should be Leo's
5:48:52channel now. Yes, looks good. I'm not
5:48:54seeing any tags on his videos. Why is
5:48:56that? Oh, wow. He must just not add
5:48:58tags. Oh, dude, you got to add some
5:48:59tags. Just make a note to text him. Bro,
5:49:01you got to add
5:49:04tags. All
5:49:07right. I'm sure he's going to find that
5:49:09pretty funny. Let's close this up and
5:49:11then Yeah. Okay, cool. So, we've now
5:49:13done that first section. And if you
5:49:15think about it, that's actually all we
5:49:16need to do because we just tested that
5:49:17it works on one. Uh then we tested that
5:49:19it works on two. So, we should now be
5:49:20able to do this on basically an infinite
5:49:22number, assuming that we don't rate
5:49:23limit out and stuff like that. It's a
5:49:25problem that some people will have. Next
5:49:26up, what we have to do is we have to do
5:49:27a daily digest. What this daily digest
5:49:29was going to do is it's going to grab
5:49:31all the data inside of that database of
5:49:33ours. Okay? So, it's going to list all
5:49:34of them. Then, for every sheet inside of
5:49:36our database, it's going to go through
5:49:38then it's going to get us all the
5:49:40videos. And then what we want to do is
5:49:43for every video, we want to calculate
5:49:45the average. So, for every list of
5:49:46videos, like this is a list of videos
5:49:47here, right? We want to calculate the
5:49:49average number of views and then we're
5:49:51going to use that to determine the
5:49:53multiple of the new video. And then if
5:49:55the multiple is over some threshold, aka
5:49:57the threshold that we define, which I
5:49:59think I'm just going to do like 2x like
5:50:01you know in multiple detection if you
5:50:02think about it logically, there are a
5:50:03variety of different ways you can do
5:50:04this. You use like 2x like 5x like 10x
5:50:072.5x. You could have it like change with
5:50:09time. You can define it somewhere else
5:50:10and you can do anything that you want
5:50:11really. I'm just probably going to do 2x
5:50:13cuz that seems simple to me. and then
5:50:15I'm going to include it in some sort of
5:50:16like daily email digest. Sounds fun.
5:50:18Okay, so let's build out the logic for
5:50:20that. That's going to be another NAN
5:50:23function or workflow. So I'm going to go
5:50:26back here. The way that I like to
5:50:27organize these is I like to tag them
5:50:29one. So Nad course and then also I like
5:50:32to do them same way I used to do them
5:50:34way back in the day on make.com. I used
5:50:36to go title YouTube trend detector ad
5:50:38update and then I'd go to YouTube trend
5:50:41detector. This would be daily digest.
5:50:44All right. So, these two are separate,
5:50:46right? And I'm running this manually
5:50:47right now, but if you think about it,
5:50:48realistically, you should be running
5:50:49this on some sort of schedule. So, we
5:50:52should add the schedule trigger to this
5:50:54instead. And then at you, you could add
5:50:56multiple triggers. So, now it's
5:50:58scheduled technically if I turn it on.
5:50:59Schedule I'm going to add is let's just
5:51:01do one. Let's trigger at I don't know 6
5:51:03a.m. or something like that at minute
5:51:05zero. So basically now every morning at
5:51:076, assuming that I turn this on, this is
5:51:09going to run and then it's going to
5:51:10proceed through the rest of my flow and
5:51:11just, you know, get get that first bit
5:51:13of work done, which is nice. And just
5:51:15because there's nothing on the done
5:51:16loop, I'm just going to add this here.
5:51:18This isn't the prettiest, but I Well,
5:51:20yeah, I think that looks okay. Notice
5:51:23how this was completely unnecessary if
5:51:25there were not bugs in NAN. There were
5:51:26bugs in NAN, which prevented us from
5:51:28doing this just cuz some of the data
5:51:30persisted when it probably shouldn't
5:51:31have, but you don't actually need this
5:51:32loop over items. Maybe future versions
5:51:34will solve this automatically. Okay, so
5:51:36let's do the daily digest. First thing
5:51:38we need to do is we just need to grab
5:51:39all of the data in all the sheets,
5:51:40right? So, this is going to be kind of
5:51:42tough to do. I don't actually know how
5:51:43we're going to do it.
5:51:46Um, what are we going to do? What are we
5:51:50going to do, ladies and gentlemen? All
5:51:51right, first thing we're going to do is
5:51:52we're going to grab all of the rows in
5:51:54the sheet. So, I'm going to go over here
5:51:55to channels. Just grab all the channel
5:51:57IDs. That makes sense, right? Talking to
5:52:00myself here, right?
5:52:03Okay, we're going to grab this. I'm
5:52:05going to test this. We're going to grab
5:52:07channels. Very cool. All right, I'm
5:52:09going to pin this. So, now we're going
5:52:11to have some pinned outputs here. Now
5:52:13that for every channel, what do we have
5:52:14to do? Well, we want to get all of the
5:52:17uh rows in the sheet for the sub
5:52:20channels.
5:52:21So, what am I going to do? I'm going to
5:52:23add my credential. And we may run into
5:52:25the same issue that we just ran into, by
5:52:26the way. So, YouTube trend detector
5:52:27database right over here. The sheet that
5:52:29I'm going to feed in is I'm going to use
5:52:31the name and then I'm actually just
5:52:33going to drag this in. Now this is going
5:52:35to be the expression node. So now what
5:52:37we should get logically, okay, is we
5:52:39should now ping this twice and then
5:52:41return four items in total. We're
5:52:43feeding into we should get four because
5:52:46um every uh sheet currently has two. So
5:52:49one, two for me, one, two for Leo,
5:52:50right? So I'm going to test the step and
5:52:52we'll see if we get it. As always, I'm
5:52:54I'm like expecting to get a certain
5:52:56output and I'm actually just rating what
5:52:58I'm expecting to get against what I
5:52:59actually get. Okay. So, the way that I
5:53:00like to see the data is using JSON. It's
5:53:02just easiest. So, he quit his job.
5:53:04That's good. Fix 90%. That's good. He
5:53:05quit his job. Fix 90%. Notice how this
5:53:08is run twice now on the same um ID.
5:53:11Okay. So, this is the same problem that
5:53:13we were running into before. Logically,
5:53:14we're going to have to find a way to
5:53:15solve it. So, let me think. Where are we
5:53:17going to add this? We're probably going
5:53:18to add the loop
5:53:19here. Delete the replace me. And then
5:53:21I'll delete this little route. And I
5:53:23think probably going to have to do is
5:53:24probably going to have to loop over
5:53:26this. So what I'm going to have to do
5:53:27actually is first I'm just going to run
5:53:28this so I can grab the data from the
5:53:30loop over items node. Okay, let's just
5:53:32test this workflow. Let's see what we
5:53:34get from here. We got a loop branch with
5:53:35one item with the channel ID. Okay.
5:53:37Okay. Very good. Very good. Now that we
5:53:39have this, I can actually map this
5:53:40individually. Now what I'm going to do
5:53:43is I'm going to let this loop over this.
5:53:45And now I'm going to let this go. And
5:53:46let's see if this fixes it. Do once,
5:53:50twice. Okay. Okay. And now we have two
5:53:52runs. So first run was me. Second run is
5:53:56Leo. Very cool. So we've actually gotten
5:53:57everything that we need. How cool is
5:53:58that? All right. So where we at now? So
5:54:00we got all sheets. We got videos in each
5:54:02sheet. Now for each list of videos, what
5:54:04we need to do is we need to calculate
5:54:05the average. How do we calculate the
5:54:06average? Well, in NAN, we're returning a
5:54:08list, an array. Okay. And in this array,
5:54:10we have views right over here. So we
5:54:12should very easily be able to determine
5:54:14the views mathematically just by doing a
5:54:17little calculation. I don't know. Is
5:54:19there like a calculate node? I don't
5:54:21think
5:54:22so. Do we need like a set node? Probably
5:54:25a set node, right? So, I'm going to add
5:54:27a few fields. I'll add views here. No,
5:54:28we can't actually do this. What we need
5:54:29to do first, sorry guys, is we need to
5:54:31aggregate this, I think, cuz this is
5:54:33currently many items. What we need to do
5:54:35is we need to put it into one item. So,
5:54:37I'm going to aggregate
5:54:40H. It'd be really nice if we could just
5:54:43get the average. Okay. I think we might
5:54:46need a code node just to make it.
5:54:48There's a million in one ways to do
5:54:49this. I think the code notes is probably
5:54:50the
5:54:52easiest because what we
5:54:54do is we're going to just aggregate all
5:54:57of this stuff. Now, so for con item of
5:55:00input.all, input.all just gets all of
5:55:02the items that are being fed into
5:55:06it. I think what I'll probably do here,
5:55:11first of all, I'm going to pin this pin
5:55:13this output right here. Okay. Second of
5:55:16all, I'm going to go const, let's just
5:55:20say array equals
5:55:22input.all. I'm going to return array.
5:55:25We're going to uh I don't actually think
5:55:27this is going to
5:55:28work. Okay. No, it it did
5:55:31work. Once we have an array, we're going
5:55:34to need to perform a mathematical
5:55:35function on that array. You know what?
5:55:38Why don't I just have AI do it as per
5:55:39usual? It's funny. Every time I'm like,
5:55:40I'm just going to code this myself. I'm
5:55:42like, well, I could do it myself. Or I
5:55:46could just have AI do it.
5:55:48So each entry includes a views
5:55:52parameter. I want
5:55:55to get the average each item in
5:55:59the input includes a views parameter. I
5:56:01want to get the average of each item's
5:56:05views and then filter so that I only
5:56:10output items who have view counts
5:56:15views over 2x the
5:56:19average. Okay, we're going to generate
5:56:22new code here. You could also ask
5:56:25anything else. You don't have to ask
5:56:26this model specifically. Just wanted to
5:56:28see if I could do this easily. So
5:56:30logically this is grabbing all of the
5:56:31input items. It's then mapping
5:56:33them. It's grabbing the item. It's
5:56:36getting the JSON. Then it's getting the
5:56:38average views. So it's doing what's
5:56:39called a reduce function to get the
5:56:42average. This is unnecessary to be
5:56:44honest, but it does it anyway. This is
5:56:46very proper filtered items. Cool. This
5:56:49is the multiple that I'm going to be
5:56:50using two. And it looks like it looks
5:56:52pretty good to me. I'm going to return
5:56:53this now. See what happens. No output
5:56:55data returned. Well, that doesn't make
5:56:57any sense logically, right? it has to
5:56:59return some sort of output data. The
5:57:01reason why is because logically
5:57:04speaking, if you have an average of two
5:57:06items, the average has to be higher than
5:57:07one item and then lower than the second
5:57:08item, right? It kind of makes sense. So,
5:57:11we should definitely have some sort of
5:57:12data here. It might just be because I
5:57:14need to reloop this. I'm just going to
5:57:16test this workflow out and just see if I
5:57:18dump it like this, what
5:57:21happens. No, it looks like we're feeding
5:57:23in the items and then it's not really
5:57:26calculating the code, which blows.
5:57:31your current code doesn't work. Come up
5:57:34with a
5:57:36simpler way to determine the average of
5:57:39all of the
5:57:42items and match it against that average.
5:57:44Let's try this. And then if that doesn't
5:57:46work, then I'm just going to ask Chat
5:57:50GBT. Consulting the guy that made all
5:57:52this stuff up. That's
5:57:54funny. Going to test this. I'm still not
5:57:56getting any output data. So I think
5:57:58logically there's just like
5:58:01some silly issue here. I'm going to run
5:58:05this through chatbt. What did I do for
5:58:17aski? Okay, it's giving me interesting
5:58:20idea.
5:58:25Um, I just got to copy the code
5:58:34here. Okay, so we're now going to add a
5:58:36little bit of debugging logic, it looks
5:58:42like. Now I'm going to open up my code
5:58:46editor, go to
5:58:48console, then I'm going to test this one
5:58:50more time.
5:58:54says, "The average uses 4,456." Oh, no.
5:58:57That actually looks okay. Oh, you know
5:58:58what it is? I think we're running this
5:59:00just
5:59:02once. Uh, let's see here. Feed in two
5:59:08items. Feeding in both of my items. Then
5:59:10we're calculating the average fees. Now,
5:59:11what are we calculating? We're
5:59:12calculating my average fees. So, 3,999
5:59:15for the first
5:59:18item. Then 4,913. So, the average to
5:59:22this
5:59:24logically 4,456. Cool. But no, it's not
5:59:27returning the it's not returning the
5:59:28items that have
5:59:29more. That's annoying. There must be
5:59:32some some other problem here. I don't
5:59:34like it.
5:59:50Okay, so it looks like we are feeding in
5:59:52two raw
5:59:56items. Looks like all view counts are
5:59:59here. Total views, average
6:00:01views. Okay, looks like it's adding up
6:00:03the views.
6:00:15H it still seems to be doing it weird. I
6:00:17really don't like using the code blocks.
6:00:19So I'm just going to cut that out. Use
6:00:21the filter
6:00:22here. What I want to do is say
6:00:26views is greater
6:00:31than. Okay. I ended up solving this with
6:00:34a simple filter node instead of a code
6:00:39block. And then I fed in this
6:00:42expression, which probably seems pretty
6:00:44intimidating to you, but let me walk you
6:00:45through it. So we grab the previous
6:00:47node, this Google Sheets node here. Then
6:00:50we get all of the items. In nad, you can
6:00:53get an individual item using the dollar
6:00:55sign JSON syntax or you can grab all of
6:00:57the items by referencing the name
6:00:59explicitly and then using a doall. Then
6:01:01I'm using a function called reduce. Now
6:01:03what reduce does is it's just a simple
6:01:05well it's a unfortunately complicated
6:01:06way of just calculating the average.
6:01:08It'd be really cool if there was just
6:01:09like an average function or something
6:01:10like that. Maybe there is maybe I'm just
6:01:12making this all way too
6:01:14complicated. H I don't think so
6:01:18though. Yeah. No, I think you have to do
6:01:21unfortunate code. But um what this is
6:01:23doing is this is reducing then it's
6:01:25grabbing the sum and the item and then
6:01:27it uses this arrow function to just like
6:01:28add it up. So this this basically just
6:01:30grabs the average and I'm dividing it by
6:01:32um the total number of items here. So so
6:01:35this sorry this gets the total number of
6:01:36views. This divides them up. For
6:01:38instance, if there's 10,000 total views
6:01:39and that's across two videos, the
6:01:41average is 5,000, which is actually
6:01:42pretty close to what it is. And then
6:01:44what we do is we just feed that into a
6:01:45filter block and we say, "Hey, is the
6:01:47number of views of this individual
6:01:48element greater than the average number
6:01:49of views of all?" Pretty
6:01:50straightforward, right? Pretty simple.
6:01:52If so, and we return this, which is
6:01:53cool. And then after I'm done returning
6:01:55this, if you think about it logically,
6:01:56what do we have to do? Well, we want to
6:01:57accumulate all of these and then we want
6:01:59to send them out in an email, right? So,
6:02:00I don't just want to add the email here.
6:02:02I actually just want to like run through
6:02:03my whole thing. I'm going to add my
6:02:04email over here instead. But just for my
6:02:07own sanity, what I want to do now is I
6:02:08just want to test this filter out on all
6:02:10of the data. So, I'll go test workflow.
6:02:12Grabbing the data from the Google sheet,
6:02:13doing the filtering steps. Cool, cool,
6:02:15cool. And it looks like on run one there
6:02:17was one item kept. That makes sense
6:02:18because out of two items, obviously, one
6:02:20and an average will be kept. And run
6:02:22two, one item was kept as well. These
6:02:24would be our outliers, for instance. And
6:02:26now we have those two items accessible
6:02:28to us in the done branch as we see here.
6:02:30And what we want to do now is we just
6:02:31want to make an email delivering these.
6:02:33Again, there's a million in one ways to
6:02:34do this sort of delivery. I'm just going
6:02:35to do a Gmail. So I'm going to do is
6:02:38I'll say send a
6:02:40message. And we don't need to loop the
6:02:42done. Just leave that over here. We do
6:02:45need to loop this
6:02:46though. Okay. So then I'm going to move
6:02:49this lower right here. This right over
6:02:52here. Simplest way I found of organizing
6:02:54this stuff. Maybe that's annoying that
6:02:56we can't do one
6:02:58[Music]
6:02:59more. Oh, na. Why must you do this to
6:03:02me? Then we're going to add our
6:03:04credential. So, this is the same idea as
6:03:06before. You just click create new
6:03:07credentials. Sign in with Google. So,
6:03:08I've already created a bunch of
6:03:09credentials here. So, I'm going to close
6:03:10this. Then, I'm just going to use my
6:03:12Gmail account number four. And
6:03:14hypothetically, I'm just going to um
6:03:15send this over to my personal email. And
6:03:19then I'll say daily
6:03:20digest trending YouTube videos. email
6:03:24type HTML over here. Um, you don't have
6:03:27to do HTML. I'm just going to copy all
6:03:30this and feed this in AI. So, let me see
6:03:33if I could just go from here all the way
6:03:35down to here. I'll say above is a bunch
6:03:39of data on trending YouTube videos.
6:03:42Format this into a simple HTML email I
6:03:45can send. It's part of a daily
6:03:48digest. Oh, sorry. All I care about are
6:03:54uh let's see here. We want the the
6:03:58title, the
6:04:00channel, the
6:04:03thumbnail, the video
6:04:09duration, the video duration, and the
6:04:12multiple. Right. Right. We should
6:04:14totally do the multiple. Uh okay. Well,
6:04:18let's just keep this for now and then
6:04:20I'll add the multiple afterwards.
6:04:21Multiple is really cool to have. Now,
6:04:22it's going to format this as an email.
6:04:25Hopefully, I'm just getting network
6:04:27connection loss. I'm not entirely sure.
6:04:29It might just be my hotel
6:04:31internet. Okay. Okay. Okay. Here we go.
6:04:34Here we
6:04:35go. I don't know what this is. What is
6:04:37this supposed to
6:04:39be?
6:04:44H. This is hardcoded,
6:04:48right? I don't like why this is how this
6:04:51is laid
6:04:52out. Okay. Daily AI video digest. Cool.
6:04:56All right. So, missing title. We'll put
6:04:57the title here. Channel title. Duration
6:04:59over here. Okay. Okay. Cool. We'll do
6:05:01the thumbnail here. Okay. Uh, hold on.
6:05:05This is just
6:05:06one. I should
6:05:12say meant to
6:05:15say include the variables
6:05:19as let's do
6:05:21that. That way I can just very quickly
6:05:24find and replace all the variables in a
6:05:27moment. Cool. Going to copy this now.
6:05:30Paste this
6:05:31in. Oh no. I don't want the each man.
6:05:35Ridiculous.
6:05:37Ridiculous. Yeah. Yeah, we don't want
6:05:39each. That
6:05:42sucks. I don't Can we actually do that?
6:05:44Maybe we
6:05:46can. Fascinating. That would be pretty
6:05:48cool if we could. I don't know if we can
6:05:50or else we don't know. We could uh I
6:05:53could do the logic here, but actually,
6:05:54let's just send one to
6:05:56start and then I'll worry about
6:05:58everything else later. Okay, we'll just
6:06:00send one to start. We'll go
6:06:02expression. Let's do this. Uh image
6:06:06source, we'll just
6:06:08do large thumb
6:06:11here. Title of the video will be I just
6:06:15want to um get something on on the page.
6:06:18Basically, I just want to have an email
6:06:19sent so that I can very quickly and
6:06:20easily identify whether or not it's like
6:06:23a trash template. I don't actually care
6:06:25about all of this data too much.
6:06:28Duration, this kind of sucks, but
6:06:30seconds, I guess. And I'm just going to
6:06:33remove this each thing. So we should
6:06:35just pump out one of these now. Okay.
6:06:37And then I only want this to run. This
6:06:40is running twice now. Why is this
6:06:41running twice? H. We need to aggregate
6:06:43these is what we need to do. That's my
6:06:46problem
6:06:47here. I'm just going to aggregate all
6:06:50item data into a single
6:06:52list. Uh it's unfortunate because we
6:06:55have to actually run should have to run
6:06:57everything here. So let's just do this
6:06:59um test workflow aggregate. That should
6:07:02now be my output.
6:07:04Cool. Very cool. Very cool. And then
6:07:08now probably going to have to remap
6:07:10this. Yes, I will. It kind of sucks. Oh
6:07:12well, that's what it
6:07:14does. Let's just do the first. Okay. So,
6:07:17we'll go source and then I'll go large
6:07:22thumb. Then here under
6:07:26title data zero.title.
6:07:33title, channel title. Cool. And
6:07:36duration. Awesome. Now, if I test this,
6:07:39should send an email. So, I can go to my
6:07:42email and just see how bad the
6:07:43formatting is. Usually, the formatting
6:07:44is like not the
6:07:47best. Okay, looks pretty good. Couple
6:07:50things that I don't like here. I don't
6:07:51like the size of this. Can I make this
6:07:52smaller? Probably. We can probably make
6:07:54this smaller just by changing the Yeah,
6:07:56we're using the large thumb here. I'm
6:07:58going to try using the small thumb for
6:08:00one. What else don't I like? I don't
6:08:02like the fact that it says this email
6:08:03was sent automatically with NAN. So in
6:08:05NAN, you can change that. Just go to
6:08:06append NAN attribution. Turn that off.
6:08:09Looks pretty okay,
6:08:10honestly. Fix 90% of your AI agency
6:08:13problems in 30 days. Okay, let's try it
6:08:15again. We go
6:08:18here. H Oh, nope. That's pretty blurry.
6:08:22That's pretty blurry. I don't like that.
6:08:25Yep, that is a little small. Can we
6:08:27change the image image source class
6:08:30thumb? Oh, you know what? That's the
6:08:32problem here. That's the problem. Let's
6:08:33just change 240 pixels and then we'll
6:08:36still use the large thumb, but we're
6:08:37only going to be at 240 pixels. Okay.
6:08:39And then what else do we really want? I
6:08:41guess we just want all of them. So
6:08:42logically, how do we do that? What we
6:08:44have to do is basically for every item
6:08:46inside of aggregate, we just have to
6:08:48generate this. Why don't I just paste
6:08:50this in again and see if two emails look
6:08:54okay. This looks fine now because it's
6:08:56in 240 pixels, right? Yeah, it's not the
6:08:58best just to have them all laid out like
6:08:59this. Kind of wish we can go like uh
6:09:02like
6:09:04lengthwise. If I feed this in
6:09:07here and then I
6:09:11say just feed this into AI, let's do
6:09:15GBD4.5. And I'll
6:09:18say this is an HTML template that's
6:09:21supposed to
6:09:23return a nice looking
6:09:27minimalistic list of higherforming
6:09:30YouTube videos. I put two as an example,
6:09:35but it should scale to infinitely many.
6:09:38Right now, this looks poor. This looks
6:09:40bad because they're stacked on top of
6:09:43each other there. And I don't like the
6:09:46formatting
6:09:47etc. fix this so it looks nice and clean
6:09:51and
6:09:52the videos are side by side in some sort
6:09:57of clean uh uh
6:09:59minimalistic but sleek grid pattern.
6:10:05Okay, there you go. We're going to see
6:10:08how that performs. We'll keep the two
6:10:10and then after I'll deal with the logic
6:10:12on generating multiple little video grid
6:10:15things. The thing is like emails just
6:10:18inherently lack like the ability to do
6:10:20some cool formatting which sucks. So, oh
6:10:22sorry I didn't mention this. Sorry,
6:10:24sorry,
6:10:25sorry, sorry. This is an HTML email so
6:10:29it needs to be formatted in light of
6:10:32that. Right. Emails are formatted a
6:10:34little bit differently than um websites.
6:10:37So, it needs to be um tables instead.
6:10:40And it doesn't look like it's a table.
6:10:42Okay, cool. Anyway, it's going through
6:10:44and it's now creating me this little
6:10:45digest, which is nice. Okay, let's
6:10:48expand this little code block now. Hide
6:10:50this
6:10:51sidebar. And then what I want to do Oh,
6:10:54we can actually preview the output. No
6:10:55way. Got a little um HTML thing in
6:10:58here. Doesn't look very good, not going
6:11:00to lie. Oh, don't tell me it's using
6:11:02each. Please don't use each. Damn it.
6:11:04It's totally using each, isn't it?
6:11:07We just said no each. Yeah, it's doing
6:11:11each. That
6:11:14sucks. We just need to go TR
6:11:19now. I
6:11:26think is this. Okay, cool. That looks
6:11:28much better. Um, so now we have
6:11:31basically this nice infinite layout. So
6:11:34if I added more, we'd be able to do
6:11:35more. Now I just have to generate the
6:11:49code. 1.7. My
6:11:52bad. Where does it do the 1.9? Does it
6:11:55have a 1.9?
6:12:04That'd be much
6:12:29Yeah. 140. Uh, what's the width here?
6:12:44It's kind of like 170
6:12:46probably maybe
6:12:53180 need 20 on both sides
6:12:58right try
6:13:03And then I'm also going to change this a
6:13:06little bit.
6:13:08So we'll say
6:13:45Cool. Looks
6:13:48fine. Nice. All right. Cool. Cool, man.
6:13:52Nice. I'm liking this.
6:13:56Uh, this
6:13:58array. Um, why is the array the same
6:14:00though? Oh, that's a problem, man.
6:14:02Why is the array the same This
6:14:04array should not be the same
6:14:07We should have different items
6:14:23here. I mean, it looks it feels a lot
6:14:26better for sure. Let's test this now.
6:14:38This like still a really weird cut off
6:14:40here,
6:14:41man. That's not right. Thumb container
6:14:43object fit
6:14:47cover. Dimensions. What are dimensions?
6:14:49I don't understand. What are my
6:14:53dimensions? Height and
6:14:56width. Width. It is 100%.
6:15:14Um, so where is this being applied? Can
6:15:17I do like 160? Oh, 170
6:15:21180
6:15:25160. I feel like it's 155. Okay. You
6:15:28know, it's probably 155.
6:15:31probably 155. So where is
6:15:35this go back here and then instead
6:15:38of
6:15:43155 send this now that way it's not
6:15:46going to be super skinny
6:15:49again. Nice. Oh yeah, that's perfect.
6:15:51Got the whole thumb, baby. That's what
6:15:52I'm talking about. Okay, we can just set
6:15:54Nixar and duration whatever on the same
6:15:56line, can't we?
6:16:00Mhm. Okay. So, let's just uh get a list
6:16:03of things we want to do
6:16:04now. Is there padding over here? I don't
6:16:07know why there's padding over here. Just
6:16:09remove the
6:16:14padding. Okay. So, we've now verified
6:16:16that this works on two. I was just
6:16:18feeding in examples of the exact same
6:16:20code snippet, um aka like the the same
6:16:22thumbnail and stuff, but now I want to
6:16:23make it so that it works with different
6:16:25thumbnails. So, I'm just going to jump
6:16:26in and actually make a little do a
6:16:27little snippet of code to handle this
6:16:29for me. First, I'm just going to trust
6:16:31that this runs on data. At least that's
6:16:33what I'm doing right now that I'm
6:16:35pinning, but I actually want to like
6:16:36have it run on live data. So, I'm
6:16:37actually just going to test this
6:16:38workflow and see what's going
6:16:43on. Okay, looks like we've now sent one
6:16:46email and I believe it's going to be the
6:16:48same thing twice, right? Okay. No, no,
6:16:51no. We're actually getting um we're
6:16:52getting data directly from So, that's
6:16:54actually fine. Uh, looks like the sizing
6:16:56is a little bit off. I don't really know
6:16:57entirely what's going on with that to be
6:16:58honest, but uh, yeah, these are actually
6:17:00the Yeah, these are actually the trends.
6:17:02So, to be honest, like it kind of kind
6:17:04of already works. Um, one big thing that
6:17:05I want that we don't currently have is
6:17:07we just I just want the multiple. So,
6:17:10that's one thing that I have to do. So,
6:17:12how am I going to do the multiple?
6:17:15H, well, I guess I could just put the
6:17:17multiple right next to the title, right?
6:17:19So, I think that's what I'm going to do.
6:17:20I'm going to go into the HTML template
6:17:22here.
6:17:24And then where I have the title, which
6:17:27is right over
6:17:29here, I'll add a span for the
6:17:33title. Then I'll also add a span for the
6:17:36multiple. And for the span, I'm just
6:17:39going to go style equals font weight.
6:17:42And then I'm just going to go bold. Then
6:17:45over here, I should have be able to come
6:17:47up with like a little multiple. Now,
6:17:50what is the multiple? Uh well the
6:17:52multiple is going to depend on this.
6:17:55So guess I can just copy all of this.
6:17:57This is not at all clean. I'm going to
6:17:59be doing calculating like directly
6:18:00inside of the template which most people
6:18:02do not recommend. Okay. But
6:18:05still f it we
6:18:07ball. Try not to swear as much. Let's
6:18:10think about this. What are we doing?
6:18:12What are we
6:18:15doing? I know what I'm going to do if
6:18:17you think about it logically.
6:18:22What we need is we need this filter to
6:18:26open an additional
6:18:32field. We need to drag all of
6:18:37these in. Can it just automatically
6:18:42map? No, I can't.
6:18:50Okay. So, yes, I can. That makes sense.
6:18:52What we want is we want that average,
6:18:53right? So, I'm going to go to filter and
6:18:55I'm going to calculate the average. Then
6:18:58here, I'm also going to say
6:19:01average, feed that in as an expression.
6:19:04So, now we're going to get the average
6:19:05and we're going to get this. So, what
6:19:06this means is when we actually feed back
6:19:08to the loop over items, it's going to
6:19:09have everything that we need. I'm just
6:19:11going to undo this and test it for
6:19:14myself. It's going to include the
6:19:15average, which we can then use to find
6:19:17out the
6:19:17multiplier. We get everything we need
6:19:20plus the average. Plus the average.
6:19:22Wonderful. Now we connect this to the
6:19:23aggregator node. Now I can use this
6:19:26average to Well, sorry. I guess I need
6:19:28to run this.
6:19:30Um, kind of annoying, but it's what it
6:19:33is. We actually have to run all this
6:19:34with the aggregator. My bad. So, we're
6:19:36going to hit the APIs a bunch more
6:19:37times. Let's see if we get a rate limit
6:19:39issue. Nope.
6:19:42I'm just too crazy with it. We get the
6:19:45average. Wonderful. We're going to pin
6:19:46this. Now, we're going to connect this.
6:19:48And now that we have this, we can
6:19:49actually go through the HTML template
6:19:51somewhere over here. Establish that
6:19:54average. So, let's do the
6:19:56math. What I'm going to want is
6:20:14this going to
6:20:19work? Does that work? I don't
6:20:23know. I don't know what I've been
6:20:29told. Yeah, I don't think we have the
6:20:31ability to do each. This doesn't really
6:20:33solve my
6:20:36problem.
6:20:38Oh. Oh, it does. It does. It does.
6:20:41does. Okay. Okay. Okay. Wait. Uh I'm
6:20:43aggregating here. I aggregate up there,
6:20:45right?
6:20:56Wait. What happens if I feed multiple
6:20:58items into this HTML node here? What
6:21:03happens?
6:21:11I don't know. Let's give it a try, man.
6:21:14Why the hell not?
6:21:16Um, We're not getting the data
6:21:18anymore. Are we getting the data
6:21:20anymore? Jason data one title,
6:21:24right? Oh, yeah. Yeah, we can just do
6:21:28this,
6:21:30right? Delete that. Delete
6:21:33that. Cool. Let's delete the
6:21:36[Music]
6:21:38TDS.
6:21:40No, we just get rid of that,
6:21:43too. Okay. So, where's this video
6:21:50table? I doing a table per video or
6:21:56what? I think we just deleted this
6:21:58Let me delete all that
6:22:01Delete that for sure.
6:22:06It says
6:22:09TR. We can probably just output them
6:22:12bunch of these,
6:22:16right? Let's kind of do that
6:22:20again.
6:22:29Um, why is it doing the same thing?
6:22:32because I'm returning the same
6:22:35thing. Well, I mean, this is this is
6:22:37what I wanted. So, now I just
6:22:38concatenate them,
6:22:40right?
6:22:48Yeah. So, I just go
6:22:50here to the video table. Cut out of
6:22:55this. Now, what I do is I do this
6:23:03No, I do Yes.
6:23:56Right. That's what I'm talking about,
6:23:58baby. We mapped the hell out of that
6:24:00man. Then
6:24:03um
6:24:06split.
6:24:09Wait. Then join. Then split with
6:24:13nothing. Oh, That's all I do.
6:24:24That looks That looks good to me, right?
6:24:27I don't know why we're getting two of
6:24:28the same outputs, but like it should be
6:24:37okay. Oh, We sent it twice.
6:24:46Um, maybe we just run it once. Probably
6:24:50enough. Execute
6:24:51once. Yeah. Sorry about
6:24:54that. Oh Where the hell's the
6:24:56thumbnail now,
6:25:02man? Why are we getting the thumbnail?
6:25:18Yeah, there's the there's the data right
6:25:19there.
6:25:40Yeah, it's not
6:25:43rendering. That
6:25:46sucks. Why is it not rendering?
6:26:21Nope, that doesn't
6:26:23work. Why the doesn't that
6:26:27work? Isn't that the whole idea, man?
6:26:29that you can insert freaking variables
6:26:32like
6:27:05Holy this is
6:27:07brutal. I really want to do the HTML
6:27:10template thing if I could just do code
6:27:11to do it. See, we may have to just like
6:27:13fix all this man. I got all the
6:27:15stuff
6:27:37out. We need to delete
6:27:40this, right?
6:28:11Well, it's now inputting the URL, which
6:28:13is cool with uh the X at the end of it.
6:28:16So, could I
6:28:21concatenate? Nice. That's
6:28:27cool. Source is this. Then I want to
6:28:31concat
6:28:33One more. Is that going to work now? Oh,
6:28:36for sakes. Come on. Chop. Chop.
6:28:39Nice. That actually did work.
6:28:41Cool. Very cool. Very cool. Uh, all
6:28:44right. So, what what are we doing over
6:28:47here? Video table thumb container thumb.
6:28:49So, let's use a class of
6:28:52thumb. We'll go
6:28:56source class equals
6:28:59this thumb.
6:29:02Okay. Oh
6:29:05yeah. Okay. And then now that we're all
6:29:10done with that, what are we doing
6:29:18here?
6:29:20Okay, we now send one item. Hello
6:29:25email. my
6:29:28life. What the hell's going on?
6:29:33I think I know what it
6:29:35is. Had like a good thing going here for
6:29:38a
6:29:39bit like 15 minutes
6:29:45ago. Give me that email template,
6:29:49man. What were we feeding in
6:29:52here? Image source large thumb thumb
6:29:56container on the outside. Are we still
6:29:58doing that?
6:30:02image
6:30:07source im uh thumb container on the
6:30:10outside.
6:30:14Right? It's image source equals
6:30:18thumb
6:30:20concat class
6:30:23thumb. That's good. I don't see any
6:30:26issues with that. So, why is the email
6:30:28coming out all
6:30:30A quick tip checker online.
6:30:34Please go over here to Yes.
6:31:07[Music]
6:31:11Mhm. Oh, that's
6:31:17useful. Come on,
6:31:20man. That's just not That's just not
6:31:23nice at all. Why would you break on me?
6:31:25Um
6:31:29h container
6:31:32right video table
6:31:36right remember earlier when this is
6:31:38working fine not that one
6:31:44okay table tab body
6:31:48tr thumb
6:31:52container so it's trd
6:31:55dev TR TD
6:31:59dev, right? Looks good to
6:32:03me. But for whatever reason, when we're
6:32:07turning these on, they break. And also,
6:32:09we're running the same data over and
6:32:11over and over again. Why is
6:32:13that? We should have new data, right?
6:32:20Like not seeing any output data on this
6:32:23branch.
6:32:27So why is this going two get four filter
6:32:32in
6:32:33two and for the first round it's 90% 90%
6:32:38so I don't fully understand what's going
6:32:40wrong
6:32:41here something is
6:32:47though we pumped out two channels good
6:32:51for both channels what we do is we loop
6:32:53through the Google
6:33:00sheet. Looks good. Then I'll put a
6:33:03filter. Filter keeps one, discards one.
6:33:08So now we have two items left. The two
6:33:11items on the left side. That looks
6:33:13good. Two items on the right side. That
6:33:16also looks
6:33:18good. Loop one.
6:33:28Yes, we are actually getting them now.
6:33:30Wonder. We're now just going to create a
6:33:32new chat GBT template entirely. One that
6:33:34is much much better looking than this.
6:33:36Let's go
6:33:38chat. Go over here. Change this to
6:33:4804. First string is my HTML template.
6:33:52I am creating a simple daily digest app
6:33:55that includes trending videos
6:34:03from
6:34:08HTML. Above our HTML templates that are
6:34:11sent via email wrapper HTML in the
6:34:15second
6:34:47Still looks like Come on, man.
6:34:50What is going on with these black
6:34:53bars? Okay, just crop the images
6:34:57in point on both sides. Height should
6:35:02be what is the height right now?
6:35:11Grab the height of
6:35:14this. Grab the height. Where's the
6:35:38height? Care for the
6:35:42demo? Probably. Sorry.
6:35:55You would have thought that San
6:35:56Francisco would have better open
6:35:59AI access,
6:36:01huh? Apparently not.
6:36:17Oh my goodness. It's It's good, but
6:36:19that's too that's too much. Okay, so
6:36:21here's what we're going to do. I'm going
6:36:24to find the specific snippet of code
6:36:26where it actually cuts into my freaking
6:36:28things. Okay, so height 155 pix. So
6:36:32that's way too
6:36:34small. We're going to do we're going to
6:36:37say double. We're going to double it
6:36:41310. Boom. Is there anything else that's
6:36:44155 here?
6:36:48No, this is good. Supposed to be good,
6:36:50but yeah, it's too much. Okay, multiple
6:36:53undefined. So, we also need the
6:36:54multiple. Where's the multiple average?
6:36:58So where we get the
6:37:01multiple we're going to do is concat
6:37:09uh JSON dot
6:37:12um JSON
6:37:14dot views divided by JSON average. Okay.
6:37:19All right. This going to be it.
6:37:39Oh yeah, sorry. We need to round it. Uh,
6:37:41how do we round this?
6:38:01probably. Okay, I'm going to run this
6:38:03one more time just in one second and
6:38:05then we should be
6:38:11good. Then instead of two or three, why
6:38:14don't I
6:38:16add Well, we should probably do like
6:38:19five or something, right? Should
6:38:21probably run this once before
6:38:23I start saying stuff. Have it screw up
6:38:27on me during the
6:38:31demo. Let me just make sure that Can I
6:38:34still see my mic and stuff?
6:38:35Yep. No issues there. Looks good. Looks
6:38:39good. We'll run it now
6:38:46once. Clean as hell.
6:38:50Nice. That's perfect. Multiple one. Oh
6:38:55god. One
6:38:58more. Y'all ever done
6:39:03this? Okay. Anything
6:39:12around decimal places. Okay. We just
6:39:14need two. You now built a trend
6:39:16detection system that automatically
6:39:17identifies viral content opportunities.
6:39:19And that's pretty cool to me. Next,
LinkedIn Customized Outreach System
6:39:21we're going to build a sophisticated
6:39:22LinkedIn AI outreach system that creates
6:39:24targeted Apollo searches using natural
6:39:25language. We're also going to enrich
6:39:27prospects with detailed profile data.
6:39:29We're going to generate personalized
6:39:30icebreers. And we're also safely going
6:39:31to send connection requests through
6:39:32automation. Lots of agencies, including
6:39:34LinkedIn lead genen agencies, AI
6:39:36automation agencies, content agencies,
6:39:38they depend on LinkedIn. And being able
6:39:40to automate that process saves hundreds,
6:39:42if not thousands of dollars per month.
6:39:43So, the system's going to handle the
6:39:44entire LinkedIn lead generation flow
6:39:46from prospecting all the way to
6:39:47outreach. You can charge $2 to $5,000
6:39:50for the system depending on volume and
6:39:51the number of accounts you have because
6:39:52it technically automates what used to
6:39:54require a full-time
6:39:56position. Okay, so here's a demo of the
6:39:59system from start to finish. We start
6:40:00with a form that I fill out which I'll
6:40:02show you in a second. That form
6:40:04basically asks for us to define the
6:40:06search parameters in natural language.
6:40:08So I am going to get to say I'm looking
6:40:09for creative agencies between one and a
6:40:11thousand people that are in the United
6:40:13States. And it will actually create an
6:40:14Apollo search URL for me completely
6:40:16autonomously. We're then going to
6:40:17generate a search URL here. Then run an
6:40:20ampify actor. Um I'm setting a limit
6:40:23node here. For those of you that don't
6:40:24know, limit node is just sort of a
6:40:25testing node. Allows me to set lower
6:40:27limits so I don't overwhelm an API.
6:40:29We're then doing a personalization step
6:40:30right over here. Um then I'm adding this
6:40:32to a Google Sheet database. You can find
6:40:34this Google Sheet database um right over
6:40:38here. This Google sheet database is very
6:40:40simple. We're just logging the ID of the
6:40:42LinkedIn account, the first name, the
6:40:43last name, the full name. Sometimes I
6:40:45like to have that the LinkedIn URL, the
6:40:47title, the email status, the photo URL,
6:40:49and then the icebreaker. And then
6:40:51finally, we are aggregating all of that
6:40:52data so that I could send an API call to
6:40:54a tool called Phantom Buster. And I'm
6:40:56going to cover all this stuff in a
6:40:57second, but for now, let me just show
6:40:58you guys what this looks like in
6:41:00practice and what the end result is. I'm
6:41:01going to test workflow. It's going to
6:41:04ask me to define my audience type in
6:41:05plain English. So, I'm going to say um
6:41:08I'm looking for creative
6:41:10agencies around one to um let's say
6:41:15100 people staff across the United
6:41:20States. I want the decision makers. So,
6:41:25come up with a
6:41:27bunch. Then I'm going to click submit.
6:41:29Now that I've done this, what's
6:41:31happening is it's going through and it's
6:41:32generating a search URL. Now, the way
6:41:35that this works is the service that I'm
6:41:36using basically takes as input a giant
6:41:39search string. And so, I'm having AI
6:41:41generate the search string. The search
6:41:42string is ultimately what is going to um
6:41:44allow us to do said
6:41:46search that looks just like this. I'm
6:41:48going to copy this over. If I paste this
6:41:50in, um what this will do is it'll
6:41:52actually go through and then get
6:41:53decision makers that are within my
6:41:55custom audience, in my case, 967 people
6:41:57across the United States. If we proceed
6:42:00with this, it will then um run uh what's
6:42:03called an appy actor. It's a service
6:42:05that we're going to be using to scrape
6:42:06this group of people. That appy actor I
6:42:09can find back over
6:42:12here. What this is doing is it's going
6:42:14and it's identifying who these people
6:42:16are. It's extracting their email
6:42:18addresses completely autonomously and
6:42:19then it's also getting me a bunch of
6:42:21additional data on them. Okay. After
6:42:24we're done with that, we then pass
6:42:25through a limit node. We have an AI
6:42:27model here, GPT4, that actually goes and
6:42:29creates customized ice breakers for the
6:42:31connection requests. And then what we do
6:42:33is we'll actually dump that into a
6:42:34Google sheet before aggregating that and
6:42:36then triggering a Phantom Buster agent.
6:42:38Phantom Buster is the tool that we're
6:42:39going to be using to grab the data from
6:42:41this Google sheet right over here and
6:42:43then actually physically produce our
6:42:46LinkedIn connection request over here.
6:42:48Okay. And what that looks like on um
6:42:51their end is we are now running this
6:42:53Phantom Buster auto icebreaker connect
6:42:56and it's actually going through and it's
6:42:58simulating real human activity in order
6:42:59to send the message essentially and the
6:43:02connection request. Finally, as this
6:43:04proceeds down the list, we will have the
6:43:06actual data right over here alongside
6:43:08the specific status whether or not this
6:43:10has been sent. Um, and so we have
6:43:12actually gone through and we've sent a
6:43:13bunch of connection requests at various
6:43:15times of the day to these various people
6:43:17using the system. And it was all done
6:43:19100%
6:43:22automatically. So I want to make
6:43:24something super clear. As of this
6:43:26moment, I've not actually built the
6:43:27system yet. I wanted to show you guys
6:43:29what a live real build process looks
6:43:31like from start to finish by somebody
6:43:32that actually does this for uh for for a
6:43:35living on a daily basis. I think right
6:43:37now on YouTube it's really fancy and
6:43:38popular to like put a finished product
6:43:40in front of people and be like here's a
6:43:42system here's how to put it together but
6:43:44that people don't actually show what
6:43:45like the live development process looks
6:43:46like. In reality the live development
6:43:48process is filled with a lot of detours,
6:43:49a lot of ups and downs, a lot of um
6:43:51guesses that you know don't actually end
6:43:53up panning out. And you know I want to
6:43:55show people how to actually build
6:43:57systems that make people money. I don't
6:43:58just want to show people like a finished
6:44:00kind of sanitized version of it. Um, so
6:44:02that's why you guys are going to see me
6:44:03do it all from scratch and that's why,
6:44:05you know, I'm I'm structuring this video
6:44:06in this way. It's very important to me
6:44:08not just to like show somebody a picture
6:44:10of the Eiffel Tower and then be like,
6:44:12"Hey, now that you've seen the picture,
6:44:13you know how to build it, right?" It's
6:44:14like, "No, I actually want to I want to
6:44:16show people the building process. I want
6:44:17to show people the schematics and the
6:44:18diagrams, if that makes sense." Cuz uh,
6:44:20for the most part, that's my audience.
6:44:21So, yeah, uh, this is the road map at
6:44:24this point in time. Basically, what I'm
6:44:26thinking I'm going to do is I'm going to
6:44:27start by scraping Apollo leads using
6:44:28Apify. Then I'm going to enrich leads
6:44:30with personalizations and I'm going to
6:44:32send a Phantom Buster for LinkedIn DMs.
6:44:34Now, if you don't know what any of these
6:44:35platforms mean, I'll explain them to you
6:44:36right now. Apollo is basically a big
6:44:38database that allows us to get a bunch
6:44:41of information based off search filters
6:44:42like dentists in the United States with
6:44:451 to 50 staff members. Okay, the issue
6:44:48with Apollo is it's a very expensive
6:44:51database. And so instead of me just
6:44:53getting leads directly from Apollo, what
6:44:55I'm going to do is I'm going to use this
6:44:56tool called Ampify, which is kind of a
6:44:58scraper, which allows us to plug in an
6:45:00Apollo URL, and then it goes in, it
6:45:02actually like scrapes the HTML of the
6:45:04page to find us the leads. Okay, so it's
6:45:06kind of a hack, but this is basically
6:45:07what everybody's doing right now to
6:45:08scrape um scrape Apollo. And the reason
6:45:10why, you know, everybody's saying that
6:45:11that's okay is because Apollo is just
6:45:13scraping LinkedIn Sales Navigator. So
6:45:15it's kind of like, you know, scraping
6:45:16the thing that scrapes the place that
6:45:18scrapes, you know. Um anyway, so this is
6:45:20our scraper. I'll show I'll show you all
6:45:22these platforms in a second. Then OpenAI
6:45:23is obviously like our AI tool. And the
6:45:25reason why we're using an AI tool here
6:45:26is because um we need to personalize the
6:45:29messages that we're going to be sending
6:45:30to people. You know, after we find the
6:45:32people, we're also going to get a bunch
6:45:33of information about them. We're going
6:45:35to figure out where they live. We're
6:45:36going to figure out their interests.
6:45:37We're going to figure out their job
6:45:38titles and stuff. Well, if you actually
6:45:40just feed all that stuff into um AI, you
6:45:42can have AI write something that seems
6:45:43pretty customized. Like it's not like,
6:45:45"Hello, dear person. I would like to
6:45:47sell you stuff." It's like, "Hey, Peter,
6:45:49you know, saw that you went to, I don't
6:45:51know, like the U of A. Um, that's super
6:45:53cool. I love that you did X, Y, and Z,
6:45:54and this may be totally out of left
6:45:56field, but I thought we should connect."
6:45:57It's something like that, right? It's
6:45:58obviously I'm going to write it way
6:45:59better. Um, but just to give you guys
6:46:01like give you guys some insight into
6:46:02that process, that's basically what
6:46:03everybody is doing right now in any sort
6:46:05of cold air outreach. Anyway, after we
6:46:07have the personalization and all the
6:46:09lead data and the LinkedIn profile URL,
6:46:11and basically after we've done these
6:46:12first three steps, okay, what we need to
6:46:13do is we need to send the outreach. And
6:46:15so I'm going to be using a tool called
6:46:16Phantom Buster to do
6:46:18that. And finally, we need to do it, you
6:46:21know, on LinkedIn. So I threw in
6:46:22LinkedIn over here. Um, but let me make
6:46:24this clear. Uh, this is a very short
6:46:25moment of time in which you can use all
6:46:27of these tools together in the way that
6:46:28I'm about to show you. So, you know,
6:46:30because we have access and availability
6:46:32to these tools, we can do the really
6:46:33cool thing that I'm that I'm about to
6:46:35do. Um, if these tools didn't exist, you
6:46:37could still do it. It' just be like way
6:46:38harder and it'd be a lot more difficult.
6:46:40So, I prefer to use pre-made tools
6:46:41wherever possible just to expedite my
6:46:43workflow. That's sort of like my guiding
6:46:45principle here as somebody that does AI
6:46:46and automation. Okay. All right. So,
6:46:49Apollo kind of looks like this. As you
6:46:51can see, it's literally just a database
6:46:53on the lefth hand side of people. Okay.
6:46:56So, hypothetically, let's say I want
6:46:59creative agencies. I'm just going to
6:47:00type in creative agency as a keyword.
6:47:02This is not the most effective way to do
6:47:03this, by the way, but I just wanted to
6:47:04show you guys what it looks like. And
6:47:06then, um, under job titles, maybe I'll
6:47:07go owner, CEO, I'll go
6:47:10founder. I'll go partner. So, and I'm
6:47:13just typing in like titles of the people
6:47:14that I'm looking for, right? Um, okay.
6:47:17Anyway, I'm just going to leave it at
6:47:18that. And what do I end up with? I end
6:47:19up with 844 creative agencies um in I
6:47:23think I put United States here
6:47:25somewhere. Maybe I didn't. Oh, yeah.
6:47:27Location, United States. Cool. So,
6:47:29that's all Apollo released for. I mean,
6:47:31I could go into more detail about it.
6:47:32I'm not going to just for the purposes
6:47:33of this, but essentially, we can we can
6:47:35generate a list of people. Okay. And so
6:47:38once I have this list of people, the
6:47:39question becomes, all right, like how do
6:47:40I actually extract something meaningful
6:47:42from this? How do I actually like get, I
6:47:43don't know, an email address? How do I
6:47:44get like a LinkedIn profile URL? How do
6:47:46I actually, you know, get their phone
6:47:47number or whatever? So normally, you
6:47:49know, I would export this in Apollo, but
6:47:51it costs a ton of money. And so instead,
6:47:52what we're doing is we're going on a
6:47:53tool called Appify, which is basically a
6:47:55big library of scrapers that people have
6:47:57put together. And we're going to find a
6:47:59tool that allows us to scrape all these.
6:48:01So I'm just going to run a proof of
6:48:02concept first before I even build
6:48:04automated systems. And I'm just going to
6:48:05run through this whole thing manually.
6:48:06Um, so let's do it. Let's do
6:48:09Apollo. Pump that in there. And I'm just
6:48:12going to use this one here. I think I've
6:48:13used this one many times before. So I
6:48:16just want to verify that I have access
6:48:17to it. Yes, I do. Okay. All right. So
6:48:20I'm just going to paste this search URL
6:48:21in here. This is just how the tool
6:48:22works. It costs a$120 per thousand
6:48:24leads. So if we want to scrape a,000
6:48:26leads, cost you $120. I should note that
6:48:28you can only do a few um like a 100 or
6:48:30150 LinkedIn connection requests totally
6:48:33cold per week per account. So, like you
6:48:35can think of this as basically $1.20
6:48:37will give you enough money to run this
6:48:39LinkedIn campaign for a whole month. Um,
6:48:41at least in terms of leads. You
6:48:42obviously still need to pay for the rest
6:48:43of software platforms. But anyway, uh,
6:48:45here we pump in some search records. So,
6:48:47500 search records, get work emails, get
6:48:49personal emails, find, whatever. I'm
6:48:50going to click save and start and let's
6:48:51just see what happens. Okay, we're
6:48:52running this manually. We're not doing
6:48:53any sort of API yet. Uh, I will I will
6:48:56put the system together in N8 after, but
6:48:59okay, cool. So, as we see, it's saying
6:49:00it's found 100 results. That's cool.
6:49:03Now it's getting some more. If I go to
6:49:05this output tab, you can see the actual
6:49:07results. Pretty neat, huh? We're getting
6:49:09all these people's data. And oh man, are
6:49:12there a ton of fields, right? There are
6:49:14a lot of fields. I'm not going to go
6:49:15into detail on all the fields, but I'll
6:49:16just show you that, you know, you can
6:49:17just you can just run these searches um
6:49:20basically free. Uh which is pretty cool.
6:49:23And yeah, we just live in a we live in a
6:49:24pretty specific point in time where you
6:49:26can actually do that. Okay. Anyway, I'm
6:49:27just going to manually export this. I'm
6:49:30going to do it as a CSV. Why? because I
6:49:31would just want to visualize this in
6:49:32Google Sheets. And now I'm thinking,
6:49:34okay, like once I visualize it, I can
6:49:36actually go through and I can use AI to
6:49:37do some stuff. So this is my thought
6:49:40process. Just trying to narrate it live
6:49:41so we see what's going on. I built out
6:49:43many similar systems like this. So
6:49:45obviously because I built similar
6:49:46systems like this, I kind of I kind of
6:49:48have a feel for like where things are
6:49:49going. But uh I'm just going to import
6:49:51now and then I'm going to go to upload
6:49:53and then drag and drop this file that I
6:49:55just exported. And I the reason why is I
6:49:57just want to visualize it. And I'm going
6:49:58to go append to current sheet. That's
6:49:59just going to allow me to, you know, I
6:50:00just change the title. I don't want to
6:50:02have to redo it all. Okay, cool. So, I'm
6:50:04going to hide these so I don't expose
6:50:06every single person's email address.
6:50:07But, um, as we see here, we now have a
6:50:10big list. We have city, country,
6:50:12departments, department, email domain,
6:50:13email status, employment, um,
6:50:16employment, you know, creative agencies.
6:50:18Obviously, all of these companies have
6:50:19the term creative agency in their title,
6:50:21which is great because I'm looking for
6:50:22creative agencies in this hypothetical.
6:50:24Um, founder and CEO, right? Then we got
6:50:26a ton of other ones, too. I think um
6:50:28Apollo just exports all of the fields
6:50:30about their job history, which is why
6:50:32it's so long. So if people have had like
6:50:3410 jobs, it'll actually like export all
6:50:35of them. Good god. Okay. But the one we
6:50:38really the one we really want is we want
6:50:40LinkedIn
6:50:41URL, which is this one right here. Okay.
6:50:44And as we see, we don't get the LinkedIn
6:50:46URL for everybody. But how long is this
6:50:50list?
6:50:52Um this list is 101. Okay, it's 101
6:50:56long. I'm just going to scroll up and
6:50:57then select all these. It looks like we
6:50:59got
6:51:0160 six uh I guess we're counting that
6:51:03one, too. So, 60 I think it's like 66
6:51:06out of
6:51:07100. So, we get about 66% of these as
6:51:10LinkedIn profiles, which is great. Um,
6:51:12you know, if I go down to email, I bet
6:51:13you we probably get a ton of emails as
6:51:15well. You always got to check the source
6:51:17data, which is why I'm doing what I'm
6:51:20doing. Um, we got 77. So, we actually
6:51:22got more email addresses than we did
6:51:24LinkedIn profiles. That's really
6:51:25interesting. But anyway, whatever. So,
6:51:27I'm sure you guys can imagine any sort
6:51:28of outreach campaign that you guys run,
6:51:30you guys could send emails and do
6:51:32LinkedIn DMs, right? And that's kind of
6:51:33like the golden um the golden egg, the
6:51:37golden goose. That's kind of like the
6:51:38golden goose egg. You know, if you hit a
6:51:40person on more than one platform, then
6:51:42that's obviously ideal. Um today, I'm
6:51:43just going to be building a LinkedIn
6:51:44system that does that outreach. But I
6:51:46want you guys to know that I've built
6:51:48the omni channel supposedly, that's what
6:51:50they're called, omni channel scrapers
6:51:52and systems and stuff like that a ton of
6:51:53times. um it's it's no major issues at
6:51:56all and um if there's demand for it then
6:51:57I could show you guys how you like kind
6:51:58of combine these two but okay so now we
6:52:01have a lot of stuff right we have
6:52:03profile fields we we we have everything
6:52:05it's great um so the question is where
6:52:06do we go from here well what I want to
6:52:08do now if we go back to our little road
6:52:09map is now that I've verified we can
6:52:11actually scrape Apollo leads using
6:52:12Ampify manually this little blue check
6:52:15mark is going to mean manually the green
6:52:16one will be after I'm done it um
6:52:17automatically we need to enrich the
6:52:19leads with personalization okay what is
6:52:21personalization well we basically need
6:52:23to write like a really small little
6:52:24snippet that we could stick at the very
6:52:26top of our LinkedIn, okay? So that when
6:52:29somebody gets a connection request, you
6:52:31know, it's it's just going to be a short
6:52:32little message that says like, "Hey,
6:52:33Peter, how's it going? Love your stuff
6:52:35and really want to connect with you."
6:52:36Okay? And that's what we're looking for.
6:52:38We're looking for for something over
6:52:39here. Hello, Fahhem Bernard and Anna.
6:52:41Hopefully you guys appreciate the views.
6:52:43Um, so actually, can I just going to
6:52:46show a little bit more here so I could
6:52:47see if I get an example? You see this
6:52:49from this lovely dude, Enel, who I think
6:52:50is in my Yeah, he's in Maker School. um
6:52:52I think I recognize him. He said, "Hey
6:52:53Nick, I just joined your community at
6:52:54school. I'm excited to start this
6:52:55journey." Okay, so we we basically want
6:52:57to personalize this just like Enel did.
6:52:59Um although obviously you're not going
6:53:00to be able to say that you joined my
6:53:01community, but by doing this, there'll
6:53:03be a much higher conversion rate on the
6:53:04back end. People are going to be a lot
6:53:05more likely to actually click the accept
6:53:07button if they see a message. Like you
6:53:08know, a lot of these other guys have
6:53:09joined my communities and stuff like
6:53:10that. And that's fine. Um but like you
6:53:13know, how much more likely am I to
6:53:14accept enels because I see that he's
6:53:15written me that message, right? A ton.
6:53:17That's the same logic we're going to be
6:53:18using. All right. All right. So, uh
6:53:20where are we? So, we just need to
6:53:22determine that we can personalize this.
6:53:24But, um, I know that LinkedIn has
6:53:25specific limits around how long we can
6:53:27do this. So, LinkedIn connection
6:53:30requests character limit. I'm just going
6:53:32to Google this really
6:53:33quickly. And it looks like we have a
6:53:35character limit of about 300 characters.
6:53:37That's actually pretty that's pretty
6:53:38small, eh? So, okay. So, 300 characters
6:53:42to words. Let's see how long that is in
6:53:45words. So, it's between 42 and 75. So,
6:53:48it's probably about 50 words or so. So,
6:53:49we actually got to make sure that our
6:53:50personalization snippet is super super
6:53:52short. Okay. Um, anyway, let me go to
6:53:55GPT40 here and let me just define a
6:53:57little prompt. Um, you are a helpful
6:54:00intelligent writing assistant. I'll say
6:54:02your task is to take as input. You guys
6:54:05might not be able to see all of this
6:54:06here just because I have my my face sort
6:54:09of covering it. Wonder if I can make
6:54:11this smaller. No, I
6:54:13can't. Anyway, trust me when I say this
6:54:15is going to be the most banger prompt of
6:54:18all time. Your task is to take us input
6:54:20a
6:54:21um bunch of LinkedIn profile
6:54:25information of a
6:54:27user and then generate a very short,
6:54:31very
6:54:33punchy icebreaker that I can use as a
6:54:36variable in the introduction in my
6:54:39connection
6:54:40request. So, I'm just asking it to do
6:54:43stuff like I'd ask a staff member. To be
6:54:45honest, AI is at that point now where
6:54:47it's intelligent enough to basically
6:54:48fully understand the context. Uh, if you
6:54:50go back to my previous videos from like
6:54:52a year ago, things have changed a lot,
6:54:53but now you can just ask like you would
6:54:55ask for anything from
6:54:57anybody. So, um, return results in this
6:55:01format. I'm going to have it return it
6:55:02in JSON JavaScript object notation. I
6:55:04know this may seem complicated to some
6:55:06people, but um, this just allows me to
6:55:08automate it later and I just want to
6:55:09verify I can do this. So, return um,
6:55:12your results in this format. Let's say
6:55:15icebreaker. Icebreaker goes
6:55:19here. Um, in order to ensure ice
6:55:22breakers are punchy and high quality,
6:55:25make them follow this
6:55:30template. Hey X. Hey
6:55:36name. Love seeing thing about them.
6:55:44I'm also into
6:55:47other
6:55:49thing plausible tie
6:55:54in thought
6:55:57I'd connect. Okay, so now I'm just going
6:56:00to see the length of this. I'm going to
6:56:02go to a website called word counter. So
6:56:03this one's 12 words, right? That's easy.
6:56:05And I think it's actually going to be
6:56:06even better because if I just scroll
6:56:08down here, you see how um yeah, you see
6:56:11how this message is like basically also
6:56:13about 12 words or so. So this is going
6:56:14to appear right before the see more
6:56:16badge. I think it's going to be great.
6:56:17This is going to be super super
6:56:18valuable. So um yeah, that's what I'm
6:56:21going to do. Um so I'm going to I'm
6:56:23going to add this
6:56:24in and then I'm going to say
6:56:29LinkedIn fields. Now I'm actually going
6:56:31to give it like an example of the data
6:56:32that I want it to personalize based off
6:56:34of. And then I'm going to see how it
6:56:36performs. And then assuming all the
6:56:37stuff is good, then I'm just going to
6:56:38pump it into NAND like one shot and it's
6:56:40going to be perfect. And by the way, um
6:56:42this kind of this is a good opportunity
6:56:43for me to talk a little bit about why
6:56:44I'm doing all this stuff like manually
6:56:46as opposed to going in Nad. And the
6:56:47reason why is because um I'm sure I
6:56:49could make it look really sexy and clean
6:56:51if I just did it all in N. But I don't
6:56:53normally actually build systems like
6:56:54this. I will start by just doing it
6:56:55manually at least once and just
6:56:56verifying that it kind of looks the way
6:56:58that I think it's going to look and
6:56:59works the way that I want it to look,
6:57:01works the way I want it to work. And
6:57:02assuming that it does, then I pump it
6:57:04into NAN and then you know I actually
6:57:05work through the the automation bits
6:57:07because the way I see it there's the use
6:57:08case and then there's the automation of
6:57:10the use case. Okay, so that might
6:57:13provide a little bit more context and
6:57:14hopefully that uh makes things clear.
6:57:16But okay, so we just need to feed in a
6:57:18bunch of fields here that'd be relevant.
6:57:20So what are we going to do? Obviously
6:57:22we're going to need the name, right? So
6:57:23I'm just going to grab Danielle
6:57:26um who is row number four.
6:57:31Um, just go Morgan
6:57:34here. Then I'm just going to dump it all
6:57:36in in plain text.
6:57:39Okay, let's just
6:57:42go Fort
6:57:45Lauderdale.
6:57:47Okay, like this. Um, that's probably
6:57:51pretty relevant. DM Creative Agency,
6:57:54it's probably pretty relevant. Founder
6:57:56and CEO. Oh, so maybe I'll go founder
6:57:58and CEO at DM Creative Agency.
6:58:01Cool. What else is like interesting and
6:58:04unique about
6:58:05her? Employment
6:58:08history. Um, I guess I could include it,
6:58:10but let me just see if there's anything
6:58:11else that might be a little bit better
6:58:12than employment history. I'm just going
6:58:14to drag this all the way to the
6:58:16right. Florida H. Okay. So, I mean,
6:58:20really, I don't have too much
6:58:21information here. I really only have
6:58:22like the company name.
6:58:25Um though it looks like a bunch of
6:58:27interests about the or sorry keywords
6:58:29about the organization. I might be able
6:58:30to feed that in
6:58:36there. Okay. Well, I think in that case
6:58:38like I'm going to have to feed in some
6:58:39of the past employment history, right?
6:58:41That makes sense.
6:58:42Um, in that way my um, you know, my
6:58:46outreach can talk about like, you know,
6:58:49it's I like that you went from doing
6:58:52like sales at whatever
6:58:54to being a founder of your own company.
6:58:56That must be interesting or or I did
6:58:58something similar or whatever, right?
6:58:59Like that's basically the vibe I want to
6:59:01go
6:59:02for. Previous
6:59:06experience. Um, and then I'm just going
6:59:08to say Outlast
6:59:10Eyewear. And then, sorry, I know I'm
6:59:13jumping around a lot here, but then I
6:59:14will say account
6:59:16director
6:59:18at Man, I cannot get these all tabs
6:59:20right at Red Ancy. Okay. And then I'm
6:59:24going to have it generate me the
6:59:25icebreaker now. Hey Danielle, love
6:59:27seeing your journey from regional sales
6:59:28director to founder and CEO. I'm also a
6:59:30creative leadership. Thought I'd
6:59:31connect. That's that's okay. That's
6:59:32okay. I don't really like the usage of
6:59:34the keywords here. Regional sales
6:59:36director. I want um I don't want to use
6:59:38the variables exactly because I want to
6:59:40imply that I've actually like read
6:59:42through it. So either I will lowercase
6:59:43them or I'm going to paraphrase
6:59:47them.
6:59:49Okay. Make sure to follow this template.
6:59:51So what I'm going to do here is I'm just
6:59:52going to zoom out a bit. I'm going to go
6:59:54over here and edit the
6:59:58prompt for thing about
7:00:01them and
7:00:04plausible plausible tie in. Never use
7:00:07the exact
7:00:10variable. Um, never use the exact
7:00:13information provided in a linked field.
7:00:16Instead, always paraphrase.
7:00:19This makes it seem human written instead
7:00:22of just an AI or an automated message.
7:00:25Let's do that. Okay. I'm going to delete
7:00:27this and we'll just run it one more
7:00:30time. Okay. And I'm also going to
7:00:32provide a little bit more context now
7:00:33because I don't like the result. What we
7:00:36had is, "Hey Danielle, love seeing your
7:00:37entrepreneurial journey with DM Creative
7:00:38Agency. I'm also passionate about
7:00:39turning vision." It's funny. DM Creative
7:00:41Agency. I guess it's her name, but like
7:00:43I'm I'm about to DM the hell out of this
7:00:45person. I'm also passionate about
7:00:47turning vision into reality. Thought I
7:00:48connect. That seems kind of weird. I
7:00:50don't like that. So, what I'm going to
7:00:51do is I'm just going to like make it
7:00:52super incredibly
7:00:56punchy. Also, make it super short. Don't
7:01:00say stuff
7:01:05like or anything like that. Be extremely
7:01:09laconic. Laconic and Spartan. Okay,
7:01:13let's try that one more time. Well,
7:01:15let's try that a couple more times till
7:01:16we figure it out.
7:01:19Cool. Yeah, this this looks pretty good,
7:01:20right? Spotting your creative agency
7:01:22journey. I'm also into entrepreneurial
7:01:24ventures. Thought I'd connect. I mean,
7:01:25you know, it's not like the best in the
7:01:26whole wide world, but that's much better
7:01:27than before. Diving into brand
7:01:29innovation. Thought I'd connect. Cool.
7:01:31That's pretty good. Let's run this
7:01:33again. Startup life. That's great. See,
7:01:35that's a pretty good
7:01:37icebreaker. Building brands. Thought I'd
7:01:39connect. Cool. That seems pretty
7:01:40reasonable. All right. Cool. So, I think
7:01:42like four out of the five so far have
7:01:44been all right. Fascinated by startups.
7:01:45All right. I think like four out of the
7:01:46five are pretty So, I'm just going to
7:01:47leave it at that. That seems to me like
7:01:48a pretty good prompt. Um, which means
7:01:50like my next kind of major task in this
7:01:52system is done, right? Um, the last
7:01:55thing I'm going to do is I'm going to
7:01:56send this to Phantom Buster for LinkedIn
7:01:57DMs. Now, this is this is kind of
7:01:58interesting, a little bit more nuanced,
7:02:00but basically what we have to do now is
7:02:02we have to take all of this data and we
7:02:03have to like send it to the platform
7:02:04that we're going to be using to actually
7:02:05like trigger the outreach. Now, that
7:02:07platform is called Phantom Buster. The
7:02:09way the Phantom Buster works is you
7:02:10basically pay for um some execution
7:02:12time. just a fancy way of saying that
7:02:14you're paying for like the amount of
7:02:16time it takes for the servers to run.
7:02:18I'm going to go over here to this um
7:02:20specific one that I've put together
7:02:22called LinkedIn autoconnect. And when I
7:02:23build out the whole NN system in a
7:02:25second, I'll um you know, I'll rename it
7:02:26and I'll make it nice and sexy. But
7:02:28basically way that it works is I go to
7:02:29setup and then what I have to do is I
7:02:31have to define a a Google sheet and I'll
7:02:33actually have it go down my Google
7:02:34sheet. Okay. So I'm going to do that and
7:02:37then I'm just going to add a column here
7:02:39called icebreaker. Okay. Then I'm just
7:02:42going to make this like one one person.
7:02:44It's just going to be this person that I
7:02:46was just doing the testing on, which I
7:02:47think was here, right? So I'm going to
7:02:49delete these two. Then I'm actually just
7:02:52going to delete all the rest of these as
7:02:54well because I just wanted to pull
7:02:56literally one record. Okay, so that's
7:02:59cool. I know I have a ton of redundant
7:03:01fields and whatever, but that's fine.
7:03:03Um, and then under icebreaker, what I'm
7:03:04going to do is I'm just going to feed in
7:03:06this um the data that it just generated
7:03:09for me.
7:03:10Then I'm going to paste that in here.
7:03:13And then voila. Okay, great. So now we
7:03:14have an icebreaker. Now the reason why
7:03:15I'm doing this is because I can now grab
7:03:17this Google
7:03:19sheet and I can feed it in here.
7:03:22Okay. And now I can actually run this
7:03:27using just feed that in. I can actually
7:03:29run like I can actually go and I can do
7:03:31um some LinkedIn outreach. Basically,
7:03:33the way that Phantom Buster works is you
7:03:35will connect your LinkedIn account using
7:03:37a um little Phantom Buster Chrome
7:03:39extension, which they will ask you to
7:03:40download when you actually get up and
7:03:42running with the service. Um, and then
7:03:43from there, you know, I'll just click
7:03:45save. And then here is the message that
7:03:47I will write. Now, I'm just going to
7:03:48write um they allow you to write a bunch
7:03:51of things. I mean, you could say, hey,
7:03:52first name, right? Then it'll pull the
7:03:54first name variable, but you know, I've
7:03:56actually just had AI write me a whole
7:03:58thing, right? So, I'm just going to use
7:03:59that whole thing, which is called
7:04:00Icebreaker. Okay. All right. So, now I'm
7:04:03going to click save. Uh, I'm not going
7:04:05to do anything for email discovery. I
7:04:06don't care about that. They just try and
7:04:07upsell you on stuff. Invitations to send
7:04:09per launch. Maximum 10 per launch, then
7:04:12save. Then launch manually whenever I
7:04:15click on it. And now I'm I, you know,
7:04:16again, I'm starting at the end. Just
7:04:17want to make sure I can actually do the
7:04:19thing that I'm asking for. So, I'm going
7:04:20to click this start button. And once we
7:04:22verified that, we can worry about um,
7:04:26you know, running it completely
7:04:27automatically. So, what are we seeing?
7:04:29We're seeing that I am indeed connecting
7:04:31to the LinkedIn. I'm connected as Nick
7:04:34Sar. I'm going through the whole
7:04:36rigomear roll
7:04:37here. Signing up, opening, sending the
7:04:40DM and stuff like
7:04:43that. It's going to take a while because
7:04:45it wants to um basically like simulate
7:04:48real profile activity. Doesn't want to
7:04:50think doesn't want to make LinkedIn
7:04:52think that I'm like a like a bot or
7:04:54whatever. So, it's going to take I think
7:04:55it's like a minute or two per profile.
7:04:57Okay. And as we can see, it just updated
7:04:58to one invitation already. Still
7:05:00pending. That means that the
7:05:01invitation's actually gone out. Um, so
7:05:03we are now 100% good to go. We verified
7:05:05that all of this system or all of what I
7:05:07wanted to do with the system works. Now
7:05:10I'm actually going to go through and I'm
7:05:11going to build it live in NAN. How fun
7:05:13and exciting is that? Never forget this
7:05:15step. When you're actually building out
7:05:16systems, make sure you can do the thing
7:05:18manually before you do it automatically.
7:05:20Otherwise, you're putting the cart
7:05:21before the horse. I've seen a ton of
7:05:23people do this and just really waste all
7:05:25their time with it. So I have an edit on
7:05:27canvas here called LinkedIn connection
7:05:28request system. If you think about it,
7:05:30what do we have to do? Okay, we have to
7:05:32start the
7:05:33system by scraping Apollo leads using
7:05:36ampify. Okay. Um, one thing that I think
7:05:39is really fun that I think I I'm going
7:05:40to do today just for fits and Google's
7:05:43is um this URL here, this actually
7:05:47includes all the information of the of
7:05:49the search, right? So what I think I'm
7:05:51gonna do is I'm actually just gonna have
7:05:52AI generate this URL for me. Like that
7:05:54would be pretty sweet, right? I'm seeing
7:05:56owner person titles equal CEO, person
7:05:58titles equal founder. I'm just going to
7:06:00go um what can you tell me about this
7:06:02URL? Feed this whole thing in here and
7:06:05let's see if we could just extract all
7:06:06the
7:06:08data. Yeah. So, are located in the US,
7:06:10owner, CEO, founder, partner, creative
7:06:13agency. Cool. Cool. So, I mean like I'm
7:06:15just going to have AI do this. I mean,
7:06:16how cool would it be if you could just
7:06:17say, "Hey, I want you to find me a list
7:06:18of all the creative agency owners in
7:06:20Texas and California or something." That
7:06:22would be sweet, right? and then we just
7:06:23like have it done for us. Hell yeah. So,
7:06:25I'm going to go over here and I'm
7:06:27actually going to start it with an NAN
7:06:29form input. Okay. And that's how this is
7:06:30going to work. When a new NAN form input
7:06:32is done, let's call this lead finder uh
7:06:36LinkedIn lead outreach
7:06:40trigger. Insert a an audience for your
7:06:45LinkedIn lead outreach. Let's say
7:06:48LinkedIn outreach campaign here. Then
7:06:51here I'm just going to do like text area
7:06:53and I'm going to
7:06:55say describe your audience in plain
7:07:00English. I'll make it required. And then
7:07:02what I want is a
7:07:05placeholder audience type. Uh I don't
7:07:09know
7:07:13company. Let's do
7:07:16like company
7:07:18type location
7:07:21etc. That should be good. Okay, let's
7:07:23test this stuff now. And I'll say I want
7:07:27all creative agencies in the United
7:07:30States with company sizes between 1 to
7:07:341,00. That's what I want. Okay, I'll
7:07:36click
7:07:37submit. And now that I have this, I'm
7:07:40actually going to feed this into AI just
7:07:41right off the bat. So go open AI. We'll
7:07:43go message an assistant credential I'm
7:07:45going to use is February 4th YouTube
7:07:47from the list. Uh I think I'll just use
7:07:50Oh, sorry. I think I'm messaging an
7:07:51assistant. I don't actually want to do
7:07:52that. I just want to do text. My bad.
7:07:54So, message a model. I think what I'm
7:07:56going to do here is I'll just do GPT4.5.
7:07:58I just want to see how like smart it is.
7:08:00Um you're a helpful
7:08:03intelligent sales assistant. So, I'm
7:08:05defining a system prompt start. That's
7:08:07where I tell the model what I think it
7:08:09is identifying as what I'd like it to
7:08:10identify as. Then underneath I'm going
7:08:12to say your task is to take as input
7:08:16a a natural language description of
7:08:22an of a prospect audience. Turn that
7:08:26into an
7:08:27Apollo search URL. Here's an example of
7:08:32an Apollo search
7:08:34URL. Okay. And then I'm going to go back
7:08:37to
7:08:39this and I'll say this URL. Oh jeez, I
7:08:44don't like
7:08:46that. This URL describes
7:08:49a search for people that
7:08:52are Let's do located. So I'm just
7:08:55telling it now that um this is an
7:08:58example of the formatting basically.
7:09:05You can
7:09:07change those fields and only those
7:09:11fields. Return your response in JSON
7:09:15using this format. Let's do Apollo.
7:09:18Let's just call it search URL. Then I'll
7:09:21go search URL goes here. Nice. Then down
7:09:24at the very bottom of this output
7:09:25content is JSON. I'm not going to add
7:09:27another message.
7:09:29And let's just pin this now. Oh, 99. So,
7:09:32we could do some testing with
7:09:36it. Go right over
7:09:39here and let's see what it pops up when
7:09:41I when I paste this in. And let's see if
7:09:43this is a valid Apollo search URL. I
7:09:44mean, you know, it's kind of like the
7:09:46first thing that you got to figure out,
7:09:54right? I paste this into
7:09:58Apollo. Yeah, this has Wow. Oh, this
7:10:01even broke down like the search size.
7:10:02That's very cool. Um, United States. Uh,
7:10:05I'm not seeing any keywords, though.
7:10:07That's an issue. So, I think like the
7:10:09way that I I always do these searches
7:10:11with a keyword like creative agency.
7:10:14Um, I think there's something broken
7:10:18here. Just want to make sure if I delete
7:10:20all these. Yeah, we're still not getting
7:10:22hide filters, show filters. Okay. So,
7:10:24there's some something broken about the
7:10:26way that I did this list a moment ago.
7:10:28So, let me just do this one more time.
7:10:35Um, let's do
7:10:39this. Let's just define my search a
7:10:42little bit more over here because I want
7:10:43to give it more
7:10:46examples. We'll go one to
7:10:50200. And then we're going to go creative
7:10:52agency. And I'm going to tell it can
7:10:54only
7:11:02These are the fields you can change. Um,
7:11:05and I'm going to say organization
7:11:10locations.
7:11:11Um,
7:11:13keywords, associated keywords. Sorry,
7:11:15one sec.
7:11:19Keywords and person titles.
7:11:28Cool. Do not add or change any other
7:11:31fields. Return your Okay, let's test
7:11:33this now and let's see if that maybe is
7:11:34a valid
7:11:38search. Uh, no, no, no. Do not add or
7:11:40change any other fields. Use the above
7:11:42template. Well, actually, maybe this is
7:11:44good. Let me
7:11:48try. All right. Yeah, that did work.
7:11:51location. Number of employees seem a
7:11:53little bit off
7:11:54though. Oh yeah, sorry. I think I need
7:11:56to add number of employees here. Um, one
7:12:00more. Let's go back to where it says
7:12:02number of employees up at the top. So,
7:12:05organization numbum employees ranges.
7:12:07There we go. That was the secret
7:12:10sauce. Person titles and organization
7:12:14num employees ranges.
7:12:17Let's just go back to my
7:12:21search. Just copy this in
7:12:24here. I'll paste that in too. Okay, now
7:12:26I'm going to run a test and I think I
7:12:28should be able to get most of what the
7:12:29information is that I
7:12:31want. Um, if I just copy this now and
7:12:34paste this
7:12:35in. Okay, this search correctly had the
7:12:371 to 1000. Correctly had the United
7:12:39States correctly had the term creative
7:12:40agency. Looks good to me, man. Cool. So,
7:12:42we now have a system that can basically
7:12:43you just put in a search term for what
7:12:45you want. it'll come out with an Apollo
7:12:47search URL. That's sick. Okay, so now
7:12:49what do we have to do? Um, we have to
7:12:51scrape the leads using ampify. So, two
7:12:53components to this, right? The first is
7:12:55we need
7:12:56to well, we need to call an appy actor.
7:13:00So, we basically need to replicate what
7:13:01I just did over here with ampify, but we
7:13:03need to do it in naden. So, how are we
7:13:06going to do that? Well, apply has an
7:13:08API. So, I should be able to run this
7:13:10using an API.
7:13:13So, if I want to trigger a
7:13:19run, I'm going to have
7:13:21to view the API reference
7:13:24first. So, how do we get a run actor?
7:13:27Run actor synchronously with input and
7:13:30return output. Okay, so this looks to me
7:13:32like basically what I want. Cool thing
7:13:33about NAND is it allows me to just
7:13:35create a uh a request using an HTTP
7:13:39call. So, sorry, a curl call. So, that's
7:13:41what I'm going to do is see it says curl
7:13:42over here. I'm just going to copy this
7:13:43whole thing. But actually, before I do
7:13:44that, I'm actually going to put in the
7:13:45the data. So, I need an HTT um I need a
7:13:49key. It looks like an API key. So, I'm
7:13:50need to put that in there. Then, I'm
7:13:52going to need an actor. Okay? So, see
7:13:54this? This is where I'm going to put an
7:13:55actor in. So, I'm going to go back here
7:13:58and you see where it says actors and
7:14:00then JJ, whatever. This is the actor ID.
7:14:03Um, you'll always find the actor ID up
7:14:05at the top
7:14:07um, between the term actors and then
7:14:10input on Ampify. Uh, there's probably
7:14:13another way that I get this as well, but
7:14:14that's just kind of the hack that I use.
7:14:16So, I'm going to go sorry, I'm going to
7:14:18go back over here. And now what I'm
7:14:20going to do is under parameters, I'm
7:14:21going to feed in the actor ID. Okay.
7:14:23Then the bearer token. I basically need
7:14:25an API key. So, I don't know where I get
7:14:27my API key on app. I've already
7:14:28forgotten. I'll probably get it in
7:14:29settings API and integrations. Yeah.
7:14:31Okay. So, I'm going to create a new
7:14:32token. I'll call this YouTube and
7:14:34create. I now have a new token. So, I'm
7:14:36going to copy this and I'm going to go
7:14:38back to the API specification which was
7:14:41just
7:14:42docs.appify.com. Then I'm going to paste
7:14:44in the bearer
7:14:45token. Okay, that looks pretty good. It
7:14:48looks like I need a body. Okay, it says
7:14:50example from schema or example. So, I
7:14:52don't really know what that means.
7:14:55Um, just body required as an object. So,
7:14:58what is what is this supposed to mean?
7:15:00Just looking for the term body here
7:15:03now. Well, it's telling me that it's
7:15:11required.
7:15:15So, I'm just going to give this a try
7:15:17and see what happens, I
7:15:19guess. So, let me just Yeah, let me just
7:15:21copy over all the
7:15:22curl. Go back here and go to HTTP
7:15:26request. Import curl. Paste this in.
7:15:31It should now map this. So, it maps it
7:15:33to the specific actor. That's
7:15:34cool. Um, I don't actually have my token
7:15:37in here, so apologies. I kind of wasted
7:15:40our time. I'm just going to copy this
7:15:41now and feed it directly in. So, this is
7:15:44where the API key token would go. Go
7:15:45authorization. And then there's this
7:15:46format like bearer token format, which
7:15:49is what most um services use. So, just
7:15:51make sure the bearer starts with a B,
7:15:53capital, and then there's a space, and
7:15:54then there's your actual
7:15:56token. Okay. Okay, so we need to do a
7:15:58post request. Good. Uh JSON body
7:16:02parameters are foo and bar. I don't
7:16:03really know we're going to feed in the
7:16:04body to be honest. I don't really know
7:16:06about this follow redirects thing
7:16:08either. So I'm just going to take that
7:16:09out. I think what we need are we need
7:16:11some query parameters,
7:16:13right? I
7:16:15think maybe we don't. I don't know.
7:16:19Anyway, in situations like this where I
7:16:20don't know, what I do is I just run it
7:16:21and I see what happens. And then
7:16:23sometimes it'll tell me what the issue
7:16:24is. So input URL is required. Okay. So
7:16:28we need in the body probably we need
7:16:32input.
7:16:36Um I'm just going to do this in
7:16:38JSON. I'm going to go
7:16:41input and then I'm going to go
7:16:44URL.
7:16:46Okay. So then I'm going to go over to my
7:16:48sales navigator search
7:16:50URL which is right over here.
7:16:55Uh, nope. That kind of stuck at the very
7:16:57bottom. Just take that back in. Paste
7:16:59this in here. Okay. So, that should now
7:17:02have the URL. Uh, field input. Now, it's
7:17:05still saying that it's required. So,
7:17:06there's probably something that I'm um
7:17:08persistently messing up here with the
7:17:09format. So, let me go back to my actor
7:17:10run. Okay. Go back here. And then,
7:17:14sorry, where it says JSON. Let me just
7:17:16get all this. Okay. This this might be
7:17:18all I need. I don't know for sure. We're
7:17:19going to give it a try, though.
7:17:22We're going to test
7:17:24this. Yeah. So that is so the JSON here
7:17:26is just the input because you know it's
7:17:29executing. It's taking time now. So now
7:17:31I don't actually know if it's running
7:17:32right. So let me just exit out of this
7:17:34stuff. I'm going to go to runs. Okay,
7:17:36cool. So it is running. So now verify
7:17:37that I've I've just triggered it inside
7:17:39of uh inside of N8 and now it's running
7:17:41in Apify. Fantastic. So basically what I
7:17:44need to do is you see this big URL here.
7:17:46Well, we don't need that. What we need
7:17:47is we need this, right? So, I'm going to
7:17:48feed this in. And total records. Uh, I
7:17:51mean, you know, you can put however many
7:17:52you want. I'm just going to do a
7:17:53thousand. If you leave that blank, I
7:17:55think you get all of them. Personal
7:17:57emails, work emails. I think this just
7:17:58means it takes a little bit longer.
7:18:00Then, while this is working, let me just
7:18:01do some renaming. So, I'll say run
7:18:04ampify actor and get results. A little
7:18:07bit longer than usual. Uh, I think
7:18:10I might have just broken
7:18:11this. Yeah, I think I just broke this by
7:18:14renaming it. Okay, maybe you don't
7:18:16rename this live. That might be bad.
7:18:19Anyway, um I'm then going to call this
7:18:22person uh not personalize. I'm generate
7:18:24search
7:18:26URL. Okay. I'm going to save this whole
7:18:29thing. I'm obviously going to have to
7:18:30rerun this now because I've just broken
7:18:32my whole thing. Kind of
7:18:35unfortunate, but it is what it is.
7:18:40Um let's just test the step again. And
7:18:42I'm just going to pin the output next
7:18:44time.
7:18:46So, let's just make sure this
7:18:48works. Feed that in again. Yeah,
7:18:51persistently working, which is nice. Can
7:18:53pin this now. Let's feed that in right
7:18:56over here. Test this again. So, my
7:18:58memory limit may be an issue. We'll see.
7:19:02It's executing. So, yeah, we're running
7:19:03a separate we're running a separate
7:19:04query. I'm going to abort the first one.
7:19:06I'm not going to give it 30 seconds. I
7:19:08don't care. I'm aborting
7:19:09you. Um, cool. And now we just have to
7:19:13wait until this finishes basically until
7:19:15we get all the results. And then when we
7:19:16get the results, it should populate on
7:19:17the right hand side of this. Okay, looks
7:19:19like this did output but it returned
7:19:21something empty. Looks like the reason
7:19:23why is I probably used the wrong um
7:19:25actor. I used run actor synchronously
7:19:28and return output. I didn't do run actor
7:19:30synchronously with input and get data
7:19:32set items. That's the one that you want.
7:19:33So woe is me. Um but I'll basically have
7:19:37to rerun that puppy is what it is. Um, I
7:19:40have the actor ID hardcoded here. So,
7:19:42I'm just going to paste this in my URL
7:19:43bar. Copy this over here. Paste this in
7:19:47here and go back that way. And then just
7:19:50for records, I got to do 500 cuz I just
7:19:52waited like 5 minutes to do a th00and.
7:19:55And I don't really want to wait that
7:19:56long. So, let's test this
7:19:59again. I'm seeing that it is indeed
7:20:02executing. Going back over here to
7:20:05runs. And, you know, we are we are now
7:20:07doing a run, which is nice.
7:20:09Um, yeah, looks like the run is running.
7:20:13Okay, great. And that looks like it just
7:20:14wrapped up. We got 500 items because I
7:20:17went back and I changed the number of
7:20:19total items to 500. Um, and now we
7:20:22basically have everything that we need
7:20:23in order to proceed with and then
7:20:25complete this whole flow. And as you can
7:20:27see, not super complicated. We had one
7:20:30form submission, one uh module or node
7:20:33to generate a search URL, and one module
7:20:35node to run an Appify actor and then get
7:20:37the results. And because I never ever
7:20:38want to have to do that again, I'm just
7:20:39going to pin this. And what I'm thinking
7:20:41is by me pinning this, I'm just not
7:20:43going to have to run that same actor
7:20:45over and over and over again. I'm not
7:20:46going to have to like have those crazy
7:20:47weight times. That's an important point
7:20:49for me to make more generally. Like um I
7:20:50find a lot of people, they will um test
7:20:54stuff using like repeat manual inputs
7:20:56over and over and over again. So if
7:20:58they're testing a form or something,
7:20:59they'll actually fill out the form every
7:21:00time. And it doesn't seem like that adds
7:21:02a lot to the process, but consider I
7:21:04might test a flow 20 times over the
7:21:05course of my development. If I test 20
7:21:07times and every time takes me additional
7:21:09minute to fill out the form, I've
7:21:10basically like added 20 minutes to my
7:21:12whole workflow, right? And as you see, I
7:21:14build these pretty simple but very high
7:21:15ROI systems like over the course of an
7:21:17hour or so in a video. Um, if I were to
7:21:19do that, I would materially improve
7:21:20increase my production times um,
7:21:22impacting them like 20 30 maybe even
7:21:2440%. So, I just like to pin data
7:21:26wherever possible. Helps avoid like a
7:21:28lot of the BS. Okay, now that I have
7:21:31this Ampify actor um, output, we we've
7:21:33got a bunch of items here. I'm going to
7:21:35go back to my road map. What do we
7:21:37really need to do? Well, next up is we
7:21:39need to enrich these leads with
7:21:41personalization. So, that's going to be
7:21:42pretty easy. You know why? Because we've
7:21:44already done most of the
7:21:45work. I'm going to go to OpenAI and then
7:21:48I'll go message a model. Okay. And then,
7:21:50if you guys remember, I already I
7:21:51already wrote most of this prompt. So,
7:21:52I'm just going to copy and paste this
7:21:54prompt right over here. So, I'm going to
7:21:57select my own credential. If you don't
7:21:58have a credential, make sure to set it
7:22:00up. You need to just copy over your um
7:22:02OpenAI API key. I'll select
7:22:06GPT4.5. I'll paste this in as my system
7:22:09prompt. And then I'll just move
7:22:12down and copy all of this as my user
7:22:15prompt. Okay, I'll make a couple of
7:22:18changes. Why? Because I don't actually
7:22:20need these lines and
7:22:23stuff. What I can do is I can actually
7:22:25just take this and feed this in as an
7:22:26additional user prompt instead.
7:22:29And here I can feed in an assistant
7:22:30prompt, have it give me an
7:22:33example, right? Because I wanted
7:22:36to. Then I can go back here, feed in
7:22:39another user prompt, and then this is
7:22:41going to be my actual live data, right?
7:22:43So what information did I put in? I put
7:22:44first
7:22:47name. So I will do first name here. Oh,
7:22:50that's ugly. One sec. I'm going to go to
7:22:53expression, paste this in, then I'm
7:22:56going to call this linked in field. You
7:22:59can, you know, actually add all of the
7:23:01information in
7:23:03um like in JSON if you want, but it it
7:23:06doesn't really make any difference,
7:23:07right? And in doing this, I get to save
7:23:09a couple of uh tokens, which may not
7:23:11make that big of a difference in
7:23:14isolation, but it does definitely make a
7:23:16big difference. Um, if you zoom out a
7:23:18little bit and like look at it over the
7:23:20course of, I don't know, a month of
7:23:21running this, a year of running the
7:23:23system. So, I need to find the city. Is
7:23:25it city? I think it's city. Yes, city is
7:23:27Grand Rapids. So, I'm just going to grab
7:23:29this here. Paste this in right there.
7:23:34Then, what I need next, I need job
7:23:37title and go title, creative director.
7:23:39That's
7:23:41cool. At and then the company
7:23:45name. What is the current company name?
7:23:48Headwind agency. It looks like the um
7:23:51employer employment history zero is
7:23:52always that. Then previous
7:23:55experience and I'm going to
7:23:58go co-founder
7:24:01COO at mission 3 media. That's cool.
7:24:07Um, let's do one
7:24:09more. We'll
7:24:12say producer at self-employed at least
7:24:15for this
7:24:16guy. Um, feed that in. Okay, great. So,
7:24:19what does this look like now? LinkedIn
7:24:21fields grand whatever Grand Rapids.
7:24:23Okay, nice. Self-employed. Beautiful.
7:24:25Beautiful. I'm then going to output my
7:24:27content as JSON. Go test step. And from
7:24:31here, our output should generate some
7:24:33cool personalization that we can then
7:24:35also map directly because it'll be um
7:24:38JSON variable. Should note that I'm
7:24:40using 4.5 preview for this. You don't
7:24:41need to be using 4.5 preview. I just
7:24:43like to use the best models for stuff.
7:24:46Why? I don't know. It's a flex. I like
7:24:48flexing. See these muscles just screwing
7:24:50around. This one's taking a little bit
7:24:52longer than usual. Uh might be because
7:24:53of token usage or something on my
7:24:55account. I'm not entirely sure. So, when
7:24:58I run into issues like
7:25:00this, just going to see if I could stop
7:25:03this. Doesn't look like I can. Okay,
7:25:06cool. I did end up stopping this. Maybe
7:25:08I'm just going to use Okay, let me just
7:25:10try rer runninging this now with that
7:25:12test
7:25:14data. Okay, once that's done, we've
7:25:16leads personalizations. Then we just
7:25:17have to send to Phantom Buster. And the
7:25:19way that we're going to do the the
7:25:20sending to Phantom Buster is I'm going
7:25:22to um just connect to their API and I'll
7:25:24send like an API request trigger with
7:25:26the uh with the Google sheet that I'm
7:25:28dumping to. So actually there's an
7:25:29intermediary step here where I need to
7:25:30dump stuff to Google sheet which I
7:25:32haven't really put together. Um but
7:25:33we'll we'll talk about that. Maybe
7:25:35actually I guess what I should do then I
7:25:38should probably dump leads to Google
7:25:40sheet, right? Then four should be send
7:25:43to Phantom Buster. Send sheet to Phantom
7:25:45Buster for LinkedIn DMs. I trigger
7:25:48Phantom Buster for LinkedIn DMs. That's
7:25:51probably what I'm gonna do. And I mean,
7:25:53this now looks kind of weird, but copy
7:25:55and paste that everywhere. Yeah, this is
7:25:57taking its sweet ass time. So, I'm not
7:25:59really sure what's going on with that,
7:26:00but as I'm sure you guys know, um, a lot
7:26:03of the time when you make an automation,
7:26:06there will be platform bugs or some
7:26:08minor issue with the nodes or the
7:26:10modules. I'm going to just change this
7:26:11model and see if that makes it snap out
7:26:13of it.
7:26:15So, we're just going to go
7:26:17GPT40 and then I'm going to test this.
7:26:20Uh, actually, looks like I have a bunch
7:26:22of additional new lines here. I don't
7:26:24know why. Should probably remove
7:26:27that. Check this out here as well. No,
7:26:30that's fine. How about this one? Does
7:26:32this one have any additional new
7:26:34lines? Can't really drag it open, which
7:26:36is unfortunate. I guess I have to give
7:26:37it a
7:26:38click. Well, looks pretty good. Yeah, no
7:26:42problems there.
7:26:44Oh man. I'm so stupid. It's cuz
7:26:46I'm doing 500 items. Duh. Oh my god. I'm
7:26:50probably racking up my Man, that's
7:26:52crazy. Okay, so what I need to do is I
7:26:53put a put a max items here. Just set max
7:26:55items to one. That way it's only going
7:26:57to generate one icebreaker. I was trying
7:27:00to erroneously generate 500 ice
7:27:02breakers. Don't be silly or stupid like
7:27:04me. Anyway, now that that's done,
7:27:08uh, we verify that this does in fact
7:27:09work. I can go back over here now and I
7:27:11could go and I could check Enrich leads
7:27:14with personalizations. Duh. Okay. Next
7:27:16up, we need to dump this to a Google
7:27:18sheet. So, what am I going to do? I'm
7:27:19going to go to sheets right over here.
7:27:23Going to
7:27:24um append row and sheet. I'm going to
7:27:27select my credential. I already have one
7:27:29called YouTube, but in your case, you
7:27:30might have to like connect it and do
7:27:32your OOTH and stuff. Then the operation
7:27:33is just going to be append row. I'm just
7:27:35going to be adding these to a new sheet,
7:27:36right? Append or update a row. Sorry.
7:27:39I'm going to make a new sheet. So, we'll
7:27:41go sheets.google. google.com. And then
7:27:43what I'm going to do is I'm just going
7:27:44to go to my account, which I know has a
7:27:46connection, which is this one here. Then
7:27:48I'm going to create a new one. This is
7:27:50just going to be called leads. Um I'm
7:27:53going to go to
7:27:54document. Look up leads. See if we can
7:27:57find something. I can. The sheet I'm
7:28:00going to choose from is just going to be
7:28:01sheet one. We're going to map each
7:28:03column manually. Now, can we just map
7:28:04automatically? That'd be great. Just
7:28:07dump literally Oh, no. No, we can't
7:28:10because we're only going to dump in this
7:28:12stuff then, right?
7:28:15H I wonder can I just
7:28:23grab I would like to have all of this
7:28:26information automatically in the Google
7:28:27sheet without me having to manually add
7:28:29every
7:28:32um manually add everything. Otherwise,
7:28:35I'm going to have to manually add
7:28:36everything. That'd be brutal.
7:28:41Yeah, that'd be kind of kind of
7:28:45crazy. The columns in Google Sheets. Oh,
7:28:47I get it. I get it. I need to set column
7:28:50names
7:28:51here. Okay. So, what I'm going to do is
7:28:53I'm just going to set these column
7:28:57names. Create a
7:29:00CSV of these header
7:29:04names. Let's see string. These are names
7:29:06that I can paste into Google Sheets.
7:29:08Just going to paste this in. And then
7:29:10what I want is I want LinkedIn
7:29:13URL. And then I also want
7:29:15icebreaker. And I mean you can put in as
7:29:17much of this information as you want.
7:29:19All of this additional information. I
7:29:20don't really want to. I just want to
7:29:21just, you know, get this up and running.
7:29:23So that's what I'm going to be using as
7:29:24an
7:29:26example. So this now has all of the
7:29:29sheets. It's telling me that one of the
7:29:30headers is twice. So, I'm just going to
7:29:32go to data and then I'll go split text
7:29:33to columns. So, I have two, yeah, I do
7:29:36have two instances of LinkedIn URL.
7:29:37That's okay. I'm going to go over here
7:29:39and now I have my leads sheet, which is
7:29:41nice. I'm going to go back and now I'm
7:29:43going to go map each column
7:29:46manually. And then it's going to match
7:29:48on
7:29:50ID. What I want to do is can I just
7:29:53actually maybe I can just go map each
7:29:54automatically. I don't
7:29:57know. I don't know if this is right. So,
7:30:00let's just get this test. see what
7:30:03happens. Just supposed to be adding a
7:30:05single row in
7:30:08here. And it's not. Um, and the reason
7:30:12why is
7:30:13because it's grabbing data from the open
7:30:17AI node instead of the previous uh limit
7:30:19node, which is what I want. So, I'm
7:30:20actually going to map each column
7:30:21manually. It's going to find all the
7:30:23ones for me. Then, what I want is um
7:30:26under this, I'm going to use ID for ID.
7:30:28First name is obviously going to be
7:30:30prank. Last name is going to be
7:30:31whatever. Um, name is going to be full
7:30:34name, I guess. Let me
7:30:35see. First, name. Then LinkedIn URL. So,
7:30:38I need to find the LinkedIn URL
7:30:43somewhere. Should be right over here.
7:30:45Then, what else did we have?
7:30:48Title. Let's go.
7:30:51Title email status. I don't really know
7:30:54why I put that in there, but whatever.
7:30:57basically just mapping a bunch of
7:30:58irrelevant fields right now just to show
7:31:00you guys what the process would look
7:31:01like. Then finally, icebreaker. The
7:31:03icebreaker would be the um message from
7:31:05the open AI node, right? Okay. So now
7:31:07we're going to test
7:31:09this. Giving it a go. You can see the
7:31:12icons changed here. And voila, right?
7:31:13We've now dumped in the records. That's
7:31:15nice. So now that we have this Google
7:31:16sheet, what does this mean for us? Well,
7:31:17we can actually just take this Google
7:31:19sheet. I'm going to go editor. Maybe
7:31:21I'll change it to viewer. Actually, I
7:31:23don't really want you to uh somebody
7:31:26always on from my YouTube, somebody will
7:31:28always find some of my sheets and then
7:31:30like come in and then just like draw
7:31:31dicks on them or something. It's It's
7:31:32hilarious. Whoever you are or whatever
7:31:34group of people you are, keep fighting
7:31:36the good fight. I'm just going to uh I'm
7:31:38going to start locking these down a
7:31:39little bit more. Okay, so that's that.
7:31:42Now that I have this Google sheet, what
7:31:43I do is I just go into Phantom Buster.
7:31:45Okay, right over here. I'm going to, you
7:31:49know, I go to LinkedIn solutions
7:31:51LinkedIn and then down here I go
7:31:54connection request or
7:31:57auto. It'll be an auto connection sender
7:32:01essentially. So I don't know where this
7:32:05is somewhere
7:32:08here. Might be connect
7:32:10request auto invitation maybe.
7:32:18autoconnect. There we go. This one here.
7:32:19So, I'm going to use
7:32:21this. What I'm going to do is I'll
7:32:23change the input into a spreadsheet URL.
7:32:25So, now I'm going to paste the
7:32:26spreadsheet URL in. Okay. The value of
7:32:29this is it's publicly accessible. Then
7:32:31from here, the name of the column
7:32:32containing profile URLs is going to be
7:32:34this LinkedIn URL one. I'm going to keep
7:32:36all of these columns in my output file
7:32:39because I'm I'm going to want
7:32:41them. Now, I then select my LinkedIn
7:32:44account. So, in my case, I'm going to
7:32:45select this one here. And I should note
7:32:46that if you want to send the LinkedIn um
7:32:49messages with like the um customized
7:32:51connection requests, uh I think to
7:32:53anybody that's not like um a second
7:32:55connection or something, you need a you
7:32:56need a LinkedIn sales navigator
7:32:58subscription now. I have everything that
7:33:00I need. I can just go icebreaker. Right.
7:33:03So, that's what I'm going to be sending
7:33:04people. I go back to
7:33:07save. I'm going to click none for this
7:33:10behavior. I'm going to do 10 per launch.
7:33:14Then I'll just leave this at
7:33:16manual and I'm going to rename this
7:33:20now auto icebreaker connect. And voila.
7:33:25Now what I'm going to do is I'm going to
7:33:26grab the ID of the Phantom which is
7:33:27going to be up here. Okay. And now I
7:33:29have to do an API call basically to
7:33:30trigger this. So we need to go to
7:33:32Phantom Buster and check their
7:33:34API. How do we do
7:33:37this? Uh we go up here. Sorry, up here.
7:33:40There we go.
7:33:42And I think the and I don't I don't know
7:33:44for sure. I'm thinking it's
7:33:45probably agent and it looks like they
7:33:48have a V2 APS. That's what I'm going to
7:33:50use. I'll go to
7:33:51agent. Agent launch probably. Yeah.
7:33:55Yeah, this is the
7:33:56one. Then I'm going to grab a curl. Is
7:33:59there a curl? Yeah, there's a curl right
7:34:00over here. So, I'm going to copy this
7:34:03over. If I just try this, am I going to
7:34:06run? Cannot validate data. Should have
7:34:08required property ID. Oh, yeah. ID of
7:34:10the agent to launch. There we go. If I
7:34:11feed this. Oh, yeah. Okay. So, what I'm
7:34:13going to do is I'm going to go to my
7:34:15LinkedIn agent, and then I'm going to
7:34:16grab the um the Phantom ID, which is up
7:34:19here. I'm going to paste it in. And
7:34:20that's going to now include that data.
7:34:21If I click try now, should be at 200.
7:34:24And then if I go back here, it's
7:34:25probably running now, right? Yeah, it's
7:34:27running. Sick. Cool. So, we just verify
7:34:29that we can actually now run
7:34:30this. Now, is it possible to abort this
7:34:33midrun because I don't actually want to
7:34:35connect to LinkedIn and do all that fun
7:34:36stuff? Uh, it is. Cool. So, what I'm
7:34:39going to do now is I'm going
7:34:41to just recreate my HTTP curl request.
7:34:45I'm going to go back to the API, copy
7:34:48this curl request, go back to NAN,
7:34:51import curl, paste this in. It's now
7:34:53going to automatically map all of these
7:34:56fields. Then, if I scroll down, I have
7:34:58my Phantom Buster key. On Phantom
7:35:00Buster, you need to create an API key.
7:35:01So, you just go over here to API keys,
7:35:03you click create API key, and then
7:35:05voila, you have another one. And then,
7:35:06I'm just going to delete the one
7:35:07afterwards. But you can only copy it
7:35:09once u basically. So make sure to copy
7:35:11it when you can then feed it in as an
7:35:14x-vantobuster- key API key up here. The
7:35:17ID of the specific agent is right over
7:35:19here. I mean it's just mapped all
7:35:20correctly. And now I'm just going to
7:35:21click test
7:35:23step. And it's executing. Now Phantom
7:35:26Buster won't return um a note saying
7:35:28that like you're good to go. It's just
7:35:29going to return a 200 and say container
7:35:31ID. The reason why is because they allow
7:35:33you to check on your container ID later.
7:35:35So what you realistically could do,
7:35:38okay, is you could have a container
7:35:41ID. You could have a web hook sent to
7:35:45another scenario or another node,
7:35:47another workflow. You could check that
7:35:49and you could use that to update this
7:35:51record saying sent question mark and
7:35:53then we could go down one by one. So
7:35:54that's what I'm going to do. So I'm just
7:35:57going to rename this now to trigger
7:35:59phantom
7:36:00buster agent just so I have this. So
7:36:03then over here it's going to be add to
7:36:06Google sheet. Wonderful. This here was
7:36:10um personalize
7:36:11outreach. And now that we have
7:36:13everything, all we need now is we need a
7:36:15web hook trigger that basically triggers
7:36:17another portion of this flow. So a
7:36:19variety of different things we could do.
7:36:22Um what I'm going to do is I'm just
7:36:24going to add a separate node or a
7:36:26separate workflow. I'll say trigger
7:36:28phantom buster agent.
7:36:33So I'm going to go number one. Then I'm
7:36:36going to have another number two. And
7:36:38the number two is going to basically
7:36:39watch for the completed
7:36:41run. I'm going start with a web hook.
7:36:45I'm going to paste the title in. I'll
7:36:46call this two. And then instead of
7:36:49trigger phantom buster agent, it's going
7:36:51to be update Google sheet with phantom
7:36:54buster connect requests. These are
7:36:57getting pretty long. So you can call
7:36:59this stuff whatever the hell you want.
7:37:01But now what I have to do is I have to
7:37:02figure out how to send a web hook. I
7:37:03know that you could send a web hook
7:37:04somehow. So I'm going to go back to
7:37:07dashboard. Go back here. And there's got
7:37:09to be a way to send a web hook,
7:37:11right? Advanced settings probably. Yes,
7:37:14there it is. Web hook. Cool. Custom web
7:37:15hook URL. So now I'm going to go into
7:37:18NAN. I have a little web hook set up.
7:37:21And what I'm going to do is
7:37:23um looks like web hooks will post a
7:37:26payload. when they post a payload, that
7:37:28just means that in order for you to
7:37:30receive it in N to change the HTTP
7:37:32method to post. Okay, if it's get,
7:37:34you're not going to get anything. It's
7:37:35just going to hang forever. So, we're
7:37:37posting the payload. It's going to have
7:37:38everything
7:37:39here with a container ID. This is
7:37:41probably what we're going to use to um
7:37:44to get the data now that I'm thinking
7:37:46about
7:37:47it. So, that's what it's going to look
7:37:49like. So, we have the container ID and
7:37:50we're going to do something else. All
7:37:51right, that's fine. So, um let's listen
7:37:54for a test event.
7:37:56And let's just
7:38:00uh well, is this done yet? I think I
7:38:04aborted this, right? Okay. Well, let's
7:38:06just let's just trigger this then one
7:38:08more
7:38:09time. Trigger me, baby, one more time.
7:38:13Should get a container ID. Cool. And now
7:38:16just while while we're listening for
7:38:18this, because this is listening right
7:38:19now, um I believe I can just continue
7:38:21building this. And if you think about it
7:38:23like what I need to do is once I have
7:38:24the web hook I need to get the data from
7:38:26the container ID right so I'm go back to
7:38:29my API reference and then
7:38:32containers let's just
7:38:34fetch output fetch the output of a
7:38:37container right so that's what I want so
7:38:40now I'm just going to copy over this
7:38:45um go back here do an HTTP request
7:38:48import this
7:38:50curl we're going to map it including the
7:38:52ID and everything that I need. And we're
7:38:55hard coding the container ID, right? I
7:38:57think. Let me just go back to wherever
7:38:59that container ID was. Yeah, I think
7:39:01we're I think we're hard coding the
7:39:02container ID. I'm pretty sure. And
7:39:04that's going to include the output. Now,
7:39:05the output is going to include a list of
7:39:06all of the records that we've actually
7:39:08sent the request to, which is nice. So,
7:39:10from there, I should essentially be able
7:39:12to do everything that I need to do.
7:39:14Okay. So, I mean, the trigger event's
7:39:16taking forever. Let me just see if I
7:39:17could run this as
7:39:19is. Oh, sorry. All right, it's going to
7:39:21be executing the web hook node. So, let
7:39:23me just add a manual trigger first and
7:39:25then let's connect this.
7:39:28Now, let's exit out of this and I'll
7:39:30click test workflow. Nope, just this.
7:39:34Thank
7:39:35you. It's saying the resource I'm
7:39:37requesting could not be found. So, why
7:39:38is that? Um, there must not be any
7:39:43data. There's probably no
7:39:47data. So, I'm just going to see if we
7:39:48can get the container ID. Is there
7:39:50container ID? I'm not seeing any
7:39:52container ID. Identity, maybe identity
7:39:54ID might be container ID. Not really
7:39:56sure. I don't know if that's what that
7:39:59means. Um, well, it did work. It
7:40:02actually went and it sent the request.
7:40:04That's pretty
7:40:06badass. So, what are we going to call I
7:40:08think it might be this identity ID.
7:40:10Unfortunately, it doesn't look like I
7:40:12can copy it. Doesn't let
7:40:14me. So, that sucks. Um h how am I going
7:40:18to get the container ID of the
7:40:28thing? I guess I
7:40:31could just
7:40:35uh grab a different
7:40:41container. This this one
7:40:44maybe. Let's just Let's try this. Okay.
7:40:48Oh, what the heck's this? I don't know
7:40:50what this
7:40:52means. This looks like a
7:40:56dust. Huh? That's the That's the output.
7:41:01Huh.
7:41:04Weird. So, I don't actually know if
7:41:06that's what we want. Do we want the
7:41:07container ID then?
7:41:10No, we want
7:41:12um agents fetch output. Get the output
7:41:15of the most recent container of an
7:41:17agent. Maybe we just need this. Okay.
7:41:19It's designed so it's easy to get
7:41:20incremental data from an agent. Output
7:41:22of the most recent container. Okay.
7:41:24Well, I'm just going to I'm just going
7:41:25to call this then like right. Yeah,
7:41:27let's just do that. Um let's not even
7:41:30worry about all this stuff. Let's just
7:41:32get the ID of the
7:41:35agent. Okay. Should be right over here.
7:41:38Now, let's do an HTTP request, but this
7:41:41time we'll do it to fetch output. Okay,
7:41:44so I'm going to copy this over, paste
7:41:46this in the test
7:41:48field. Try it. And now, we did get a
7:41:51weird We did get a really weird output.
7:41:53I'm not really sure what that
7:41:58means. Process finished. Spreadsheet is
7:42:01empty or everyone has already been
7:42:02added. Okay. Okay. Yeah. No, we did we
7:42:03did actually get
7:42:05the we did actually get the output.
7:42:09Um, maybe there's something that I'm
7:42:11missing here because it looks like I'm
7:42:14fetching I'm not fetching what I want.
7:42:17Um, I'm fetching something different.
7:42:23Okay, so let me see if I could feed
7:42:27in the right container.
7:42:37H. Basically, what we want is we just
7:42:39want the big list, right? So, how am I
7:42:42going to do
7:42:43that?
7:42:45H if omitted or set to Okay, you know
7:42:48what? Maybe maybe it's actually this.
7:42:50Maybe we go to agents um fetch
7:42:56output. Then we feed this in. Let me try
7:42:59it. Oh, sorry. I'm feeding in a
7:43:01container ID to something that wants
7:43:03something called an Asian
7:43:05ID. That's kind of killing me a little
7:43:08bit. Uh, all right. That's fine. Let's
7:43:11just kind of circle back. Um, I was
7:43:14using a post request or a get
7:43:19request. I don't remember. Let me paste
7:43:22this in
7:43:23now. Now, let me test this. Says it's a
7:43:27bad request. I need to check my
7:43:28parameters. So, why is that?
7:43:31could be that the um ID is not the ID of
7:43:36an agent. So, I'm going to go back here
7:43:37to where I define the ID of my agent and
7:43:39I'll go back here and I'll paste the ID
7:43:41of my agent
7:43:42in. And no, we do get just this weird
7:43:46output file which doesn't actually have
7:43:48anything. So, that makes me think that
7:43:50in order for me to do this, I should
7:43:52probably test with another lead. So, not
7:43:54just one lead, but two leads. So, why
7:43:56don't we just test with with another
7:43:57lead? Now, I'll go over here.
7:44:00Let me just delete
7:44:01Frank. And
7:44:03[Music]
7:44:04then actually, why don't I just test
7:44:06this on my on my real data? That'd be
7:44:09interesting. Let's go back here. And
7:44:11then instead of a limit of
7:44:13one, why don't I just do a limit of
7:44:18three. That'll allow three things to
7:44:20move, which will
7:44:22allow us to generate two more rows.
7:44:27basically those two rows should dump
7:44:31here. So just um testing all this
7:44:33iteratively right
7:44:35now. So we should have two more. Okay,
7:44:38now we do with the ice breakers, right?
7:44:40So the rest of the system works fine.
7:44:42And now we just need to send that to
7:44:43this Phantom Buster agent. Okay, so um
7:44:47let's do it. I'm going to send to Okay,
7:44:49actually this is a good opportunity for
7:44:50me to test my
7:44:51um uh my web hook, right? So, why don't
7:44:56I grab this listen for this test
7:45:00event? Then over here, I'm going to test
7:45:02sending all of these results to my web
7:45:05hook. Looks like it's already running,
7:45:08which is a problem. H, it is
7:45:12running.
7:45:15Interesting. I get it. I know why it's
7:45:17running. It's running because we're just
7:45:18doing we just sent three results over.
7:45:21We need to aggregate the results in
7:45:24between these two. So I'm going to use
7:45:25aggregate.
7:45:27Okay, I don't think I need any field
7:45:29name at all. I think I can just
7:45:30aggregate these so that these three
7:45:32items become one item. Let's see. No, I
7:45:35guess we do need a field to aggregate.
7:45:36We'll aggregate them based off of
7:45:39ID. No, I just want to aggregate all of
7:45:41them really.
7:45:43Um, let me just see if maybe there's
7:45:45another field that I need to use that's
7:45:46not
7:45:48aggregate. Um, could I just combine
7:45:50these all into one item? No, I think I
7:45:52do need to use aggregate. Just going to
7:45:53aggregate all item data into a single
7:45:55list. Put it inside of this object
7:45:56called
7:45:57data. And then from here, I'm now going
7:46:00to have one item. And then I can just
7:46:01trigger this once instead of, you know,
7:46:02however many times I've done so. All
7:46:04right. Well, I'm glad that I spotted
7:46:06that. That otherwise would have been a
7:46:07catastrophic error. Um, let's see how
7:46:10our agent's
7:46:12doing. Looks like we're processing two
7:46:14new records, which is nice. So, this
7:46:16obviously understands and is capable of
7:46:19like kind of mediating, modulating,
7:46:21whatever the hell you want to call it.
7:46:22Um, the output. Let me just make sure
7:46:25this web hook is set. Oh the web
7:46:27hook URL is not set. Oops. Save. Save.
7:46:30Save. Save and close. Yeah, this
7:46:33probably ran without that web hook URL.
7:46:35So, that that that makes sense. I'm kind
7:46:37of silly. Okay, looks like we did indeed
7:46:40finish that run. Two invitations were
7:46:42sent. I'm not getting a web hook here,
7:46:43unfortunately, which is kind of
7:46:45annoying. So, I'm just going to um leave
7:46:48that for at the end of the video when I
7:46:50do a demo. For now, I'm just going to
7:46:51pretend like I did get the web hook and
7:46:53then I'll just continue manually
7:46:54triggering the rest of this flow. So, um
7:46:57yeah, because we triggered that flow
7:46:58right at the very end there. And then if
7:47:01I go to my execution history, I should
7:47:02see a record
7:47:04of the flow at the very end where the
7:47:08error
7:47:09was. Uh I don't know why. Oh, that looks
7:47:13okay. That looks kind of weird. I don't
7:47:14remember doing that. It's probably this
7:47:15one
7:47:20here. Something is weird happening here.
7:47:23This is like mcking around with the
7:47:26Okay, that might be a bug of some kind.
7:47:28Um, anyway, I should be able to grab the
7:47:30ID of the agent,
7:47:32right? So, I should then just be able to
7:47:34feed this directly in, which is the same
7:47:36as before. We should be able to test it.
7:47:39Should be able to get the the data. But
7:47:42no, I'm not really getting the data. Not
7:47:43really wondering. I'm really wondering
7:47:45why I'm not getting the data here. Looks
7:47:46like this is
7:47:50good. I mean, I sent it out, but why are
7:47:52we sending it in this format? I don't
7:47:54want it in whatever the hell this is. I
7:47:56want in JSON, right? I'm just getting
7:47:58this all as one big text string.
7:48:02So, could I get
7:48:06this agents fetch
7:48:11output?
7:48:15Hm. Yeah, that's kind of annoying. You
7:48:17know what? We might not actually be able
7:48:18to do it. It kind of sucks. I think
7:48:21instead what we're going to have to do.
7:48:24So, we're just going to have to go like
7:48:26when it is sent, we're going to have to
7:48:28mark this as xxx basically.
7:48:31Um, yeah. I mean, there's no other way
7:48:34of doing so. I mean, it's not ideal and
7:48:35it's not technically one, but looks like
7:48:38the only alternative to that would be
7:48:39madness. we'd have to parse out all of
7:48:41those people using AI and this would not
7:48:43be
7:48:44reliable. And then um it also cost way
7:48:48too much in order to do it. So I guess
7:48:51we're going to scrap that. What we're
7:48:52going to do is we're just going to keep
7:48:53keep on with this one scenario that
7:48:55triggers the Phantom Buster agent. And
7:48:57then after the Phantom Buster agent,
7:49:01uh well, we're not even going to have a
7:49:02scent column really. It's just anybody
7:49:03that's here will obviously have just
7:49:05made it through the Phantom Buster
7:49:06agent. So that's what we're going to
7:49:07that's what we're going to say.
7:49:09And
7:49:11then yeah, the Phantom Muster agent,
7:49:13we'll just run it um every time we add
7:49:16new people to this
7:49:18list. And then I think we can also
7:49:20probably just run it once a day or
7:49:21something, once every couple of days
7:49:24because it actually automatically has
7:49:25the dduplication functionality inside of
7:49:27it, right? So yeah, I guess there's no
7:49:28real reason to have like a like a done
7:49:29column
7:49:31anyway. It's not that that was a silly
7:49:33thought. Ideally, you should track this,
7:49:35but there is there is really no need to
7:49:37split it in two, I suppose.
7:49:40because if it is on the sheet, Phantom
7:49:42Buster will automatically ddup it. And
7:49:44so we just basically anything that goes
7:49:46in the sheet will eventually be taken
7:49:47care of, I suppose. And if you want to
7:49:49see how far down you are, you just go to
7:49:52results and you basically just have a
7:49:54list of everybody that you sent to. So
7:49:57yeah, we do have that taken care of
7:49:58automatically. And as we can see, you've
7:49:59already sent some of these DMs. So I'm
7:50:01probably going to get like some actual
7:50:02connection requests from these people,
7:50:04which is nice. Looking forward to
7:50:06meeting you, Frank, Greg, and Atina. So,
7:50:08let me just think. Is there anything
7:50:09else that we need to do in order to make
7:50:10this work? I don't really think so. I
7:50:12think that's about it. Just do that with
7:50:14creative agencies. So, now we're just
7:50:16going to trigger the Phantom Buster and
7:50:17have that go. Yeah, looks pretty good.
7:50:19Awesome. You now have a LinkedIn
Deep Personalization Icebreaker Generator
7:50:21outreach system that automates
7:50:22personalized prospecting and also
7:50:23automates connection requests. You're
7:50:24already generating a steady stream of
7:50:26LinkedIn connections and conversations.
7:50:27Plus, you're selling the same system to
7:50:29others for over $2,000. We're now going
7:50:31to be building a multi-line icebreaker
7:50:33generator that uses deep website
7:50:34scraping to create extraordinarily
7:50:36personalized cold email openers. This is
7:50:38the exact system that routinely
7:50:39generates 5 to 10% reply rates and helps
7:50:41scale any agency to six figures through
7:50:43cold email. And here's what makes the
7:50:44system so valuable. Instead of sending
7:50:45generic low-v value cold emails with
7:50:48templated variables that get ignored.
7:50:49This workflow is going to scrape
7:50:50prospects websites. It's going to
7:50:52analyze their content with AI, and it's
7:50:54going to use AI and a little bit of
7:50:55prompting magic to generate a few
7:50:57multi-line icebreers that are so
7:50:58personalized that a lot of recipients
7:51:00actually think that you've spent hours
7:51:01researching them individually. The
7:51:03result is a cold email campaigns that
7:51:05actually gets responses and actually
7:51:06book meetings. By the way, if you're
7:51:08serious about turning your NAD skills
7:51:09into actual income, please do check out
7:51:11Maker School. Many of our members use
7:51:12systems exactly like this one to land
7:51:14their first $3,000 AI automation clients
7:51:16within two to three weeks of joining.
7:51:17All right, let's dive into building this
7:51:18cold email system. Again, we're going to
7:51:20turn website data into highconverting
7:51:21personalized
7:51:23outreach. To make a long story short,
7:51:25what we're going to do is we're going to
7:51:26start with an Apollo.io search. Apollo
7:51:29is just a lead aggregator and lead
7:51:30database. Fortunately, it's very
7:51:32expensive to purchase leads directly
7:51:34through Apollo. So, what most people do
7:51:35nowadays is they scrape it using a third
7:51:37party service. For that, I'm going to be
7:51:38using Ampify. And then I'm going to pump
7:51:40all of that through a pretty complicated
7:51:42N8 flow just to show you guys how at the
7:51:44end of it all we can generate
7:51:46highquality leads. So, first things
7:51:47first, let me give you guys a demo of
7:51:49the system. What I've done here is I
7:51:50built a Google sheet called multi-line
7:51:52icebreaker generator. There's a URL
7:51:54column over here on the left and a sheet
7:51:55called search URLs down at the bottom.
7:51:57Then under leads, we get a bunch of
7:51:59information. First name, last name,
7:52:00email, website, URL, headline, location,
7:52:02phone number, and multi-line icebreaker.
7:52:03This is sort of the juice. What I'm
7:52:05going to do is I'm going to feed in the
7:52:06URL to the Apollo search that I showed
7:52:08you guys a moment ago. Okay. Then I'm
7:52:10going to go and start my flow. What's
7:52:13occurring when I click test workflow is
7:52:15it's grabbing the URL that I just added.
7:52:17So that's that big long Apollo search.
7:52:19It's now scraping that Apollo list on
7:52:21Apify. What it's doing is it's spinning
7:52:23up a cloud instance of the actor. That's
7:52:25what they're called on Apify that's
7:52:27going out and it's actually getting me a
7:52:28ton of that lead data. Then we're doing
7:52:30a bunch of data processing to filter for
7:52:32only websites and emails. And then what
7:52:34we're doing is once we have all those
7:52:35websites, we're actually scraping the
7:52:36hell out of them. We're extracting the
7:52:38HTML content and then we're editing the
7:52:39fields. Now, there's a couple more steps
7:52:42here, but ultimately what ends up
7:52:43happening is we summarize the website
7:52:45pages, then feed that into AI. And the
7:52:48end result, if I go over to my leads
7:52:49page here, is as you'll see, we're
7:52:51filling in this multi-line icebreaker
7:52:53column. What this multi-line icebreaker
7:52:56is is it's a extraordinarily highquality
7:52:58personalized pitch where you add this to
7:53:01the beginning of a cold email and it's
7:53:03so customized that the person on the
7:53:05other end of the line is going to assume
7:53:06that you've actually read through all of
7:53:08their website and done a bunch of
7:53:09personal searching yourself. So this is
7:53:11the sort of thing that routinely gets me
7:53:125 to 10% reply rates on my cold email
7:53:14campaigns. And it's one of the ways that
7:53:15I scaled my own AI and automation agency
7:53:18to $72,000 per month. So So you can see,
7:53:20hey Cali, love how L2 makes it easy to
7:53:22filter by acreage. also a fan of your
7:53:24property update email option. Wanted to
7:53:25run something by you. If I was Cali and
7:53:28I received all of this is like the first
7:53:29two lines of my email. I'm obviously
7:53:31going to assume that I've done my
7:53:33research in my pitch. Okay. So, in a
7:53:35nutshell, what we do from here is we
7:53:36just take this data and we feed it into
7:53:38a campaign like on instantly. Instantly
7:53:41is a cold email service, one that I
7:53:42personally use for most of my emailing.
7:53:44What we'll do then if I go to campaigns
7:53:46here, you can see an example one that I
7:53:47set up for website agencies is we pump
7:53:49it directly into a sequence and our end
7:53:52email will look something like this. So
7:53:54in this case, this is for a website
7:53:55design agency. Hey Katie, love KT also
7:53:57graphics. I wanted to run something by
7:53:58you. I'm new to this so please bear with
7:54:00me but insert customized information or
7:54:02icebreaker over here. And this specific
7:54:04pitch has already got me a 4% reply rate
7:54:06and something like over 30 qualified
7:54:08leads that have wanted to book calls or
7:54:10meetings with me. I show you guys all
7:54:11this back end just to make it abundantly
7:54:13clear that the actual work that goes
7:54:14into building out a cold email campaign.
7:54:16If you really want it to crush, it's a
7:54:17little bit more complicated than just
7:54:18scraping a bunch of leads off Apollo and
7:54:20then sending. You know, a lot of the
7:54:21time you need some sort of way to
7:54:22paraphrase or make the content that you
7:54:25are sending to people seem a lot more
7:54:27customized. So that's in a nutshell how
7:54:29the system works. I'm going to do now is
7:54:30I'm going to build it for
7:54:33you. Okay. So I'm going to open up a new
7:54:35NAND panel over here and I'm going to
7:54:37call this deep multi-line icebreaker. We
7:54:39got our canvas right over here. First
7:54:41thing I'm going to do is I'm just going
7:54:42to do a manual trigger. This is just the
7:54:43simplest and easiest thing for me to do
7:54:45and I do it for all of the flows that
7:54:47I'm testing. I'm then going to head over
7:54:48to Google Sheets. What I'm going to want
7:54:50is I'm going to want a get rows in
7:54:52sheet. What we're going to do is we're
7:54:53going to hook this up to that multi-line
7:54:54icebreaker generator Google sheet. And
7:54:56so in order to do that, you need first
7:54:57to add credentials. I've already added
7:54:59credentials, but if you haven't done so,
7:55:00all you need to do is click on that
7:55:02little pen icon and then click sign in
7:55:04with Google. From there, what I'm going
7:55:05to do is I'm going to find the specific
7:55:06document that I'm looking for. So that's
7:55:08multi-line icebreaker generator. Then I
7:55:10also need to select not just the
7:55:11document but the sheet as well. You guys
7:55:13notice either search URLs and leads.
7:55:15What that is is that's this tab or this
7:55:16tab. So what I want to do is I want to
7:55:18grab this search URL and actually not
7:55:19just this one but any search URL that I
7:55:21list just so that I can also scale this
7:55:22up. What I'm going to do is I'm going to
7:55:24head over search URLs. Then once I have
7:55:26all of that in, if I just click test
7:55:27step, what this will do is it'll
7:55:28actually grab me the URL as well as the
7:55:31row number which is handy. In N8 I
7:55:33always pin my data. This just allows me
7:55:34to test my flows a lot faster because I
7:55:36don't have to rerun things and it also
7:55:38spares me some API usage. The Google
7:55:40Sheets API is notoriously low rate limit
7:55:42which can be annoying. Okay, so from
7:55:44there we now have the search. What I
7:55:45need to do next is I need to call my
7:55:47scraping service. And what I'm going to
7:55:48call in this video is Appify. So I've
7:55:50already preconfigured this Appify
7:55:52scraper module here. And I'm doing it
7:55:54because if you want to converse with the
7:55:55Appify API, you do have to know a little
7:55:57bit about how it works. But to make a
7:55:59long story short, what we're doing is
7:56:00I'm sending a post request to a URL. The
7:56:03URL looks like this. Okay. And if I make
7:56:06this bigger, you guys will see it. It's
7:56:08https back/appi.appify.com/v2x
7:56:14um
7:56:18colactor-id-sync-gets. Now, you may be
7:56:19wondering, Nick, where the hell did you
7:56:20get this? Well, if I just look up Apify
7:56:24API, this is the backend for the service
7:56:26that I'm using. If I scroll down to this
7:56:29right over here, this exact same URL. So
7:56:32you guys could see and this gives you
7:56:34all the specs on how to use this
7:56:35specific API endpoint. But to make a
7:56:37long story short, what I did was I
7:56:38copied in this curl request. I made a
7:56:40couple of changes and then I ended up
7:56:42with this here. I imported my curl. So
7:56:45API requests are sort of beyond the
7:56:46scope of this video, but basically you
7:56:48have to put an accept application JSON
7:56:49header and authorization bearer and then
7:56:51apply API token. If you guys like this
7:56:53sort of stuff, I've recorded a lot of
7:56:55detailed documentation walkthroughs and
7:56:57how to actually like practically read
7:56:59APIs for beginners. So, I'll link that
7:57:01video above. Okay. What this is going to
7:57:03be doing is this is going to be running
7:57:04our search. So, if I click test step
7:57:06over here, this is going to do now is
7:57:08it's actually going to push this to
7:57:09ampify. And the way that you check this
7:57:12out in Apify is you have to go to their
7:57:13console. But if I go to runs, you
7:57:16actually see there's a live run that is
7:57:17currently now happening because I've
7:57:19sent this request. Now, I should be
7:57:21getting something like 100 or I guess 96
7:57:23leads. You can see here I demoed this a
7:57:24couple of times. And once we're done,
7:57:26what we get is we get a bunch of first
7:57:28names, last names, email addresses,
7:57:30LinkedIn URLs, and so on and so on and
7:57:32so forth. Pretty cool, huh? Now, in
7:57:34addition, we also get a ton of other
7:57:35fields here, which I'm not going to go
7:57:36through all of them because there are
7:57:37quite a lot, but that includes stuff
7:57:38like the organization name, the URL of
7:57:41their websites, and so on and so forth.
7:57:42And what we want to do here is we want
7:57:44to take the URL of the websites. First,
7:57:45we need to verify that they have a URL,
7:57:47and we also need to verify that they
7:57:48have an email. But once we've done that,
7:57:50we want to take the website URL that
7:57:51we're generating and then we want to
7:57:53pump it through some sort of scraper and
7:57:54then we want to throw it into AI to have
7:57:56it tell us something about it. Okay. So
7:57:57the next thing I'm going to do is I'll
7:57:58go over here and I'll pick the filter
7:58:00node. What the filter node allows us to
7:58:02do is allows us to look specifically to
7:58:04see if we have an email address present.
7:58:06So if I just go command F email, you'll
7:58:08see that some of these fields are null.
7:58:10So what I want to do is I want to check
7:58:11to see whether or not an email exists.
7:58:14Okay, if the email exists, then I'll
7:58:15continue. If not, I won't. In addition,
7:58:18I also want to check and whether or not
7:58:20the website URL exists. So I I'm just
7:58:23searching for website URL. I'm going to
7:58:24stick that here and I'll say this has to
7:58:27exist. Now in this case, it's not
7:58:29existing because this particular example
7:58:30just does not include a website URL.
7:58:32What I'm going to do is I'm just going
7:58:33to click test step now. Carry the data
7:58:35forward and we're going to see what sort
7:58:36of output we got. If we feed in 96
7:58:38items, we keep 28 items. That means that
7:58:41of the 96, we are filtering out 68. And
7:58:44that's okay for us. That's just how
7:58:45Apollo works. You're going to feed in,
7:58:47you know, about 100 or so and you're
7:58:48going to get about 30. Just math. From
7:58:49here on, what we're going to do is we're
7:58:51actually going to feed this into an HTTP
7:58:53request node. Now, the reason why I'm
7:58:54doing this is I basically want to feed
7:58:55that website in that I got a moment ago
7:58:57directly into an HTTP request node. I
7:58:59want to make a request to this website.
7:59:01I want to search for it. In order for
7:59:02this to work though, what we're going to
7:59:03have to do is we're going to have to add
7:59:04redirects and then click follow
7:59:06redirects with max redirects of 21. If
7:59:08you don't do this, I find that uh in
7:59:10practice, a lot of the websites are
7:59:11going to error out because most of them
7:59:13redirect. If I click test step, what
7:59:15we're doing now is we're actually
7:59:15scraping this web page right here,
7:59:19assetrealtyindia.com. In addition, what
7:59:20we're going to need to do is add one
7:59:21other option here. And that is we'll go
7:59:23to settings over here. And then on
7:59:25error, what I want to do is I want to
7:59:27continue using the error output.
7:59:29Basically, I just want this to continue
7:59:30executing even if there is an error. And
7:59:32if there is an error, we're just going
7:59:33to do nothing. And the reason why is
7:59:34because not all websites scrapes work.
7:59:36Some websites have protections built in
7:59:37that stop us from being able to do this
7:59:39easily. So realistically, if we feed in,
7:59:41I don't know, like 28 or 30, we'll
7:59:42probably get like 15 or 20 websites that
7:59:44are actually able to be scraped. And it
7:59:46looks like we did. We have 21 items that
7:59:48successfully worked and then seven that
7:59:50didn't. Now, when you add those error
7:59:51branches, you're going to get a success
7:59:53and an error branch. You know, I'm just
7:59:54going to do nothing with the error, but
7:59:55you can certainly do things with the air
7:59:57if you wanted to recoup your costs. In
7:59:58my case, I usually do these things
8:00:00pretty quick and scrappy, so I don't
8:00:01really worry about doing that recouping.
8:00:02For me, if I could do this for 20 out of
8:00:04100 leads fed in, well, in Apollo, I'm
8:00:06just going to make sure that my audience
8:00:07size is really big, like 10,000.
8:00:09Therefore, I'm going to get about 2,000
8:00:11of those. So, that's okay for me. After
8:00:12that, what we need to do is we actually
8:00:13need to scrape this data or uh rather
8:00:16extract links from this data. If I click
8:00:20on show data over here, what you'll see
8:00:23is we're getting a ton of HTML. Do you
8:00:24guys see this? In this case, this is a
8:00:27WordPress website, but what we want is
8:00:29we just want to extract all the links on
8:00:30this website. So what we want is we
8:00:32basically want a tags with this href
8:00:35equals to. So you see this this is
8:00:38actually a link on the page. In this
8:00:40case, this is kind of an empty link. But
8:00:41if I keep on searching this, we should
8:00:42get
8:00:43stuff. Okay, see this
8:00:47hath.com/authoradmin. Well, that
8:00:48actually is going to take me to a blog
8:00:49page on the website that might actually
8:00:51be pretty important for me to customize.
8:00:53This is a contact page. It might be
8:00:54important for us. Basically, what I'm
8:00:56going to do is I'm just going to extract
8:00:57all of these links. And the way you do
8:00:58this in NAND in a really simple and easy
8:01:00way. So we go to success. Just go HTML
8:01:02extractor here. Now what we need to do
8:01:05is we need to stick the links that we're
8:01:07finding into a key. I'm just going to
8:01:08use the term links. The CSS selector is
8:01:10going to be a the value we're going to
8:01:12return is going to be an attribute. And
8:01:14in my case, I'll just go href. I'm going
8:01:15to return an array and then under
8:01:17options, I'll trim values and I'm going
8:01:18to clean up the text. What this does, to
8:01:20make a long story short, is it just
8:01:22gives us a nicely formatted list of
8:01:24links from the HTML that we're feeding
8:01:25in. So the links are going to look
8:01:27something like this. What we've done now
8:01:29is we've pushed in a homepage to the
8:01:31HTTP request node. And then what it's
8:01:33doing is it's outputting us all of the
8:01:34links on that page. Now, why would we
8:01:37want to do this? Well, logically, the
8:01:38reason why is because if you really
8:01:39wanted to understand a website deeply,
8:01:41you wouldn't just scrape one page like
8:01:42most other people are doing. You'd
8:01:44actually scrape all the pages on the
8:01:45website and then you'd feed it into some
8:01:46sort of intelligence, in our case AI, to
8:01:48have it tell us something about each
8:01:49page before combining all of that into
8:01:51some big summary, using that to generate
8:01:53some sort of custom asset. Next up, what
8:01:54I'm going to do is I'm just going to
8:01:55rearrange all of this data. If we go to
8:01:57this HTML tag now, what we have is we
8:01:58have 21 items. Every one of these items
8:02:00is a big array of links. Now, this is a
8:02:03ton of information, but if you think
8:02:04about it, we also want to make sure that
8:02:06we're grabbing the lead data, too. Like,
8:02:08we want to make sure we get Joshua's
8:02:09information, for instance, here. So,
8:02:11what I'm going to do here is I'm just
8:02:12going to clean this up by adding an edit
8:02:13fields node right over here. Now, what
8:02:15edit fields node does is it basically
8:02:18allows us to add fields and then rename
8:02:20them according to some spec. So if I
8:02:21drag this first name here and then if I
8:02:23do the last name and so on and so forth,
8:02:26then what I'm going to do is I'm just
8:02:28going to output a much simpler version
8:02:29of all this data. I'm basically going to
8:02:31remove all the fields that I don't find
8:02:32important. Now in our case, we're
8:02:33getting a ton of these does not exist or
8:02:35unpin node HTML and execute. So because
8:02:38nadn isn't sure of exactly which record
8:02:41means which thing, what we need to do is
8:02:43we need to unpin them all. And now we
8:02:44need to test this. What it's going to do
8:02:46is it's going to run through that Google
8:02:47sheet again. It's going to grab the
8:02:49Apollo URL. It's then going to feed that
8:02:51into our Apify scraper over here. After
8:02:54it outputs, I think it was 96 or 98
8:02:56items or something. We're then going to
8:02:57filter out a lot of them. It's going to
8:02:58bring us down to I think like 28. It's
8:03:00going to filter us down to I think like
8:03:0121 or something. Then out of the 21,
8:03:03we're going to extract all the HTML
8:03:05content. Then finally, we're going to be
8:03:06left with 21 nicely formatted items. And
8:03:09if you are curious what these look like,
8:03:11it looks like this. We have first name,
8:03:13last name, website, headline if they
8:03:14have a headline, location, phone number.
8:03:16In this case, this is empty. And then
8:03:17just a big list of links. Okay. From
8:03:19here, if you think about it, what we
8:03:20need to do is we need to find a way to
8:03:22iterate over this list of links because
8:03:23we have technically what like 22 items
8:03:26here. But basically what I want to do is
8:03:28I want to process David first and then
8:03:29after I'm done processing David, process
8:03:31Zayn. And after I'm done processing
8:03:32Zayn, process Michael. And the best way
8:03:34to do that in NAD is using what's called
8:03:36a loop over items or split in batches
8:03:38node. This can be pretty intimidating
8:03:40and annoying to deal with if you haven't
8:03:42ever run one of these before, but I'm
8:03:43just going to delete the replace me node
8:03:45and run you guys through how this works.
8:03:46Basically, there are two routes here.
8:03:48There's a done route and then there's a
8:03:49loop route. What the loop route does is
8:03:51anything that you put in here will
8:03:52basically proceed until you connect the
8:03:56loop route back to the input. So
8:03:58basically for every one of these 21
8:04:00items, we're going to do something. If
8:04:02you think about it logically, what do we
8:04:03want to do? Well, we want to go into
8:04:04these 21 items and then we just want to
8:04:06take all these links and we want to do
8:04:07some processing on these links.
8:04:08Basically, we want to like run HTTP
8:04:09requests for each, right? So that's what
8:04:11we're going to I'm going to go to loop
8:04:12and then I'm just going to type in well
8:04:14first of all if you think about it these
8:04:16right now are all buried inside of an
8:04:17array right so we have to expand these
8:04:19or split these away from the array. So
8:04:21what I'm going to do is I'll go split
8:04:22out and I'm going to feed in the loop
8:04:24directly into the input and I'm just
8:04:25going to put this down here a little
8:04:26lower so it's nicer. Now unfortunately
8:04:28we can't see previous nodes because
8:04:30that's just how the split in loop node
8:04:31works. Um the fields from the left that
8:04:33I want to split out are called links. So
8:04:35that's just what I'm going to use. And
8:04:36then this done route this is going to
8:04:38trigger after we're done our loop. Okay.
8:04:40So, for now, I'm just going to loop this
8:04:41back in. Just make this super simple.
8:04:43Show you guys what this looks like. And
8:04:45just to make my life a little bit
8:04:46easier, I'm just going to go through and
8:04:46I'm actually going to pin all the rest
8:04:48of these outputs. Okay? That way when I
8:04:50start, it's just going to run
8:04:52immediately over to the loop over items
8:04:53and then just split out all of these.
8:04:55And you'll see what I mean by uh
8:04:56splitting them. Okay? So, we just fed in
8:04:5821 items. Okay? And now for every one of
8:05:00those items, I want to show you guys
8:05:02what the links look like. Just go down
8:05:04to number one. Notice how now what we're
8:05:06doing is for every run, okay? For all
8:05:0821, we're outputting a massive list of
8:05:10links. So this massive list of links,
8:05:11which is pretty long, I think it's 30
8:05:13something. This is for run one. This
8:05:15massive list of links is for run two.
8:05:17This massive list of links is for run
8:05:19three. This massive list of links is for
8:05:21run four. So basically, each of these
8:05:22runs are just a different person and
8:05:24their website. Okay. So now, what do you
8:05:26think we're going to do? Well, for each
8:05:27person and their website, what we're
8:05:29going to want to do is we're going to
8:05:30want to process these links a little. I
8:05:31mean, like, check this out. This stuff
8:05:33is crazy. Most of these are basically
8:05:34exact duplicates for Christ's sake.
8:05:36Also, these are um absolute URLs, not
8:05:38relative URLs. What we want to make a
8:05:40long story short is we want a bunch of
8:05:41links that look like this.
8:05:42Home-valuation
8:05:44y-list-with- us communities leewood real
8:05:47estate. Stuff like this just makes it a
8:05:48lot easier to process using HTTP
8:05:50requests later. So, we're going to have
8:05:51a bunch of relative links. And then
8:05:53we're going to add the initial website
8:05:55URL. So, then in this case, it' be troy
8:05:57homes
8:06:00sky-lists-with-. So, I'm going to go
8:06:02over here and I'm going to click add
8:06:03filter. And what I'm going to do, okay,
8:06:05it's unfortunate we we don't have access
8:06:07to that data, but what I'm going to do
8:06:08is I'm just going to make sure that the
8:06:10string starts with an a slash. Okay, and
8:06:14the way that this data is being output,
8:06:16it is being output under links. So I
8:06:19actually know how to reference this. I'm
8:06:20just going to go
8:06:23expression. I'm going to go dollar sign
8:06:27JSON. Okay. Now, if I take this, I pin
8:06:32this and I test this. Okay. And so, what
8:06:35ended up happening is we fed in 270
8:06:37items here. We looped over all of these
8:06:39links. Then, for all of them, we
8:06:41filtered them out and we ended up with
8:06:42just 121 items. Okay. So, basically what
8:06:46we did is we just discarded a bunch of
8:06:47the links that, you know, didn't have
8:06:48anything. So, these, for instance, are
8:06:50all absolute URLs. We just wanted all
8:06:52the relative ones in the website. Is
8:06:54this the perfect and best way to do it?
8:06:55No, not really. Like, theoretically, we
8:06:56could extract these. I'm just not doing
8:06:58it because I'm a little lazy and I find
8:07:00that most websites just have relative
8:07:02links to begin with. In reality, we
8:07:04don't actually scrape every page on
8:07:05every website. That just be a ton more
8:07:07work than is necessary, especially for
8:07:08those really heavy SEO pages. So, I'm
8:07:10just going to go with like my proxy.
8:07:12Proxy just means like my thing that's
8:07:14close to the right answer, which is
8:07:16just, hey, you know, if a website has
8:07:17any relative links on it, that's what
8:07:18we're going to scrape. Sure, some
8:07:19websites aren't going to have relative
8:07:20links on it, and you can totally adjust
8:07:22the logic to fix that on your own end if
8:07:24you'd like. Okay, one thing I'm noticing
8:07:25now is there's a bunch of duplicates.
8:07:26So, I'm just going to go to remove
8:07:28duplicates. I'll go remove items
8:07:29repeated within current input. Okay,
8:07:31this is going to immediately remove all
8:07:33of the duplicates in the flow. Now, I
8:07:34know how this works. I'm pretty
8:07:35confident it's good. So, I'm just going
8:07:36to move forward. And now, to be honest,
8:07:38we're basically ready to do our HTTP
8:07:40request. So, for all of those that are
8:07:42remaining, what I'm going to do is I'm
8:07:43going to get the URL. Now, I know what
8:07:46this expression already looks like. It's
8:07:48going to be loop over items item.json
8:07:49website URL and then JSON.links. What
8:07:52this is going to do is this is basically
8:07:53going to concatenate the website URL
8:07:56with the relative URLs that I'm pulling
8:07:57here. So for instance, if my website was
8:08:00leftclick.ai, this would be the base URL
8:08:03and then this would be the relative URL.
8:08:05That's what I'm doing right over here.
8:08:06I'm just concatenating. I'm just
8:08:07sticking them together just because
8:08:09sometimes there are redirects. I'll go
8:08:11down to redirects as well. And now what
8:08:12I'm going to do is I'm just going to
8:08:13test it on all of these links. Okay,
8:08:15it's going to be a lot of HTTP requests,
8:08:16but it's important that we give this a
8:08:18try. Okay, and what we ended up with was
8:08:2039 items. So I scraped 39 pages here and
8:08:24the result of these 39 pages are all
8:08:26HTML. What I want to do is I want to
8:08:28convert this into like some sort of
8:08:29language that I understand. And the
8:08:30simplest and best way to do that is
8:08:32using an HTML to markdown node. So I'm
8:08:33just going to drag in HTML. It's going
8:08:35to get the HTML data inside of this
8:08:37node. And then uh yeah, to make a long
8:08:40story short, this is just going to
8:08:40convert this into some sort of workable
8:08:42text that I can actually use. After
8:08:45that, we now have a bunch of markdown
8:08:47data. If you've never seen markdown
8:08:48data, it's pretty straightforward. Just
8:08:50scrolling through here, what we end up
8:08:51with is we end up with just a bunch of
8:08:53links again and then just a bunch of
8:08:54plain text. So this just basically makes
8:08:56the token cost a little bit lower. For
8:08:58those of you that don't know how HTML
8:08:59works, it usually I mean it looks kind
8:09:01of like this, right? So to write the
8:09:02word renter experience, you can't just
8:09:03write renter experience. You need to go
8:09:05less than symbol title greater than
8:09:06symbol renter space experience less than
8:09:08symbol/title greater than experience uh
8:09:10greater than symbol. This is just way
8:09:12more to uh tokens than you need. And
8:09:14since we're about to feed all this stuff
8:09:15in AI, we want to minimize the token
8:09:17cost wherever possible. And next up,
8:09:18what we have to do is we just have to
8:09:19feed this into AI. So you do so by going
8:09:21to open AI and then click messaging a
8:09:23model. I've actually already created
8:09:24this message node. So I'm just going to
8:09:26paste it in here just to make our lives
8:09:27a little bit easier. But if I feed this
8:09:30in, I'll run you guys through what this
8:09:32is doing. First of all, we need to
8:09:34connect our credential. So I connected
8:09:35to one. If you haven't done this
8:09:36already, just head over here and get
8:09:37your API key from OpenAI. It'll actually
8:09:40walk you through all of this stuff. Um,
8:09:41it's very straightforward, luckily.
8:09:43Although if you are at the beginning or
8:09:45a rate limit, just note that this may
8:09:46actually push you over the rate limit
8:09:48just because we're going to be sending a
8:09:49lot of requests very quickly. The model
8:09:50I'm going to be using is GPT4.1. The
8:09:53first prompt I'm going to use is a
8:09:54system prompt that says you're a helpful
8:09:55intelligent website scraping assistant.
8:09:57And then over here is the actual prompt.
8:09:59Okay. And this is kind of like where the
8:10:00AI magic comes in. So you're provided a
8:10:03markdown scrape of a website page. Your
8:10:05task is to provide a two paragraph
8:10:06abstract of what this page is about.
8:10:08Return in this JSON format. Abstract.
8:10:10Your abstract goes here. Rules. Your
8:10:12extract should be comprehensive, similar
8:10:14level of details and abstract to a
8:10:16published paper. That's very important.
8:10:17Use a straightforward spartan tone of
8:10:19voice. And if it's empty, just say no
8:10:20content. This is necessary because some
8:10:23of these scrapes that we're going to do
8:10:24are going to turn up empty. And we just
8:10:25want a simple and easy way to handle
8:10:27them. Okay. So, from there, what we're
8:10:29going to do is we're going to feed in
8:10:30all of this directly into AI and just
8:10:32have it tell us something about it. It
8:10:34doesn't have to be super complicated, as
8:10:35I'm hopefully you guys can tell. All we
8:10:37need to do is just ask it to do this for
8:10:39us. And what I'm going to do here,
8:10:42sorry, I just I I ran this one
8:10:43individually. Give this a click. What we
8:10:45see is we get an output that looks like
8:10:47this. This web page serves as a contact
8:10:49page for Hayan Company, Inc., a real
8:10:51estate firm located in Overland Park,
8:10:52Kansas. It provides organizational
8:10:54contact information, including the
8:10:55physical address, commercial phone, and
8:10:56facts numbers, and a link to the
8:10:57company's website. It also invites users
8:10:59to reach out with assistance. So, this
8:11:00just basically gives us some context
8:11:02about what that specific page is. And
8:11:03since we're going to be doing this for
8:11:04all of the pages, you know, I'm sure you
8:11:06guys could tell, we're going to rack up
8:11:07a ton of data. What we need to do now is
8:11:09we need a simple and easy way to get all
8:11:10the data. It's funny cuz I'm saying data
8:11:12and data different like every time I do
8:11:14it. Um anyway, what I'm going to do here
8:11:17is I'm going to get the data and then
8:11:19I'm going to aggregate it into an array
8:11:21and then I'm just going to feed all of
8:11:22that aggregated array into another AI
8:11:24module that says, "Hey, here is a ton of
8:11:26information about a website. What I want
8:11:27you to do is I want you to customize a
8:11:28piece of outreach based off that." So
8:11:30the simplest way to do that here is to
8:11:31go aggregate. And what you're going to
8:11:32want to do is the specific field that
8:11:35you're going to aggregate is going to be
8:11:36this abstract. So I'm just going to grab
8:11:38the input field name here. I'm not going
8:11:39to rename the field. That's okay. Okay.
8:11:41And now I'm just going to run this end
8:11:42to end from left to right. Make sure
8:11:44that I have all the data laid out not
8:11:46with pinned nodes if that makes sense.
8:11:48Because if you pin all the nodes and
8:11:49only test off of pin nodes sometimes and
8:11:51it bugs out just because you are
8:11:53sometimes expecting more or fewer
8:11:55records than a later node actually gets.
8:11:58So we're just going to run this end to
8:12:00end now on new data. Give that a try.
8:12:04Colonify scraper over here. Okay, we now
8:12:06have a bunch of items. We're then doing
8:12:08tons of HTTP requests. So, you can see
8:12:10we've gotten a slightly different number
8:12:12of items here. Okay, and it's running
8:12:15and it's just kind of doubling up. What
8:12:17I did is I connected the end to the
8:12:18beginning here. I'm just looping over
8:12:21and as you can see, the summarized
8:12:22website page is taking a little bit
8:12:23longer because it's probably a pretty
8:12:25long page. Okay, and it looks like this
8:12:27is hanging. And I think the reason why
8:12:29is because what we're doing is we're
8:12:30feeding in just a boatload of tokens. It
8:12:33looks like some of the website scrapes
8:12:34just a lot longer than I was
8:12:36anticipating. So, what I'm going to do
8:12:37is I'm actually going to check to see
8:12:41the length of the data here is okay.
8:12:45This is 18,000 characters to
8:12:47tokens. One token is around four
8:12:49characters. So, 18 898 divided by four.
8:12:52That's quite a few words, right? Why
8:12:54don't I cap this out at 10,000? Let's
8:12:58say then if it's greater than 10,000
8:13:02then I want to do JSON. Sorry, let me go
8:13:05to the expression field to make it
8:13:06easier for you
8:13:07guys. Then if not, I want to do
8:13:12this. Well, slice it from 0 to
8:13:1610,000. All right, that should be good.
8:13:18And now we're always going to be working
8:13:20with reasonably simple and small data.
8:13:23Let's actually do this even less. Let's
8:13:24just go like 5,000.
8:13:27We don't need much more than that
8:13:29realistically. Okay, let's just touch
8:13:31that formula up. I just added length
8:13:33there by accident. Now let's run this
8:13:36one more time. Okay, and then if we
8:13:38click on this little aggregate button
8:13:39here, what we see is we have multiple
8:13:41runs. And every time that there are
8:13:43multiple links, what we do is we
8:13:44actually aggregate them together. Now,
8:13:46in this case, we haven't actually
8:13:47aggregated any because it looks like the
8:13:48first two people that have run through
8:13:50the system are both working for Hath and
8:13:51Company Incorporated, which is just like
8:13:53the, you know, obviously there's like
8:13:55the same number of like links for each,
8:13:57right? This one did though. Notice how
8:14:00we had one page here, another page over
8:14:02here, another page over here, another
8:14:04page over here. And what it did is it
8:14:06just aggregated all of those fields
8:14:07together. In this case, it's pretty
8:14:08long, right? It's 23. That's why it took
8:14:09so long for us to finish. But anyway,
8:14:11what I'm trying to say is now that we've
8:14:12aggregated all the data, what we have to
8:14:13do next, we we kind of have to pass that
8:14:15through another AI node, right? What I'm
8:14:17going to do is I'm going to feed this
8:14:19through a second one here called
8:14:21generate multi-line icebreaker where now
8:14:24what we're going to do is we're going to
8:14:24feed in all these independent website
8:14:26summaries into said multi-line
8:14:28icebreaker. Okay. Going to give this a
8:14:30double click now. And the way that this
8:14:31is set up is the same as before up here.
8:14:34And the text is we just scraped a series
8:14:36of web pages for a business called Oh,
8:14:37sorry about that. We don't actually have
8:14:39the text on the
8:14:40business. Your task is to take their
8:14:42summaries, turn them into catchy
8:14:43personalized openers for a cold email
8:14:44campaign to imply that the rest of the
8:14:46campaign is personalized. We actually
8:14:47just tell it what we want and return
8:14:48your icebreers in the following JSON
8:14:49format. Now, what I've done is I've
8:14:51actually written out a custom icebreaker
8:14:52that I know works pretty well. Hey, name
8:14:55love thing also doing/like/ a fan of
8:14:58other thing. Wanted to run something by
8:14:59you. I hope you'll forgive me, but I
8:15:01creeped you and your site quite a bit
8:15:02and I know that another thing is
8:15:03important to you guys or at least I'm
8:15:04assuming this given the focus on fourth
8:15:06thing. I put something together a few
8:15:08months ago that I think could help. To
8:15:09make a long story short, it's insert
8:15:11thing you're selling over here. Okay.
8:15:13And I think it's in line with some
8:15:14implied belief they have. I guess the
8:15:16point I'm making, and you guys can do
8:15:17this however the heck you want, but I
8:15:18just have AI like kind of fill in the
8:15:20blanks for me, but I don't do it like
8:15:22with simple templated variables. What I
8:15:24do is I will make it flexible. Like I'll
8:15:27use a variable and I'll like tell AI,
8:15:28hey, fill this in with something, right?
8:15:30Where thing is the thing that I wanted
8:15:31to fill in. This is in contrast to like
8:15:33using actual variables which are
8:15:35procedural and always fixed. If you tell
8:15:37AI like, "Hey, I want you to write this
8:15:38casually in short form." What it can do
8:15:40is it can paraphrase those things and
8:15:41then it seems a lot more like realistic
8:15:43to a customer which I find. So use
8:15:45whatever the heck you want here. This is
8:15:46just my template. Then I have a ton of
8:15:47rules. Write in a Spartan lonic tone of
8:15:49voice. Make sure to use the above format
8:15:50when constructing your icebreers. You
8:15:51write out this way on purpose. Shorten
8:15:53the company name wherever possible to
8:15:54say XYZ instead of XYZ agency. Love AMS
8:15:57instead of love AMS professional
8:15:59services. Love Mayo instead of Love Mayo
8:16:00Inc. Do the same with locations. Then f
8:16:03for variables focus on small non-obvious
8:16:05things to paraphrase. The idea is to
8:16:06make people think we really dove deep
8:16:08into their website. So don't use
8:16:09something obvious. Do not say cookie
8:16:10cutter stuff like love your website or
8:16:12love your take on marketing. So all of
8:16:14these things are important. This here
8:16:15just makes it seem more humanwritten
8:16:17because humans tend not to write the
8:16:18whole company name. If you write the
8:16:20whole company name, if you say hello, I
8:16:21love Mayo Incorporated. Odds are you
8:16:24scrape Mayo Incorporated somewhere from
8:16:26the internet. you do, hey, love San
8:16:28Fran, then odds are you did not scrape
8:16:30San Francisco somewhere from the
8:16:32internet. Odds are if you say for your
8:16:34variables, focus on small non-obvious
8:16:35things to paraphrase, then you did not,
8:16:37you know, do all of that stuff. I guess
8:16:38all of this stuff just makes it seem a
8:16:40little bit more human written. Then what
8:16:41I do is I give it some examples of
8:16:43profiles and then websites. Okay, so
8:16:45what I did is I basically ran this exact
8:16:46same flow on a couple of test demo
8:16:49websites. Then I got the profile and
8:16:50then I got a bunch of different website
8:16:52scrapes. Okay, so exact same thing here.
8:16:53I'm just feeding this in as like an
8:16:55example.
8:16:56Then I basically instead of me just
8:16:58telling it what I wanted to do, I fed it
8:17:00an example of the perfect outline for an
8:17:03icebreaker. And then what I'm doing now
8:17:05at the end is I'm actually feeding it on
8:17:06real data. Okay. So just to make a long
8:17:08story short, I'm doing a system prompt
8:17:10first, then a user prompt where I give
8:17:12it instructions, then a user prompt
8:17:14where I give it an example of an input,
8:17:16then an assistant prompt where I give it
8:17:18an example of an output, then finally I
8:17:20give it the actual user prompt with the
8:17:21actual input and output. Once this is
8:17:24generated, if you think about it, our
8:17:25job here is basically done. All we need
8:17:26to do now is we just need to update or
8:17:28add a section to the Google sheet that
8:17:30we had before. So, I'm just going to
8:17:31delete all of these. Go to Google Sheets
8:17:32first, then click append row. Mixing up
8:17:36my platforms here. Just going to use the
8:17:38YouTube credential. What I want is I
8:17:40want to select the document obviously.
8:17:41So, multi-line icebreaker generator. The
8:17:43sheet I'm going to be pulling data from
8:17:44is or I'm adding data to is going to be
8:17:46leads. Then, what I'm going to have to
8:17:48do is I'm going to have to map all these
8:17:48fields. And I can't actually hold this
8:17:50data yet. So, I'm just going to give it
8:17:51a quick run and then do it in a second.
8:17:52Okay. From here, what I've done is I've
8:17:54now mapped all the correct fields. So,
8:17:56the first name field is going to fill in
8:17:59this column. The last name field is
8:18:02going to fill in this column. The email
8:18:04field is going to fill in this column.
8:18:06Website, headline, location, phone
8:18:08number, and then multi-line icebreaker.
8:18:09Okay, this icebreaker is the new field
8:18:12that I can't access. So, we are now just
8:18:14going to give it a run. And because I
8:18:16need to loop this, obviously I have to
8:18:17grab the output of this and move this
8:18:18all the way here to the input of the
8:18:19loop. And then when it's done, I don't
8:18:21need to do anything. Okay, so let's give
8:18:23this a try now on some real live data.
8:18:25I'm going to click test workflow. First
8:18:26thing it's going to do is it's going to
8:18:27split it all out like we did before.
8:18:30Then it's going to filter it out, remove
8:18:31all the duplicates, and then start my
8:18:33HTTP requests, format it as markdown,
8:18:36summarize individual pages, aggregate
8:18:38all those individual pages into one
8:18:39array, feed that whole array into the
8:18:41multi-line icebreaker, then it'll add
8:18:42the row, and then it's just going to
8:18:44proceed line by line by line, and do the
8:18:46same thing. Now, the first two leads in
8:18:48this list were obviously um the same
8:18:49company, Hen Co., You know, you can
8:18:51filter out duplicates in the company
8:18:53website if you want. Didn't do that in
8:18:54this case because I actually think that
8:18:55it makes sense to pitch two people on an
8:18:57individual business. A cool thing there
8:18:59that you could do, which I'm not doing
8:19:00here, is you could also reference like,
8:19:01"Hey, David, I just reached out to Zayn
8:19:03and I wanted to follow up with you as
8:19:04well." If you do stuff like that, people
8:19:06are a lot more likely to believe that
8:19:07you are a real human being do this
8:19:09outreach, not some automated super cool
8:19:11robot. Okay, looks like we just added
8:19:13another one that says, "Love how you got
8:19:14the Casey trusted partners list dialed
8:19:16in. Also a fan of that local lender
8:19:18vetting approach." Very
8:19:20nice. We're just about wrapping up our
8:19:22test set
8:19:23here. Okay, so hopefully you guys
8:19:26appreciated seeing me put that system
8:19:27together in real time. I hope it's
8:19:29abundantly clear, but that system is
8:19:30just like a nugget. It's a stem. You can
8:19:32add onto that system, make it
8:19:33arbitrarily complicated if you want. I
8:19:35use some very simple filtering logic
8:19:37here because I just wanted to let you
8:19:38guys do whatever the heck you wanted
8:19:39with it. I also just tend to be kind of
8:19:41hacky in the way that I put things
8:19:42together. So, I will focus on the 80/20
8:19:44thing that does 80% of what I want, even
8:19:46if it's a little less cost-effective or
8:19:48even if I end up wasting some of the
8:19:49leads. To me, the leads are never the
8:19:51bottleneck here, just because we have
8:19:52platforms like Apollo and Ampify and
8:19:53stuff that let us get an almost infinite
8:19:55number of them. Uh, aside from that
8:19:56though, yeah, like you can squeeze a lot
8:19:58of juice out of the system. You could do
8:19:59a lot more than I did here. You could do
8:20:00a number of things. Instead of just
8:20:01scraping all of the website pages and
8:20:03putting it into an icebreaker, you'd
8:20:04actually like use it to generate an
8:20:05asset. You could build a big dossier on
8:20:07the client. You could have this be like
8:20:09a person research machine where you
8:20:10build up some massive list of
8:20:12information and extract everything about
8:20:13them and then feed that into a big
8:20:15database and then use that database to
8:20:16pitch people in a lot more detailed of a
8:20:18manner than I am. You could generate
8:20:20multiple different types of icebreers.
8:20:21You could test different icebreers
8:20:22against each other. You could blast out
8:20:24to everybody in the same domain and then
8:20:26use other people's information to
8:20:28reference those people in those emails.
8:20:30You could say, "Hey, David, I was
8:20:31looking through Zayn's profile. pretty
8:20:33sure he's one of your colleagues and I
8:20:35noticed X Y andZ really unique cool
8:20:36thing that only a human being would
8:20:38notice. Just wanted to say great work
8:20:40and I had a proposition for you. When
8:20:42you say stuff like that, people again
8:20:43just assume that you're a real human
8:20:44being that sat down and is doing this
8:20:46manually. And whether or not you know
8:20:48your pitch is even that incredible.
8:20:49Usually when you can imply that you're a
8:20:50real human being and you can convince
8:20:52someone of that, they're a lot more
8:20:53likely to take the rest of your pitch
Outro
8:20:54seriously. You're crushing it. You just
8:20:55built a cold email system that now
8:20:56generates 5 to 10% reply rates through
8:20:58deep website personalization. Assuming
8:21:00of course the rest of your copy is up to
8:21:02snuff. The idea is now you or the person
8:21:03that you are selling the system to has
8:21:05prospects that are reaching out and
8:21:06showing genuine interest in automation
8:21:08services. Congratulations if you guys
8:21:09are still here. You've completed the
8:21:11most comprehensive NAND master class on
8:21:13the internet that features live
8:21:15building. You went from someone that has
8:21:16no idea how to put together an
8:21:17automation to somebody who now has a
8:21:19complete arsenal of both
8:21:20professional-grade AI workflows that
8:21:22businesses are willing to pay thousands
8:21:23for and also the knowledge to build
8:21:25these things from scratch. At this
8:21:26point, you're no longer just a beginner
8:21:28watching an automation tutorial. You are
8:21:29hopefully equipped with eight proven
8:21:31systems to solve real business problems.
8:21:32You understand n foundations. You can
8:21:34build complex multi-step workflows. And
8:21:37you also have some systems that
8:21:38typically sell for 3 to 15,000 bucks in
8:21:40implementation. You can reference any
8:21:41part of this master class just using the
8:21:43timestamps below. So please bookmark
8:21:45this video. Come back anytime you want
8:21:46to brush up on a specific workflow or a
8:21:48specific technique. Now in reality
8:21:50having technical skills is just the
8:21:51beginning. The gap between people who
8:21:53understand nod and people who actually
8:21:55make money with it is not really the
8:21:56technical knowledge. It's execution.
8:21:58It's accountability and it's staying
8:22:00consistent with the daily activities
8:22:01that generate clients. That's exactly
8:22:03what Maker School solves. That is my
8:22:0490-day accountability program that
8:22:06guarantees you your very first a
8:22:07automation client or your money back.
8:22:09Instead of wondering what to focus on
8:22:11every day, Maker School gives you a
8:22:12clear daily action plan. The whole idea
8:22:14is to eliminate the decision fatigue so
8:22:16inherent in stuff like this. And it just
8:22:18keeps you moving towards your goal in as
8:22:19effective a method as possible. Many
8:22:21members start selling the exact same
8:22:22systems that we just built together
8:22:24within a couple of weeks of joining. and
8:22:25they build revenue streams that deliver
8:22:26consistent monthly income. If you're
8:22:28serious about turning these skills into
8:22:30actual income, I would encourage you to
8:22:31at least consider joining Maker School.
8:22:33Aside from that, thanks for completing
8:22:35this master class and I'll catch you all
8:22:36in the next video. Peace out.