Social listening
Every Monday the week's public LinkedIn posts about the problem you solve are searched, judged against your ICP, and posted to Slack as one digest: the conversations worth joining, and the commenters in them who look like buyers, each quoted with a link.
Set up the social-listening cookbook in this project.
1. If the Cargo CLI is not installed yet, follow every step in https://api.getcargo.io/INSTALL.md
2. From the Cargo project, run: cargo-ai cdk add cookbook/social-listening
3. Then follow .claude/skills/social-listening/SKILL.md. Stop for my approval before any paid call, and stop at "cargo-ai project plan" before deploying anything.$cargo-ai cdk add cookbook/social-listeningSay this to your agent
Every Monday, tell #gtm-signals which LinkedIn conversations about lead routing are worth joining.
Illustrative output #
Fictional records, to show the shape of what comes back.
:ear: *What the market said this week*
_Routing breakage after CRM migrations came up three times._
*Worth joining*
• Dana Ruiz, VP RevOps at Fabrikam: "Our Salesforce migration broke every
routing rule we had" — ICP persona, pain "routing breaks on field changes"
(linkedin.com/posts/dana-ruiz_fab…) · 41 comments
• Wingtip Toys Engineering: a teardown of hand-built lead routing — category
term "speed to lead" (linkedin.com/posts/wingtip…) · 12 comments
*Warm engagers*
• Sam Okafor, Head of Revenue Operations at Contoso, on Dana's post:
"We rebuilt ours three times this year." (linkedin.com/in/sam-okafor)
_Searched: "lead routing" OR "speed to lead" · 40 posts read, 3 already surfaced_
Forty posts were read; two were picked and recorded in surfaced_posts, one commenter matched an ICP
persona, and nothing was sent to anyone.
What you will be asked #
| Input | Why | |
|---|---|---|
searchKeywords (infra/models/linkedin-posts.ts) | Looked up | It is what you buy each week. Positioning copy as keywords returns vendors talking to each other; buyer language returns buyers. |
limit (infra/models/linkedin-posts.ts) | Asked | It is the weekly spend ceiling on the search. |
channelId (infra/agents/listener.ts) | Asked | The digest names people. Locked so it never lands in a customer shared channel. |
Done when #
node --import tsx evals/contract.mjspassescargo-ai cdk planreports the agent, the two models, the three connectors and the two folders- the first sync landed rows in
linkedin_posts, all from the past week, no more thanlimit - one digest landed in the locked channel in the
references/digest.mdshape, every pick citing a context line and linking its post surfaced_postshas one row per pick plus onedigest-<date>row, and no column holding a person- a second run the same day posted nothing and read no comments
- the run transcript shows no LinkedIn action other than
searchPostComments, and only on picks - every quoted comment exists on the linked post, and every employer shown is in the commenter’s own headline
What it costs #
Read the live price of each paid step immediately before the plan, and say each one out loud:
cargo-ai connection integration get linkedin: thefetchPostsextractor (per post returned, so the weekly ceiling islimittimes that price) andsearchPostComments(per comment returned).cargo-ai orchestration action list postMessage --kind connector --integration-slug slack.
The weekly cost is one search capped by limit, comment reads on at most five posts each capped by
the prompt’s comment limit, one Slack post, and the agent run billed as LLM tokens through the
Anthropic connector. On the live run the agent run, not the search, was most of the bill: it reads
the ICP, personas, objections and insights before it judges a post. A re-run that stops at the
ledger costs a small fraction of a full run. Read the run’s usage after the first week
(cargo-ai ai message get) before you widen limit.
A weekly digest of the LinkedIn conversations worth joining, and the commenters in them who look like buyers. A model buys one capped post search; an agent judges it against the ICP in the workspace context, reads comments only on the posts it picks, and posts one digest to a locked Slack channel. It never engages on anyone’s behalf.
What it does #
- Syncs the past week’s LinkedIn posts for your buyer-language keywords every Monday.
- Drops posts already surfaced, then picks at most five worth joining, each tied to a context line.
- Reads comments on those five only, and quotes up to ten commenters whose headline matches an ICP persona.
- Posts one digest, then records the picked posts in a ledger so none headlines twice.
What’s inside #
Adds 9 resources.
| File | Resource | Role |
|---|---|---|
infra/models/linkedin-posts.ts | defineModel (fetchPosts) | the weekly, capped keyword search: what you buy |
infra/models/surfaced-posts.ts | defineModel (native) | the ledger: one row per post surfaced, no people |
infra/agents/listener.ts | defineAgent | the cron, the reads, the comment pull, the locked post |
infra/agents/listener.prompt.ts | (not a resource) | read context, pick, read comments, post, record |
infra/connectors/linkedin.ts | defineConnector (linkedin) | the search and the comment read; no engagement wired |
infra/connectors/slack.ts | defineConnector (slack) | the post path |
infra/connectors/anthropic.ts | defineConnector (anthropic) | the model the agent runs on |
infra/folders/index.ts | defineFolder ×2 | where the agent and the models are filed |
references/digest.md | (not a resource) | the digest shape and the rule for each section |
Why the search is in the model #
The search is a paid source: it bills per post returned. That makes its query the purchase, so it
sits in the model’s config with a limit, rather than pulling everything and narrowing in SQL. The
sync replaces the rows each week, which is why “already surfaced” lives in a separate ledger.
Placeholders (edit before deploy) #
searchKeywordsininfra/models/linkedin-posts.ts: buyer-language phrases and competitor names from your workspace context.channelIdininfra/agents/listener.ts.languageModel: any Anthropic model the workspace’s connector can reach.
What it does not do #
It does not like, comment, connect, message, follow or visit a profile; store a list of people; look anyone up beyond the comment they wrote; or post anywhere but the locked channel.