AIT-470: Instagram tool surface - #72
Conversation
|
Warning Review limit reachedNext included review available in 36 minutes. View limit detailsLimit details: You’ve used all 2 included reviews currently available. Your 84 included PR review attempts over the past 7 days set your current allowance at 2 reviews per hour. Your organization has reached its usage spending cap. Adjust your spending cap in the billing tab. Review configuration: ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (5)
Comment |
…e CLI Mirrors the new MCP tools so the CLI stops sending people to raw curl for things we are approved for: - instagram media — posts, stories, and tagged posts; --media reads one post and expands carousel children. Until now --media on insights and comments wanted an id the CLI never produced, and its own help sourced it "from the inbound webhook". - instagram mentions — where other accounts @mentioned you. - instagram threads — DM threads, one thread's messages, and the public profile behind an IGSID. Scoped with platform=instagram so a linked Page cannot answer with the wrong inbox. - instagram profile — the profile fields insights never served, plus the publishing quota behind --quota. Thread and participant ids are Meta's opaque keys rather than numeric Graph ids, so they get a URL-safe-alphabet guard instead of the numeric one.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 000a441a4e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (rows.length === 0) process.stdout.write('No messages in this thread.\n'); | ||
| return; |
There was a problem hiding this comment.
Print the cursor when a thread has more messages
When a thread contains more than the default 25 messages, human-readable mode returns here without printing res.paging.cursors.after, unlike the conversation, media, and mentions list paths. As a result, users receive a silently truncated thread and cannot determine the value required by --after unless they rerun the command in JSON mode; print the continuation hint before returning.
Useful? React with 👍 / 👎.
…hook
Meta documents /{ig-user-id}/mentions as POST-only: it creates the reply. The
list tool this branch added would have failed against Meta on every call.
The real read is a field expansion on the IG-User node —
mentioned_comment.comment_id(<id>) or mentioned_media.media_id(<id>) — keyed
by an id that only the mentions webhook supplies. Replying keys off media_id
in both shapes, so a comment mention needs both ids.
Renamed to get_instagram_mention / `instagram mentions --media|--comment`,
which reads the mention and posts the reply in one call, and rejects a reply
missing media_id locally instead of letting Meta return an unhelpful error.
The docs and skill now say plainly that no listing exists and point at the
webhook.
Meta gates /{ig}/stories and /{ig}/tags on a Facebook User access token plus
pages_read_engagement, and the Instagram-Login page states the setup "cannot
access ads or tagging". Every channel we connect is Instagram Login, so the
stories and tagged sources would have failed for every customer.
Removed rather than left in to fail: an option that never works is worse than
an absent one. list_instagram_media is now posts plus the single-post read.
content_publishing_limit is documented against
instagram_business_content_publish, so get_instagram_account gates on that
scope when the quota is requested and on basic when it is not.
The docs page keeps its stories and tags curl, now under a warning saying who
can actually call them.
…hreads From the Codex review, verified against Meta docs before applying. Accepted: - A conversation has NO /messages edge. Meta serves the messages as a field expansion on the conversation node and nests them under messages.data, so the old call returned an empty list and dropped the cursor silently. - mentioned_comment / mentioned_media are Facebook-Login expansions. The Instagram-Login Mentions guide documents exactly two calls on graph.instagram.com: GET /<IG_ID>/tags to see what tagged or @mentioned you, and POST /<IG_ID>/mentions to reply. The tool is now reply-only and the read is list_instagram_media with source "tagged". Rejected, both contradicted by Meta: - ice_breakers as a flat array. The IG-Login doc shows the call_to_actions wrapper, and the Messenger variant marks locale "default" as REQUIRED. - fields in the DELETE query string. Meta sends it as a JSON body. Also reverses my own earlier removal of /tags: I had read the IG-User /tags REFERENCE page, which lists Facebook-Login permissions. The Instagram-Login guide is the one that applies to us, and it documents /tags on graph.instagram.com under instagram_business_* scopes. /stories stays out — no Instagram-Login guide documents it.
Reading a thread printed the messages and stopped. The conversation list right below it ends with a "More: --after <cursor>" line, so the same command taught you how to page in one mode and not the other, and --after was undiscoverable for threads. The cursor is there, just nested: a conversation has no /messages edge, so Meta expands the messages onto the node and the cursor lands under messages.paging.cursors.after rather than at the top level. The JSON output already read it from there; the human-readable output did not. Found by a second Codex pass over the branch.
Same defect as the backend tool. --after was sent as a top-level param, so it paged the conversation node rather than the expanded messages edge, and the "More: --after" hint added in e7f7b19 pointed at a cursor that returned the same page. The modifiers now ride inside the expansion as messages.limit(N).after(CUR){...}, and the cursor is validated before it is interpolated there, since a stray ) or { would escape the expansion.
Wraps the Instagram endpoints we hold Advanced access to but never exposed. Four repos, one branch:
ait-470-instagram-tool-surface.MCP tools (backend)
list_instagram_media— posts, stories, tagged posts, plus a single post with carousel children. This is where media ids come from, soget_instagram_insightsandlist_instagram_commentsstop being unreachable.list_instagram_mentions— where the account was @mentioned, and the post behind it.list_instagram_conversations— DM threads, one thread's messages, and the profile behind an IGSID.get_instagram_account— profile fields insights never served, plus the publishing quota on request.set_instagram_thread_setup— starter questions and the thread menu.send_messagenow documents the Instagram payloads it always relayed: quick replies, generic/button templates, sender actions.CLI:
instagram media,instagram mentions,instagram threads,instagram profile.Docs: new Mentions page; CLI and MCP sections added to Your posts, Inbox, Insights, and Ice breakers.
Skill:
integrate-hookmyappno longer tells agents that listing posts is "raw HTTP; no CLI command".Ticket: https://linear.app/hookmyapp/issue/AIT-470/instagram-we-expose-about-a-third-of-what-our-approved-permissions
Notes for review:
assertIgObjectId.platform=instagram; without it a Page-linked account can answer from, or be written to, the Messenger inbox.