<summary>Fetch the people who reacted to or commented on a LinkedIn post — the
user's own post or anyone else's — and store them as queryable engagement
rows. Use when the user wants to turn a post's engagers into leads
("everyone who liked this post", "who commented on her launch post").
Visibility follows the user's LinkedIn account: any post it can view
works, and private or deleted posts return a plain error. The list is
capped at 500 reactions + 500 comments per post; on a bigger post the
return flags the cut-off. Data fetched within the last 6 hours is served
from the database at no cost; a real fetch counts one action against the
shared daily engagement-fetch budget and paces its LinkedIn requests, so
a post with hundreds of engagers takes around half a minute — set that
expectation with the user before calling this on a big post.
When this runs in an agent, every person who engaged is saved as an
`agent_search_results` person row, rendered in the agent's Output tab and
queryable via `query_search_results`: `data.person` carries the name and
headline, `data.provider_id` the LinkedIn id, and `data.columns` the
engagement (Engagement, Comment, Post, Post URL). Company pages that reacted
or commented aren't people, and the user isn't a lead, so neither is saved;
both stay in the engagement rows. Re-running updates existing rows rather than duplicating
them. Pass `list_name` to name their list; absent, they land in the
'default' list.
Each person new to the list is checked against `criteria`, one at a
time, reading their headline and engagement, and saved with the
verdict; the rejected ones are hidden from the list's default view and
from `query_search_results`. The check adds about 20 seconds per
hundred people. To keep everyone who engaged, write broad criteria,
such as "Anyone who engaged with this post". A person already on the
list keeps their verdict, so to screen a post's engagers against new
criteria, pass a new `list_name`.
After this returns, read the saved people with the `query_search_results`
call in `next_step`, which is scoped to this post: one list can hold
several posts' engagers. Judge anyone the check kept as `unclear` or left
without a verdict yourself, then queue outreach for the people who fit
with one batched `setup_linkedin_sequence` call passing each person's
`data.provider_id`. Send-time resolution skips anyone already connected,
so they don't need pre-filtering here. Every engager, the rejected ones
included, also stays queryable with `query_linkedin_post_engagements`
using `post_id = <post_analytics_id>`.</summary>
<returns>
<description>On success, a dict
{'success': True, 'post_analytics_id': int, 'author_name': str,
'is_own_post': bool, 'post_text_snippet': str, 'from_cache': bool,
'reactions_stored': int, 'comments_stored': int,
'unique_engagers': int, 'truncated': bool,
'budget': {'used_today': int, 'limit': int},
'engagers_preview': [first 10 engagers, unchecked], 'next_step': str,
'list'?: {'list_name', 'created', 'updated', 'total', 'rejected'}}.
`unique_engagers` counts company pages too; `list.total` counts only the
people saved, rejected ones included, so it can be lower. `list.created`
and `list.updated` count the people the list shows, and `list.rejected`
the ones the check turned down.
On failure, {'success': False, 'error': str} when the post isn't visible to the
user's account, the daily budget is exhausted, or LinkedIn actions
are paused after a rate limit.</description>
</returns>