In this tutorial, you’ll learn how to build AI agents that manage your LinkedIn outreach 24/7. This step-by-step guide shows how Uxer, combined with Anthropic’s Computer Use, delivers automation that is faster, cheaper, and more reliable than any other solution. Unlike generic bots, this system creates hyper-personalized LinkedIn outreach that feels human and builds real connections by using each person’s profile information, latest activities, and current company details.
We will implement five scenarios to complete LinkedIn outreach:
- Send connection requests: Reach out to your ideal customer profiles from LinkedIn search results.
- Scrape accepted invitations: Collect data on people who accepted your connection request.
- Scrape profiles: Extract details from profiles, including recent activities and current company information.
- Prepare draft messages: Create hyper-personalized messages using the scraped data.
- Send messages: Deliver the drafted messages automatically.
You decide how to get started:
- DIY: Follow the step-by-step tutorial.
- Get Help: Ask questions in our support channels or at community.uxer.ai.
- Fast Track: Let our team implement your custom workflow for you.
Scenarios
Prerequesites
- Antropic API Key
- Create relevant data sources with a test data: Linkedin_Invitation_List and Linkedin_Contacts
1. Send connection requests
For {i} in 1 to 3
OpenBrowser Chrome "https://www.linkedin.com/search/results/people/?geoUrn=%5B%22103644278%22%5D&keywords=sales%20manager&network=%5B%22S%22%2C%22O%22%5D&origin=FACETED_SEARCH&page={i}"
// Make sure page is loaded
MoveMouseTo 500,500
IsVisible Text "Home"
Scroll 10 -UntilVisible Text "Next"
// Scrape the all page
Click 500,500 -Button right
SendKeys Escape
SendKeys LeftControl+A
SendKeys LeftControl+C
Delay 1000
{CompletePage} = Clipboard
{FormattedList} = UxerAction "Goal: Format the given Linkedin page data into datasource type. Rules: No need to take a screenshot or click anything. Just return the names in expected format. Exclude people who has pending request. Expected columns: Name Given Data: {CompletePage}"
Scroll -10
//Send connection request for each person
For {Person} in {FormattedList}
//Close the profile page if exist
If IsVisible Text "Contact Info" -Retry 1
SendKeys LeftControl+W
//Open persons profile page
{Name} = {Person["Name"]}
If IsVisible Text {Name}
Click Text {Name} -Button Right
Click Text "Open link in new window"
Else
// If person is not visible scroll down and check again
Scroll 3
If IsVisible Text {Name}
Click Text {Name} -Button Right
Click Text "Open link in new window"
Else
// If person is still not visible use AI to find.
UxerAction "Goal: Right-click profile name and click 'Open link in new window' for the given person. You may need to scroll up or down to find the person. Rules: Never left-click any profile. Never go to next or previous pages. Person should be on the exising page but may require scrolling. If not, return fail Person: {Person} Failure: If you moved from the search results page go back using back arrow or keyboards shortcuts. You usually click right arrow to go back which is a mistake. Use left arrow or keyboard shortcuts instead."
//Send connection request
Click Text "Contact info" > Text "More"
Click Text "Contact info" > Text "More" > Text "Connect"
Click Text "Send without a note"
// Copy profile link
SendKeys LeftControl+L
SendKeys LeftControl+C
{ProfileLink} = Clipboard
// Add details to inkedin_Invitation_List
{Person["Profile Link"]} = {ProfileLink}
{Person["Invitation Status"]} = "Request sent"
{Linkedin_Invitation_List} = {Linkedin_Invitation_List} + {Person}
2. Scrape accepted invitations
OpenBrowser Chrome "https://www.linkedin.com/mynetwork/invite-connect/connections/"
Click Text "Sort By:"
//Scroll 10 -WaitAfter 3000
SendKeys LeftControl+A
SendKeys LeftControl+C
Delay 1000
{CompletePage} = Clipboard
{FormattedList} = UxerAction "Goal: Format the given Linkedin page data into datasource type. Rules: No need to take a screenshot or click anything. Return the names under column name 'Name'. Exclude people who has pending request. Given Data: {CompletePage}"
For {formatted} in {FormattedList}
For {invitation} in {Linkedin_Invitation_List}
If ({invitation["Name"]} = {formatted["Name"]})
If ({invitation["Invitation Status"]} = "Request sent" )
{invitation["Invitation Status"]} = "Accepted"
3. Scrape profiles
For {person} in {Linkedin_Invitation_List}
If ({person["Invitation Status"]} = "Accepted" )
OpenBrowser Chrome {person["Profile Link"]}
IsVisible Text "More"
// Scrape Profile Page
Scroll 5
Click 500,500 -Button right
SendKeys Escape
SendKeys LeftControl+A
SendKeys LeftControl+C
Delay 1000
{ProfilePage} = Clipboard
SendKeys LeftControl+W
// Scrape Latest Actvity
{RecentActivityLink} = {person["Profile Link"]} + "/recent-activity/all"
OpenBrowser Chrome {RecentActivityLink}
Click Text "All Activity"
Delay 3000
SendKeys LeftControl+A
SendKeys LeftControl+C
Delay 1000
{ActivityPage} = Clipboard
// Scrape current company page if exist
{ExperienceLink} = {person["Profile Link"]} + "details/experience/"
SendKeys LeftControl+W
OpenBrowser Chrome {ExperienceLink}
// Handling OCR for "- Present" and "- Present."
If IsVisible Text " - Present"
{currentcompanylink} = " - Present"
If IsVisible Text " - Present." -Retry 1
{currentcompanylink} = " - Present."
If Click Text {currentcompanylink} -Retry 1
IsVisible Text "About"
SendKeys LeftControl+A
SendKeys LeftControl+C
Delay 1000
{CurrentCompanyPage} = Clipboard
Else
{person["Current Company Details"]} = "Not Available"
SendKeys LeftControl+W
{person["Invitation Status"]} = "Scraped"
{ProfileDetails} = UxerAction "Goal Extract the most relevant personal and contextual details in detail from the LinkedIn content blocks below and populate three top-level fields in the datasource: • Profile Details • Latest Activity • Current Company Details Return your output exactly in this schema (no additional keys, no nesting): Current Datasource: {Person} Rules 1. Source restriction – Use only the supplied LinkedIn content (ProfilePage, ActivityPage, CurrentCompanyPage). Do not run external tools, open links, or take screenshots. 2. Format fidelity – Write strictly under the three keys above. If you must add extra context, place it as plain text inside one of these keys—never create new keys. 3. Employment status – If the person is unemployed, set Current Company Details to Not Available. 4. Relevance – Capture specific facts that enable hyper-personalized outreach (e.g., roles, achievements, projects, interests, education, locations). Skip generic statements while giving as much as detailes possible. 5. Style – Be concise and factual; avoid filler words and buzzwords. Preserve original capitalization of names and titles. 6. Missing data – If a detail isn’t present, leave it blank—do not invent information. 7. If you need to add any other text, use thought process field in the response. Content Blocks • Profile Page Data: {ProfilePage} • Activity Page Data: {ActivityPage} • Current Company Page Data: {CurrentCompanyPage} Return only the filled schema above—nothing else."
//{ProfileDetails["Current Company Details"]} = {CompanyDetails}
{Linkedin_Contacts} = {Linkedin_Contacts} + {ProfileDetails}
4. Prepare draft messages
For {person} in {Linkedin_Contacts}
If ({person["Invitation Status"]} = "Scraped")
{person["Message"]} = UxerAction "Goal: Create a draft Linkedin message following the instructions below. It will be used to outreach people. It should be an authentic message. Rules 1. Do Not take a screenshot or use tooluse. You just need to use given data and provide the draft message in a single response. You have all the relevant data. 2. Write in clear, conversational language. no robotic phrasing, exact copy-paste fragments, or buzzwords. 3. Keep tone factual; avoid exaggerated emotion. 4. Don't use dash. 5. Never use direct quotes or exact phrases from the person's profile/posts. Instead, paraphrase and interpret their content in your own words. Transform their ideas into natural conversational references. Examples: - Don't say: your recent post on revenue-driven product launches - Do say: your recent insights about driving revenue through strategic product launches - Don't say: your comment better data = better outcomes - Do say: your point about how quality data drives stronger results 6. Keep new lines. 7. Strictly follow the format rules. Expected Message Parts: Part 1 – Ice-breaker What to do: Create 1–2-sentence ice-breaker with a personal detail drawn from their latest activity or proud moment, so they feel recognised and valued.] Example text: Hi {Name}, I enjoyed your recent post on revenue-driven product launches your metric on time-to-value was spot-on. Part 2 – Bridge to the purpose What to do: Link their achievement to why you’re reaching out. Keep it to one sentence and make sure to connect with pain/gain part Example text: That focus on rapid customer value is why I thought we should connect. Part 3 – Pain-to-gain prompt What to do: State a common hurdle in personalised outreach and the upside of solving it. Tie the pain to their role/company Example text: Even experienced sales managers spend hours on manual LinkedIn outreach, and prospects still tune out generic messages. Part 4 – Real-time proof & transparency What to do: 1. Reveal that you used Uxer.ai to send connection request, learn about their profile, latest activities, company and created the note fully automated. 2. Emphasise the benefit (speed + personal touch). 3. Signal that they can achieve the same. Example text: Uxer agents, in the other hand, have reviewed your profile, recent insights, and company page, and then drafted this note fully automated, showing how you can truly personalized outreach and make more sales on scale. Part 5 – Single, low-friction CTA What to do: Offer one clear next step and invite them to see the tool in action. Example text: May I send you a two minutes demo video of Uxer in action? Just reply Yes and I’ll share it. Sign-off Thanks, Zek Co-Founder | Uxer.ai Given Data: Personal details: {person}"
{person["Invitation Status"]} = "Message Prepared"
5. Send messages
For {person} in {Linkedin_Contacts}
If ({person["Invitation Status"]} = "Message Prepared" )
RunCommand "notepad.exe"
Click Text "Notepad"
Write {person["Message"]}
SendKeys LeftControl+A
SendKeys LeftControl+C
Delay 1000
{message} = Clipboard
Click Text "File"
Click Text "Exit"
Click Text "Don't Save"
OpenBrowser Chrome {person["Profile Link"]}
IsVisible Text "Home"
Click Text "Contact info" > Text "Message"
Click Text "Write a message..."
SendKeys LeftControl+V
Delay 4000
SendKeys LeftControl+Enter
Wait -UntilInvisible Text "Sending..."
SendKeys LeftControl+W
{person["Invitation Status"]} = "Message Sent"
//Closes all chrome instances
CloseBrowser Chrome