Show only the Airtable tasks your team can act on today

Get a weekday Slack list of Airtable tasks whose dependencies are complete, so the team can focus on work that is ready to move.

Automate.ax team7 min read

Integrations used in this example

Find the next useful task in a crowded base

An agency board can contain hundreds of tasks, many waiting on another piece of work. A long list of due dates does not tell the team what they can actually finish today.

This example reads every page of one Airtable task table, checks each task's linked Blocked By records, and posts a weekday Slack digest of To do or In progress tasks whose dependencies are Done. It reports the total ready count and shows the first 40 so the message stays readable.

An agency operator described roughly 400 Airtable tasks, many blocked by dependencies, and trouble seeing which tasks were actionable.Source: an agency's 400-task Airtable board

What you'll tell the agent

  • An Airtable task table with Name, Status, and a linked-record Blocked By field; an optional text Owner field adds ownership to the digest. The agent can inspect or create the schema.
  • A team Slack channel for the daily digest.
  • Account authorization for Airtable and Slack. Slack requires a paid workspace for the current Automate.ax connection.

The agent will create the project and ask you for these details. When Automate.ax asks you to connect an account, authorize the integrations you want this workflow to use.

The automation

The Airtable action follows every result page. A task is ready only when each linked dependency is present in the same table and marked Done.

airtable-actionable-task-digest.automation.ts
import { automation, onSchedule, t, transform } from "automate.ax"
import { airtable } from "automate.ax/airtable"
import { slack } from "automate.ax/slack"

export default automation(
  "Show the tasks that can move today",
  {
    parameters: [
      { label: "Airtable base ID", name: "baseId", type: "text" },
      { label: "Tasks table", name: "table", type: "text" },
      { label: "Slack team channel ID", name: "slackChannelId", type: "text" },
    ],
  },
  ({ parameters }) => {
    const tick = onSchedule({ schedule: "0 9 * * 1-5", timeZone: "UTC" })
    // No maxRecords: the action follows Airtable's result pages.
    const tasks = airtable.listRecords({
      baseId: parameters.baseId,
      table: parameters.table,
    })

    const digest = transform([tasks, tick], ({ records }) => {
      const byId = new Map(records.map((record) => [record.id, record]))
      const ready = records.filter((record) => {
        const status = record.fields.Status
        if (status !== "To do" && status !== "In progress") return false
        const dependencies = record.fields["Blocked By"]
        if (!Array.isArray(dependencies)) return true
        return dependencies.every((id) => {
          if (typeof id !== "string") return false
          const dependency = byId.get(id)
          return dependency?.fields.Status === "Done"
        })
      })
      const lines = ready.slice(0, 40).map((record) => {
        const name =
          typeof record.fields.Name === "string"
            ? record.fields.Name
            : record.id
        const owner =
          typeof record.fields.Owner === "string"
            ? record.fields.Owner
            : "unassigned"
        return `• ${name} — ${owner} (Airtable record ${record.id})`
      })
      return { count: ready.length, lines }
    }).filter(({ count }) => count > 0)

    slack.sendMessage({
      conversation: parameters.slackChannelId,
      text: t`${digest.count} tasks can move today. Showing the first 40:\n${digest.lines.transform((lines) => lines.join("\n"))}`.transform(
        escapeSlackText,
      ),
      unfurlLinks: false,
    })
  },
)

/** Keeps provider text from becoming Slack mentions or control markup. */
function escapeSlackText(text: string) {
  return text
    .replaceAll("&", "&")
    .replaceAll("<", "&lt;")
    .replaceAll(">", "&gt;")
}

What a run looks like

Example input

Task A is To do and depends on Task B, which is Done. Task C is To do and depends on Task D, which is still In progress.

Expected result

Task A appears in the Slack digest. Task C waits until Task D is Done.

Set it up

  1. Copy the setup prompt at the top into your coding agent.
  2. Ask the setup agent to inspect the Airtable fields and adjust the status names to match your base.
  3. Authorize Airtable and a paid Slack workspace, then compare the first digest with a few known blocked and ready tasks.

Check the result

Use test records with one complete dependency, one incomplete dependency, and one missing linked record. Confirm that only the truly ready task appears.

Where this workflow stops

  • The example assumes dependencies are linked records in the same table and status values are To do, In progress, and Done. Map different schemas before deployment.
  • The message displays the first 40 ready tasks and includes the full ready count. It does not assign or reorder work.
  • Airtable records with a missing dependency are treated as blocked rather than silently shown as ready.

Common questions

Will it check all 400 tasks?

Yes. Airtable's listRecords action follows all provider pages unless you set a maxRecords limit, which this example does not.

Does it change task status?

No. It reads the board and gives the team a short list of work that can move.

More automation examples