Intro: The Problem
0:00
[Music]
0:03
so Max and I cooked up a crazy idea what
0:05
if AI can answer your LinkedIn messages
0:07
for you this started as a jam session
0:09
with Max the original flowmer where we
0:11
basically vibecoded our way through a
0:13
working MVP if you want to see how it
0:15
came together Max made a
0:16
behind-the-scenes video worth checking
0:17
out we were both overloaded with
0:19
LinkedIn messages and internal requests
0:21
and we thought man there's got to be a
0:22
better way to handle this so here's what
0:24
we built a LinkedIn request router that
0:25
uses UniPile to handle messages Slack
0:27
for approvals and Notion is the brains
0:29
behind the scenes we're actually using
0:30
this ourselves this isn't just a demo
0:32
let me show you how to set it up let's
Demo: AI Inbox in Action
0:34
start by seeing a demo of this in action
0:35
the way this works is we utilize Slack
0:38
as our interface for human in the loop
0:40
to do this we've created an app called
0:42
Request Router request router acts as a
0:44
messaging cue for you to process your
0:46
incoming LinkedIn messages now because
0:49
we don't fully trust AI and because
0:51
there are some instances where the AI
0:52
just cannot answer with the context that
0:54
we have we want to make sure that these
0:56
messages go through us first and we're
0:58
able to edit them before we send out the
1:00
AI responses so to do that I'm going to
1:02
go ahead and trigger our web hook here
1:04
on the Unipile side and I'm going to
1:06
trigger a sample message from LinkedIn
1:08
so we'll give it just a few moments for
1:10
it to run and then we should see it
1:12
moving smoothly through this process
1:14
here and there we go so now we've
1:15
triggered the workflow to run and as you
1:17
can see it's running through the
1:18
workflow
1:20
and there we go now if we make our way
1:21
back to request router we can see we've
1:23
received a message it's very well
1:25
formatted using block kit and we have a
1:27
few useful links here we can link
1:28
directly to the person who messaged us
1:30
LinkedIn account or we can link directly
1:32
to the LinkedIn message itself and
1:34
respond via the website LinkedIn but
1:37
what's most useful here is that the
1:39
message has already been preformatted
1:41
and preset up all I have to do is come
1:42
in here and make some changes if I want
1:44
to and hit approve and it will send that
1:46
new updated message out to this user via
1:49
LinkedIn message now this message here
1:51
of course we're is a sample message so
1:53
we're not going to utilize this right
1:54
now but as a cue what we can do here is
1:57
if we don't intend to message this
1:59
person back we can just hit archive or
2:00
we can hit approve to send the message
2:02
for this one I'm going to go ahead and
2:04
archive it for now now let's see what
2:06
happened on the back end so here what
2:08
has happened is we have received the
How It Works (Slack + Notion + Unipile)
2:10
message from LinkedIn through unipile
2:12
which is a third-party service that acts
2:14
as a relay for the LinkedIn API it is a
2:16
paid service however it is well worth
2:18
the cost as it makes working with
2:20
LinkedIn's API very easy to do so the
2:22
message comes in via UniPile we check to
2:24
make sure that we were the one that sent
2:26
or received this message then once we
2:28
check as we can see here it's someone
2:29
other than ourselves that sent this
2:31
message so we're going to go ahead and
2:32
route it here if it had been us
2:34
responding to the person that message
2:35
would have gone down this path because
2:37
we don't want it to take action on our
2:38
messages only incoming messages so the
2:41
message comes in we do some checking on
2:42
LinkedIn to find more details of the
2:45
user to get context of that user in
2:48
LinkedIn things like followers and
2:50
connections and even where they're from
2:51
additionally we will then check our
2:54
notion database this notion database
2:56
acts as a directory this directory
2:58
allows us to route messages hence where
3:00
the name request router came from to the
3:02
right department cuz many times the
3:04
problem is we don't know who needs to
3:06
get a particular message or even if we
3:07
do getting the URL or email address of
3:10
the person that needs to be contacted
3:12
can be difficult or timeconuming at the
3:14
very least so here what we've done is
3:16
we've created a standardized database
3:17
that we're going to look at here in a
3:19
moment to feed the AI with context to
3:21
generate the message appropriately this
3:23
also has a little bit of memory so that
3:25
it keeps track of the separate
3:26
conversations and gives it more context
3:29
when it comes to responding in real time
3:31
next up we will then send one of three
3:33
different messages as we saw here
3:35
there's actually two different types of
3:37
user within LinkedIn so you can get a
3:39
message from an individual user or you
3:41
can get a message from an organization
3:43
so here what we're doing is we're
3:44
checking to see if we find the user if
3:45
we can't then we search the organization
3:48
endpoint and if we can't we have a
3:49
fallback error message and this error
3:52
still generates a Slack automatic
3:53
message but it doesn't have the
3:55
contextual details for the user or the
Setting Up the Workflow
3:58
organization let's go ahead and walk
3:59
through setting this up i've done my
4:01
best to color code these to make it easy
4:03
to deploy so to do that we have the red
4:06
items here which are web hooks that need
4:07
to be updated one here on UniPile one
4:10
here in Slack and then the yellow for
4:12
logic or credential updates that need to
4:14
be made to make sure that this works
4:15
correctly everything else should be able
4:16
to be left as is so let's go ahead and
4:18
start by updating the UniPile web hook
4:21
portion to make this easier I've
4:22
included a link directly to the UniPile
4:25
dashboard to where we need to go so what
4:27
we're going to do here is we're going to
4:28
set up a new web hook so I'm going to
4:29
call this something along the lines of
4:30
NAN web hook i'm going to set it to only
4:33
trigger on messages and on any new
4:35
messages that's what's going to trigger
4:37
the web hook now this is important if
4:38
you manage a business in LinkedIn you
4:40
will not only receive messages sent to
4:42
you but also to your organization any
4:45
organizations that you manage or are
4:46
owner of they're going to trigger this
4:48
workflow as well and when you respond as
4:50
that organization it will trigger it as
4:52
well so we're going to need to update
4:53
the logic to take this into
4:54
consideration so here's where we put our
4:56
callback URL that's pretty
4:58
straightforward we're going to go into
4:59
the web hook we're going to copy the
5:00
production URL and we're going to paste
5:02
it right here now I'm not going to do it
5:03
in this case cuz I don't need more than
5:05
one here so as you can see mine's
5:07
already set up this is what yours should
5:08
look like and you'll be ready to go the
5:10
next portion of setup is the logic so
5:13
this right here is as I was mentioning
5:15
is your LinkedIn user ID now I don't
5:18
believe this is LinkedIn's actual user
5:19
ID this is Unipile's version of your
5:22
LinkedIn ID so the best way to do this
5:24
is to send a message to someone on
5:26
LinkedIn while this is active maybe turn
5:28
off the Slack portions or all the other
5:31
portions here at the end by hitting the
5:32
little power buttons here when the
5:34
message comes in that you know that you
5:35
sent this will fill in with your user ID
5:38
so just copy this directly into this
5:41
portion same goes for if you send or
5:44
receive a message from your organization
5:45
the organization that you manage go
5:47
ahead and update it here if you don't
5:48
manage an organization in LinkedIn go
5:50
ahead and delete this and you'll be in
5:52
good shape from there we're going to
5:53
want to update the credentials inside of
5:56
your Unipile HTTP request so again I've
6:00
tried to link it to make it a little bit
6:01
easier to the Unipile site what we're
6:03
going to do here is we're going to
6:04
generate a token we're going to give it
6:05
messaging and account scopes i'm also
6:07
giving it web hook scope i don't believe
6:09
it needs it but it's best to have it
6:11
just in case we'll call this NAN credits
6:14
and we'll go ahead and generate and make
6:16
sure that expiration date is set up
6:18
correctly now I'm going to delete this
6:19
here in a moment but I did want to
6:20
generate it so that you realize that
6:22
there are two things that need to be
6:23
updated the first is the URL you're
6:25
going to copy this URL here you're going
6:27
to go into here and make sure that this
6:29
portion right here reflects that same
6:32
URL for UniPile and then the second
6:35
portion is the API key so we're going to
6:36
go ahead and go into the Unipile account
6:38
here we're going to copy that API key
6:40
easier to just copy it here into this
6:42
value now you will want to use the
6:44
X-API- key in all caps exactly as we see
6:48
here and don't forget to give it a name
6:49
so here I'm going to leave my old one in
6:51
place i'm going to come back here and
6:53
hit done and I'm going to go ahead and
6:54
delete this one right now once that is
6:57
updated you will need to make sure that
6:59
you do that for all three of these so
7:01
this one as well as this one these three
7:03
all have the Uniile login and they will
7:06
need to be updated next up we're going
7:07
to make our way into Notion now the
7:09
Notion portion already has plenty of
7:11
documentation and I don't have the
7:13
ability to generate API credentials on
7:15
my Notion account here what you're going
7:16
to want to do is follow the
7:18
documentation internally by clicking
7:20
docs and following the instructions but
7:22
more importantly change this out for
7:24
whatever service you use you don't have
7:25
to use Notion you can use something as
7:27
simple as Google Sheets rather if you do
7:29
change this make sure that you change as
7:31
well the outputs here so you may get
7:33
under the schema you really want to get
7:35
a name description as well as an action
7:38
make sure to click and drag these here
7:39
to map them correctly into this single
7:41
object and then from there the rest will
7:43
be updated automatically on the AI agent
7:46
side next we're going to go ahead and
7:47
update our model so if you're going to
7:49
use Open AI's chat GPT it's as easy as
7:52
opening this up and updating your API
7:54
keys here again this is very well
7:56
documented i'm not going to dive into
7:57
the documentation for this portion but
7:59
if you are unsure on how to set up
8:01
credentials for this go ahead and hit
8:02
docs and you'll be good to go it'll walk
8:04
you through it the Slack portion can be
8:06
a little bit more work but I've tried to
8:07
make it as easy as possible what we're
8:09
going to want to do is make your way to
8:11
the Slack API portion under
8:13
api.slack.com/apps
8:16
and it should look something like this
8:17
and what you're going to want to do is
8:18
create a new app now I have included the
8:21
app manifest here to make it easier
8:23
you're going to click here select your
8:24
organization and make your way to the
8:26
template page that's provided in the
8:28
link and head down to the Slack setup
8:30
portion and copy this app manifest in
8:33
order to copy and paste all of the
8:35
scopes required for this app now I did
8:38
not put in a web hook URL so you're
8:40
going to want to replace this with your
8:42
web hook URL we're going to go here and
8:44
go into production URL and replace it
8:46
with your Slack URL this once you've
8:49
pasted it in and created your
8:51
organization or your Slack app you're
8:53
going to go into request into the app
8:54
itself and you're going to go into
8:56
interactivity and shortcuts and just
8:58
make sure that web hook URL is set here
9:00
correctly you may have to update it and
9:02
hit save and it should then start
9:04
working at this point both sections are
9:07
then going to be active make sure that
9:08
you of course update your credentials
9:10
here as well they should update
9:11
automatically once you create the
9:13
credentials here but if not double check
9:15
it and ensure those are up to date now
9:17
that we've set up both portions of the
9:19
workflow ready to start working let's go
9:21
ahead and dive through each portion this
9:23
portion of the workflow receives the
9:25
message and isolates some variables in
9:28
order to make life a little easier we've
9:30
already talked a little bit on how to
9:31
update this portion not going to dive
9:33
too deeply into it and the message comes
9:35
in and is then checked to see if we can
9:38
find more details on the user that
9:40
information can be found by opening this
9:42
up and as you can see we have the data
9:44
on the right with the information of the
9:46
user if it's not found it will then try
9:48
the organization to see if it can find
AI Agent & Directory Logic
9:50
it once we get that information we're
9:51
going to get our directory this is where
9:53
a big portion of the power of this
9:55
automation lives ai is wonderful but
9:58
without guard rails AI can quickly start
10:00
hallucinating responses that we may not
10:02
want to that end we've created a little
10:04
database internally for our team you can
10:06
think of this database as almost a
10:08
standardized procedures database that
10:10
allows us to route the answers to the
10:13
correct department for example if
10:15
somebody wants to become an NADN
10:16
ambassador they need to visit a specific
10:18
web page that web page is now preloaded
10:20
so if the message comes in saying "Hey
10:22
how do I become an NAND ambassador?"
10:24
Typically I'd have to find the owner get
10:26
the information from them get the URL
10:28
and then send it to the person via
10:30
LinkedIn in this case that information
10:31
is already included in the database so
10:33
it will generate a response that
10:35
includes that URL that makes life a lot
10:37
easier things like as well how can I
10:39
become an expert here as you can see we
10:41
have the NAND experts page this allows
10:43
us to quickly route the message to the
10:46
right person not only that but we see
10:47
who the owner is we're able to
10:49
standardize our internal processes and
10:51
use that standardized database not just
10:54
for manual use for someone like me that
10:56
might be new to be able to figure out
10:58
who to send requests to but also for our
11:00
AI to automatically generate responses
11:03
this is really powerful if you create a
11:04
subworkflow of the AI portion of this
11:07
and use that subworkflow not just for
11:08
LinkedIn but also for maybe your email
11:10
inbox to instead of generate the
11:13
responses and send them via email but to
11:15
generate responses and set them up as a
11:16
draft email attached to that thread
11:18
there are many uses for this and it
11:20
doesn't have to be notion it can also be
11:22
something as simple as Google sheets the
11:24
other thing that we can do is
11:25
conditional responses this is really
11:27
powerful because one of the things we're
11:29
getting here via LinkedIn is how many
11:30
followers and connections a particular
11:32
person has or organization has when they
11:34
message you for example on my end what
11:36
I've done is I've created a conditional
11:38
message that if somebody messages me and
11:40
they have over 5,000 followers on
11:42
LinkedIn I immediately will give them my
11:44
booking link this is great because I can
11:47
see that this person is an influencer
11:48
this person is wellconed and maybe they
11:51
can help our organization internally in
11:54
terms of our outreach now if they're
11:56
under 5,000 we can give them a warm
11:59
polite decline so thanking them for
12:01
their interest let them know that I'm
12:03
currently heads down or unable to meet
12:05
thanks so much for this kind message
12:06
really appreciate it at this moment I'm
12:07
heads down not taking on new meetings
12:09
letting them know hey I'm sorry I'm a
12:11
little busy right now these kinds of
12:12
messages tend to flood my inbox and so
12:14
this has been a wonderful way to be able
12:16
to quickly decide whether or not I
12:19
should reach out to someone or not now
12:21
that you have a better understanding of
12:22
the directory database let's head back
12:24
into request router and move on to the
12:26
next step which is the AI agent this is
12:28
where the AI magic happens there are two
12:31
inputs here we have our user input which
12:33
is the context of the message here we
12:35
have the name of the sender the message
12:37
themselves that was sent and my name in
12:39
this particular case and here I might
12:41
replace this with Angel and you don't
12:42
have to give it this context but it
12:44
helps especially if you're utilizing
12:46
this workflow across several different
12:48
users and then here we have a little bit
12:49
of a prompt to found the LinkedIn
12:50
profile will be below pay close
12:52
attention to the number of followers and
12:53
connections this is important for that
12:56
conditional responses that we mentioned
12:58
earlier and then the most important part
13:00
is here the actual system prompt you can
13:02
think of this as the AI's personality so
13:04
here we're telling it what it is smart
13:06
professional assistant designed to help
13:08
generate smart personalized responses in
13:10
LinkedIn we give it an idea of what it's
13:12
going to be provided with and then our
13:13
objective the first objective is to look
13:15
inside of our directory database which
13:18
is included below to see if there's any
13:20
potential responses to their answers in
13:23
that database and then if nothing is
13:24
found generate a thoughtful response
13:26
from its own training this makes it
13:29
faster to respond because this at least
13:30
takes care of the pleasantries within
13:32
the message response cycle at the very
13:34
least all I have to do is go into Slack
13:36
and edit just the content itself but the
13:38
beginning and end is usually well
13:40
thought out and ready to go we also give
13:42
it a nice tone so friendly confident and
13:44
professional lightly personalized
13:46
doesn't sound like a sales pitch and
13:48
keep the replies concise and natural we
13:50
want to make sure to acknowledge the
13:51
sender's message add a relevant or
13:53
helpful comment and keep the tone warm
13:55
and open-ended only the output of the
13:58
message should be sent to the user and
13:59
here we have the actual directory
14:01
database we give it the context needed
14:03
to respond correctly and then the format
14:05
we expect it to respond in we also have
14:08
that format set in the output parser
14:10
right here in order to double check to
14:12
make sure that the output is correct
14:14
once that is done because we are setting
14:16
a response type and that is set a little
14:18
further earlier on here on the type so
14:21
here we're either a user type or we're
14:23
an organization type or if not either of
14:26
those then none here it routes through
14:28
one of these two and if it can't find
14:31
them then it sends this type of message
14:33
as you can see here we sent this kind a
14:35
user message and we've mapped in all of
14:38
the relevant block kit needed to ensure
14:40
that the message looks nice and is
14:42
contextual and we've also included the
14:44
button block kit here that embeds the
14:48
uniile message ids and chat ids in order
14:51
to store this inside of Slack almost as
14:54
a database item when we hit the button
14:56
it sends this data back in the bottom
14:59
part of this workflow to quickly route
15:01
the message as needed let's take a look
Slack Button Actions + Advanced Routing
15:02
at that portion when we hit one of the
15:04
buttons it sends it down to this web
15:06
hook this is used to verify that the web
15:08
hook is still active in case Slack sends
15:11
a challenge message normally this will
15:13
not be used other than whenever you
15:14
first put in your web hook URL in the
15:16
Slack app and then here we check for
15:18
users because we want to create the
15:20
least amount of apps possible what we
15:22
can do is we can use this as an
15:24
organization here what we're doing is
15:26
we're checking to make sure that my
15:27
Slack user ID is set if I'm the one that
15:30
presses the button my Slack user ID is
15:33
included in the payload user ID and it
15:35
routes it through my response type but
15:37
if for example my colleague Max presses
15:40
the button on his but he's using the
15:42
same Slack app it gets sent to the same
15:43
workflow what I can do is send that
15:45
payload to his workflow in N8N and have
15:48
him take care of the logic on his end to
15:51
customize what happens when the button
15:52
is pressed here as you can see if the
15:54
message is mine I'm going to isolate the
15:56
message and payload here we're going to
15:58
check to see if we approved it or not
15:59
and then here since we have stored the
16:02
message and chat ids we're going to go
16:04
ahead and send it to this channel ID the
16:06
message and here is the message itself
16:09
that we're sending this as the response
16:11
and then from there we're going to go
16:12
ahead and delete the message from Slack
16:14
in order to keep our queue nice and
16:16
clean and keep that human in the loop
16:18
process active that is the whole process
16:20
now this can be adapted in many
16:22
different ways you can adapt this for
16:24
this portion right here to be its own
16:25
subworkflow that then can be used both
16:27
for LinkedIn or for emails whenever an
16:30
email inbox message is sent into a
16:32
shared organization email you can use
16:35
the same subworkflow to ensure that only
16:38
one place needs to be updated across
16:40
multiple workflows and you have the same
16:43
consistent output across all of them and
Wrap-Up & Template Info
16:45
that's request router simple human in
16:46
the loop and built using tools you
16:48
probably already have if this sparked
16:49
any ideas or you want to build your own
16:50
flavor of it hit me up via LinkedIn i'd
16:52
love to see what you come up with i'm
16:53
including the template file in the link
16:55
below and again don't miss the
16:56
behind-the-scenes video Max made of the
16:58
original session catch you on the next
17:00
one