Reads each new meeting's notes, pulls out who agreed to do what by when, and adds a task for each to Airtable.

UsesAirtableFireflies.aiGmailOpenAI

Turn meeting notes into tracked tasks

Once a day, the notes of your latest recorded meetings in Fireflies are read and the AI pulls out the follow-up actions people actually agreed to: the task, who took it on and any deadline stated. Each action becomes one row in your Airtable task tracker, so what was agreed on a call is tracked like any other work rather than forgotten.

Each row records the task, owner, due date, meeting title and meeting ID with a status of 'To do'. An owner is never invented: when the notes do not say who took something on, the row is filed under 'Unassigned' with the status 'Needs an owner', and a recap email lists those still needing an owner. Rows are only ever added, and a meeting whose ID is already in the table is skipped, so the same actions are never filed twice. If that check cannot be made, the meeting waits for the next run rather than risking duplicates.

Your Airtable table needs the columns 'Task', 'Owner', 'Due', 'Meeting', 'Meeting ID' and 'Status', spelled exactly.

ScheduleRun every day.Run every day.
ValuesSet taskBaseId to blank.Set taskBaseId to blank.
ValuesSet taskTableName to blank.Set taskTableName to blank.
ValuesSet recapEmail to blank.Set recapEmail to blank.
ValuesSet meetingsToCheck to 10.Set meetingsToCheck to 10.
ValuesSet tasksAdded to 0.Set tasksAdded to 0.
ValuesSet actionsNeedingAnOwner to an empty list.Set actionsNeedingAnOwner to an empty list.
Fireflies.aiFireflies.aiList Fireflies meetings. Save it as recentMeetings.List Fireflies meetings. Save it as recentMeetings.
Decisions & LoopsFor each meeting in recentMeetings.meetings:For each meeting in recentMeetings.meetings:
ValuesSet meetingId to blank.Set meetingId to blank.
Decisions & LoopsIf a step below fails, save the error as meetingIdErrorIf a step below fails, save the error as meetingIdError
Try
TextTrim meeting.id and save it as meetingId.Trim meeting.id and save it as meetingId.
On error
ValuesShow in the output: Skipped a meeting that came back without an id: meetingIdError as text.Show in the output: Skipped a meeting that came back without an id: meetingIdError as text.
Decisions & LoopsIf meetingId is emptyIf meetingId is empty
Yes
Decisions & LoopsSkip to the next item.Skip to the next item.
No
No steps
ValuesSet tasksAlreadyLogged to -1.Set tasksAlreadyLogged to -1.
Decisions & LoopsIf a step below fails, save the error as lookupErrorIf a step below fails, save the error as lookupError
Try
ListsCount the items in the records from the Airtable “List records” step and save it as tasksAlreadyLogged.Count the items in the records from the Airtable “List records” step and save it as tasksAlreadyLogged.
On error
ValuesShow in the output: Could not check whether meeting meetingId was already logged, so it is being left for the next run: lookupError as text.Show in the output: Could not check whether meeting meetingId was already logged, so it is being left for the next run: lookupError as text.
Decisions & LoopsIf tasksAlreadyLogged is not 0If tasksAlreadyLogged is not 0
Yes
ValuesShow in the output: Meeting meetingId was skipped - its actions are already in the tracker.Show in the output: Meeting meetingId was skipped - its actions are already in the tracker.
Decisions & LoopsSkip to the next item.Skip to the next item.
No
No steps
ValuesSet meetingNotes to blank.Set meetingNotes to blank.
Decisions & LoopsIf a step below fails, save the error as notesErrorIf a step below fails, save the error as notesError
Try
TextTrim the text from the Fireflies.ai “Get meeting transcript” step and save it as meetingNotes.Trim the text from the Fireflies.ai “Get meeting transcript” step and save it as meetingNotes.
On error
ValuesShow in the output: Could not read the notes for meeting meetingId: notesError as text.Show in the output: Could not read the notes for meeting meetingId: notesError as text.
Decisions & LoopsIf meetingNotes is emptyIf meetingNotes is empty
Yes
Decisions & LoopsSkip to the next item.Skip to the next item.
No
No steps
ValuesSet meetingTitle to blank.Set meetingTitle to blank.
Decisions & LoopsIf a step below fails, save the error as titleErrorIf a step below fails, save the error as titleError
Try
TextTrim meeting.title and save it as meetingTitle.Trim meeting.title and save it as meetingTitle.
On error
ValuesShow in the output: This meeting has no title; it will be logged as 'Untitled meeting'..Show in the output: This meeting has no title; it will be logged as 'Untitled meeting'..
Decisions & LoopsIf meetingTitle is emptyIf meetingTitle is empty
Yes
ValuesChange meetingTitle to Untitled meeting.Change meetingTitle to Untitled meeting.
No
No steps
ValuesSet extractionPrompt to You are reading the notes from one meeting and listing only the follow-up actions people actually agreed to.Set extractionPrompt to You are reading the notes from one meeting and listing only the follow-up actions people actually agreed to. Rules: - List an action only when the notes make both the task and the person who took it on clear. - Never guess an owner. If the notes do not say who owns an action, write the single word unassigned in the owner column. - Write the owner's name exactly as the notes give it. - One action per line, in the form: task | owner | due - Fill the due column only when the notes state a deadline. Otherwise leave it empty. - Do not add a header row, numbering, bullets, quotes, or any other commentary. - If nobody agreed to do anything, reply with the single word none. Meeting: meetingTitle Notes: meetingNotes truncated to 12000 characters.
ValuesSet agreedActions to blank.Set agreedActions to blank.
Decisions & LoopsIf a step below fails, save the error as modelErrorIf a step below fails, save the error as modelError
Try
TextTrim the response text from the OpenAI “Ask OpenAI” step and save it as agreedActions.Trim the response text from the OpenAI “Ask OpenAI” step and save it as agreedActions.
On error
ValuesShow in the output: Could not pull the actions out of meeting meetingId: modelError as text.Show in the output: Could not pull the actions out of meeting meetingId: modelError as text.
Decisions & LoopsIf agreedActions is emptyIf agreedActions is empty
Yes
Decisions & LoopsSkip to the next item.Skip to the next item.
No
No steps
TextSplit agreedActions by a new line and save it as actionLines.Split agreedActions by a new line and save it as actionLines.
Decisions & LoopsFor each actionLine in actionLines:For each actionLine in actionLines:
TextTrim actionLine and save it as actionText.Trim actionLine and save it as actionText.
Decisions & LoopsIf actionText is emptyIf actionText is empty
Yes
Decisions & LoopsSkip to the next item.Skip to the next item.
No
No steps
Decisions & LoopsIf actionText in lowercase is noneIf actionText in lowercase is none
Yes
Decisions & LoopsSkip to the next item.Skip to the next item.
No
No steps
Decisions & LoopsIf actionText doesn't contain |If actionText doesn't contain |
Yes
ValuesShow in the output: Ignored a line that was not in the 'task | owner | due' form: actionText.Show in the output: Ignored a line that was not in the 'task | owner | due' form: actionText.
Decisions & LoopsSkip to the next item.Skip to the next item.
No
No steps
TextSplit actionText by | and save it as actionParts.Split actionText by | and save it as actionParts.
TextTrim actionParts[0] and save it as taskText.Trim actionParts[0] and save it as taskText.
Decisions & LoopsIf taskText is emptyIf taskText is empty
Yes
ValuesShow in the output: Ignored a line with no task in it: actionText.Show in the output: Ignored a line with no task in it: actionText.
Decisions & LoopsSkip to the next item.Skip to the next item.
No
No steps
TextTrim actionParts[1] and save it as ownerText.Trim actionParts[1] and save it as ownerText.
TextMake ownerText lowercase and save it as ownerWord.Make ownerText lowercase and save it as ownerWord.
ListsGet the last item of ownerWord split by a space and save it as ownerLastWord.Get the last item of ownerWord split by a space and save it as ownerLastWord.
ValuesSet ownerIsUnknown to the length of ownerText is 0 or ownerWord is unassigned or ownerWord is unknown or ownerWord is tbd or ownerWord is n/a or ownerWord is none or ownerWord is team or ownerWord is everyone or ownerLastWord is team or ownerLastWord is everyone.Set ownerIsUnknown to the length of ownerText is 0 or ownerWord is unassigned or ownerWord is unknown or ownerWord is tbd or ownerWord is n/a or ownerWord is none or ownerWord is team or ownerWord is everyone or ownerLastWord is team or ownerLastWord is everyone.
ValuesSet ownerField to Unassigned.Set ownerField to Unassigned.
ValuesSet taskStatus to Needs an owner.Set taskStatus to Needs an owner.
Decisions & LoopsIf ownerIsUnknown is noIf ownerIsUnknown is no
Yes
ValuesChange ownerField to ownerText.Change ownerField to ownerText.
ValuesChange taskStatus to To do.Change taskStatus to To do.
No
No steps
ValuesSet dueText to Not stated.Set dueText to Not stated.
Decisions & LoopsIf the length of actionParts is greater than 2If the length of actionParts is greater than 2
Yes
TextTrim actionParts[2] and save it as statedDue.Trim actionParts[2] and save it as statedDue.
Decisions & LoopsIf statedDue isn't emptyIf statedDue isn't empty
Yes
ValuesChange dueText to statedDue.Change dueText to statedDue.
No
No steps
No
No steps
ValuesSet taskSaved to false.Set taskSaved to false.
Decisions & LoopsIf a step below fails, save the error as saveErrorIf a step below fails, save the error as saveError
Try
AirtableAirtableAdd a record to taskTableName.Add a record to taskTableName.
ValuesChange taskSaved to true.Change taskSaved to true.
On error
ValuesShow in the output: Could not add the task '@taskText' to your tracker: saveError as text.Show in the output: Could not add the task '@taskText' to your tracker: saveError as text.
Decisions & LoopsIf taskSaved is yesIf taskSaved is yes
Yes
ValuesAdd 1 to tasksAdded.Add 1 to tasksAdded.
Decisions & LoopsIf ownerIsUnknown is yesIf ownerIsUnknown is yes
Yes
ListsAdd - taskText (from: meetingTitle) to the end of actionsNeedingAnOwner and save it as actionsNeedingAnOwner.Add - taskText (from: meetingTitle) to the end of actionsNeedingAnOwner and save it as actionsNeedingAnOwner.
No
No steps
No
No steps
Decisions & LoopsIf tasksAdded is greater than 0If tasksAdded is greater than 0
Yes
ValuesSet recapBody to Added tasksAdded task(s) to your tracker from the latest meetings.Set recapBody to Added tasksAdded task(s) to your tracker from the latest meetings.
Decisions & LoopsIf actionsNeedingAnOwner isn't emptyIf actionsNeedingAnOwner isn't empty
Yes
ValuesChange recapBody to recapBodyThese actions did not name an owner in the meeting. They are logged as Unassigned and someone needs to pick them up:Change recapBody to recapBodyThese actions did not name an owner in the meeting. They are logged as Unassigned and someone needs to pick them up: actionsNeedingAnOwner joined by a new line .
No
ValuesChange recapBody to recapBodyEvery action found named an owner.Change recapBody to recapBodyEvery action found named an owner.
ValuesChange recapBody to recapBodyOpen your task tracker to review them.Change recapBody to recapBodyOpen your task tracker to review them.
GmailGmailSend an email to recapEmail.Send an email to recapEmail. Subject: Meeting actions added to your task trackerrecapBody
No
No steps