Approval war room for every social post awaiting sign-off

By General Input

One screen showing every social post waiting on approval, sorted by deadline, so reviewers can approve or reject without leaving the page.

Integrations

  • Hootsuite
  • Slack Bot

Type

App

Categories

  • Marketing
  • Operations

Build me an approval war room for social content: a single-screen board my reviewers open every morning that lists every Hootsuite message currently sitting in pending-approval state across all of our social profiles, soonest go-live deadline first.

The main view is one dense, scannable board. Each row shows a countdown badge to the scheduled send time, a red urgent flag on anything due in the next 24 hours, the post copy, a thumbnail of the attached image, the social profile name and its network, the client the profile belongs to, who submitted the post, and the pre-check verdict chip if one exists. Default sort is scheduled send time ascending so the closest deadline is always on top. A filter bar across the top filters by client, social profile, network, and submitter, plus a toggle for due in the next 24 hours only. The header shows a running count of how many posts are waiting and how many are due inside 24 hours.

The board handler loads the queue with Retrieve Outbound Messages filtered to the pending-approval state over a rolling window, defaulting to 7 days back through 21 days ahead. Two constraints to bake in: that call requires both a start time and an end time and the range cannot exceed 4 weeks, so if the configured horizon is longer, page the board in consecutive sub-4-week windows and merge the results, following the cursor within each window. And if Hootsuite rejects the state filter (error 40019, message state filter not supported), fall back to fetching the window unfiltered and filtering to pending-approval in the handler. On each load also call Retrieve Social Profiles once and cache it, then join on social profile id so every row shows the real profile name and network instead of a bare id.

Client labels live in the app. A small Settings view lets an admin assign a client name to each social profile returned by Retrieve Social Profiles, and that mapping is stored in app storage. Rows display the client label and the filter bar groups by it, so an agency reviewing for six brands can narrow to one at a time.

Expanding a row fetches the freshest copy of that message with Retrieve Message and its review trail with Get Message Review History. The expanded panel shows the full post copy, the media attachment at full size, every target profile, and each prior review action with who took it, what they decided, and when.

Approve and Reject buttons sit on every row and in the expanded panel. Both Approve Message and Reject Message require the message's current sequence number, which increments on every review action, so the handler must call Retrieve Message immediately before acting and use the sequence number that call returns rather than anything the UI is holding. Reject opens a small dialog that keeps its confirm button disabled until the reviewer types a reason, and that reason is sent along with Reject Message.

Handle the race properly. If an approve or reject comes back with a state error (Hootsuite error 40003 means the message cannot be actioned in its current state) or the sequence number no longer matches, do not surface a raw error. Replace that row with a calm inline state reading "This post was already reviewed by someone else", show who reviewed it and the outcome pulled from Get Message Review History, and offer a Refresh board link. Give the same treatment when a message has simply dropped out of the pending set since the last load.

Permissions matter here. Hootsuite endpoint access is governed by the member's dashboard role, not by OAuth scopes, so a 403 with codes 4002 through 4010 means the viewer's role does not permit approvals rather than a missing scope. On load, work out the viewer's approval capability using Retrieve Authenticated Member and treat a permission-coded 403 from a review action as a definitive answer, then render Approve and Reject as disabled with a tooltip explaining their Hootsuite role does not allow approvals. Disable them, never hide them, so it is obvious why they cannot act.

Every row also gets a "Pre-check this post" button that kicks off a background agent. The agent takes the message id, pulls the full message with Retrieve Message, and reviews the copy against our house rules: no unapproved claims, every link present and resolving, copy inside the target network's length limit, and brand tone. It writes back a verdict of pass or flag, a one-line summary, and its reasoning rule by rule, stored in app storage keyed by message id so the board can show it. The row shows a pending chip while the agent is working and swaps to the pass or flag verdict when it lands, with the full reasoning readable in the expanded panel next to the post. The agent never approves or rejects anything itself; the human reviewer decides but arrives informed. Keep the house rules in the Settings view as editable text so a manager can change them without rebuilding the app.

When a rejection succeeds, post a note to our content channel with Slack Bot Send a Message so the creator sees it immediately: the post copy, the social profile and client, the time it was scheduled to go out, who rejected it, and the reason they typed. The target channel is configured in Settings.

Refresh the board after every successful action so the counts, ordering, and countdown badges stay honest, and make the whole morning queue clearable without a single page change.

Related prompts

Explore more prompts
A brand asset library your marketing team actually searchesTurn Mailjet email clicks into ranked HubSpot follow-upsClean out the Looker dashboards and Looks nobody opensLiveKit live operations console for room moderationWake up dormant Keap leads with a researched reasonLiveChat coverage board for planning next week's shiftsPhone routing control panel for LiveKit voice agentsLinkedIn Ads budget pacing dashboard for every client accountGive your team Looker numbers without buying more seatsPause marketing emails to escalated customers, then restore them