Turn Grain meeting action items into owned Asana tasks

By General Input

As soon as a Grain recording finalizes, an agent extracts every action item, files it as an assigned Asana task, and DMs you the list in Slack.

Integrations

  • Grain
  • Asana
  • Slack Bot

Type

Agentic Task

Categories

  • Operations
  • Sales

Build me an agent that triggers on a Grain webhook when a recording finalizes (recording_ready / recording.added) and turns every action item from the call into an owned Asana task, then DMs me a recap in Slack.

Trigger: Grain webhook for recording_ready. The payload includes the recording id.

Step 1, gather the source material from Grain. Use Get Recording on the recording id and request the workspace API enrichments: intelligence_notes, ai_summary, participants, highlights, and the recording's deep-link URL. Then call Get Transcript on the same recording id to get the full speaker-stamped transcript with timestamps. Prefer the structured 'Action items' section inside intelligence_notes when it is present (Business/Enterprise plans); fall back to extracting action items from the transcript and AI summary when it is not.

Step 2, decide whether to skip this meeting. If the participants list contains only people whose emails match our own workspace domains (no external participants), stop and do nothing. This rule should be configurable so the user can flip it off or change the 'internal' definition.

Step 3, extract action items. For each candidate, capture: the action text (rewritten as a short imperative task title), the owner mentioned in the call (name or email if spoken), any natural-language due date phrase from the conversation ('by Friday', 'next week', 'EOM', 'end of quarter'), and the verbatim transcript snippet (with its timestamp) that produced the item. Drop vague items with no clear owner and no concrete verb (e.g. 'follow up later').

Step 4, resolve owners against Asana. Call Get Users in a Workspace once to fetch the workspace roster, then match each spoken name/email against that list to get an Asana user GID. If no confident match exists, leave the task unassigned and surface the unresolved name in the Slack recap.

Step 5, pick the destination project. Call Get Multiple Projects in the workspace and apply simple keyword matching from the meeting title against project names (e.g. 'Acme' in the title → 'Acme Onboarding' project). If no project matches, use the user-configured default project. Both the default and the keyword map should be configurable.

Step 6, parse each due-date phrase relative to the meeting's start time and create the Asana task. For each action item, call Create a Task in the chosen project with: name = short imperative title, assignee = resolved Asana user (or unassigned), due_on = parsed date (omit if none), and notes containing (a) the verbatim transcript snippet that produced the item, (b) the speaker, (c) a deep link to that exact timestamp in the Grain recording, and (d) the recording URL itself. Use the recording's permalink format with the timestamp suffix that Grain supports.

Step 7, DM the meeting host in Slack. Look the host up by email with Look Up User by Email, Open a Conversation with that user to get the DM channel id, then Send a Message as the bot with a tidy bullet list: one line per created task showing the task title, the assignee (or 'unassigned' if not resolved), the due date (or 'no due date'), and a clickable link to the Asana task URL. Include a one-line header noting the meeting title and a link back to the Grain recording. If any owners could not be resolved, call those out explicitly at the bottom of the message so the host can fix them in seconds.

Failure handling: if Grain returns 404 for the recording (still processing), wait briefly and retry once. Never create duplicate tasks for the same recording id on retries; treat the recording id as the idempotency key.

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