Interacting with your Coda docs from anywhere

Coda allows you to create dynamic documents, including tables, formulas, and integrations with other apps.

But most of our work is done outside of docs. Switching between our work app and Coda can be time-consuming and error-prone. With Text Blaze, you can interact with your Coda docs from anywhere - read data from Coda and type it quickly or update your document as you're typing with important information.

Let us know what you think and share your own Coda snippets in the comments
Also, let us know with which other apps you'd like to use Text Blaze

Coda and Text Blaze · Interacting with Coda docs from anywhere - Watch Video

For this example, I used this public Coda doc which includes a task tracking table.

Screenshot 2022-12-13 at 11.58.21 AM

Interacting with the doc from anywhere

Getting started

  1. You'll need your Coda API key to start interacting with Coda using Text Blaze. Get it from your Coda account setting page. Click "Generate API token" under "Coda API tokens".
    Screenshot 2022-12-13 at 12.01.23 PM

  2. If you haven't already, make sure that you have the Text Blaze Chrome Extension installed.

  3. Copy any of these snippets to your dashboard, update the API key and try using them anywhere on the web.

  4. The first time you use one of these snippets, you'll be asked to configure your folder to be allowed to read and write data to Coda.
    Connecting a folder to Coda

Listing all open tasks

Quickly type an update about open tasks

Here are the tasks that are currently open:
{repeat: for task in `open tasks`} - {=task["Task name"]}, Assignee: {=task["Assignee"]}, Due date: {=split({=task["Due date"]}, "T")[1]} (Status: {=task["Status"]})
{endrepeat}{note: trim=yes}
{API_KEY="replace with your API key"}
{doc_id="IU9zjBEyAV"}
{table_id="grid-zWlGZ80Vvc"}
{column_map=["c-06GA7GheB_":"Task name", "c-eZqAWBtIrB":"Assignee", "c-lYEuP77-Zi":"Status", "c-9_S8vQnkwY":"Due date"]}
{urlload: https://coda.io/apis/v1/docs/{=doc_id}/tables/{=table_id}/rows; method=GET; done=(res) ->["rows":catch(fromJSON(res)["items"], "???")]; headers=Authorization: Bearer {=personal_access_token}}
{map_ids=(row)->[column_map[id]:value for (id, value) in row]}
{tasks=[map_ids(row) for row in map(rows, x->x["values"])]}
{`open tasks`=filter(tasks, task->task["Status"]=="In Progress" OR task["Status"]=="Pending")}{endnote}

Q: How do I get the doc id and table id?
A: See below for snippets that makes it easy to find the information?

Q: How did you create column_map - the mapping of column id to column name?
A: There's a snippet that does that as well below.

Create a new task

Send someone information about a new task and also create a new row in your Coda table

Hi {note}{formtext: name=assignee full name; default=Joe Smith}{endnote}{=split(`assignee full name`, " ")[1]}, I'm creating a new task - {formtext: name=task name} - and assigning it to you. The due date is set to {formdate: MMM D, YYYY; name=due date}. {status="Pending"}{note: trim=left}

{API_KEY="Replace with your API key"}
{doc_id="IU9zjBEyAV"}
{table_id="grid-zWlGZ80Vvc"}
{payload=toJSON(["rows": [["cells": [["column": "c-06GA7GheB_", "value": `task name`], ["column": "c-eZqAWBtIrB", "value": `assignee full name`], ["column": "c-lYEuP77-Zi", "value": status], ["column": "c-9_S8vQnkwY", "value": `due date`]]]]], "{rows: {cells: {column: string, value: string}}}")}
{urlsend: https://coda.io/apis/v1/docs/{=doc_id}/tables/{=table_id}/rows; method=POST; body={=payload}; headers=Authorization: Bearer {=personal_access_token}, Content-Type:application/json}{endnote: trim=yes}

Provide information about a given task

Select one task from the list and quickly type its current status

{note}{formmenu: default=Please select a task; name=selected_row_name; values={=map(rows, row->row["name"])}}{endnote}{if: selected_row_name<>"Please select a task"; trim=left}{=task["Task name"]}, Assignee: {=task["Assignee"]}, Due date: {=split({=task["Due date"]}, "T")[1]} (Status: {=task["Status"]}){endif}{note: trim=yes}

{API_KEY="Replace with your API key"}
{doc_id="IU9zjBEyAV"}
{table_id="grid-zWlGZ80Vvc"}
{column_map=["c-06GA7GheB_":"Task name", "c-eZqAWBtIrB":"Assignee", "c-lYEuP77-Zi":"Status", "c-9_S8vQnkwY":"Due date"]}
{urlload: https://coda.io/apis/v1/docs/{=doc_id}/tables/{=table_id}/rows; method=GET; done=(res) ->["rows":catch(fromJSON(res)["items"], "???")]; headers=Authorization: Bearer {=personal_access_token}}
{if: selected_row_name<>"Please select a task"; trim=left}
{selected_row=filter(rows, row->row["name"]=={=selected_row_name})[1]["values"]}
{task=[column_map[key]: value for (key, value) in selected_row]}
{endif}{endnote: trim=yes}

Snippets that work across any Coda doc and table

This snippet lists your docs and provides the doc id for the selected one

{API_KEY="Replace with your API key"}
{urlload: https://coda.io/apis/v1/docs; method=GET; done=(res) ->["docs":catch(fromJSON(res)["items"], "???")]; headers=Authorization: Bearer {=personal_access_token}}
{formmenu: default=Please select a doc; name=selected_doc_name; values={=map(docs, doc->doc["name"])}}
{if: selected_doc_name <> "Please select a doc"}
{selected_doc=filter(docs, doc->doc["name"]=={=selected_doc_name})[1]}
{selected_doc_id=selected_doc["id"]}
Doc ID: {=selected_doc_id}
{endif}

This snippet lists tables within a given doc and provides the id of the selected one

{API_KEY="Replace with your API key"}
{doc_id="IU9zjBEyAV"}
{urlload: https://coda.io/apis/v1/docs/{=doc_id}/tables; method=GET; done=(res) ->["tables":catch(fromJSON(res)["items"], "???")]; headers=Authorization: Bearer {=personal_access_token}}
{formmenu: default=Please select a table; name=selected_table_name; values={=map(tables, table->table["name"])}}
{if: selected_table_name <> "Please select a table"}
{selected_table=filter(tables, table->table["name"]=={=selected_table_name})[1]}
{selected_table_id=selected_table["id"]}
Table ID: {=selected_table_id}
{endif}

For a given table, this snippet creates a map between the column id and the column name

{API_KEY="Replace with your API key"}
{doc_id="IU9zjBEyAV"}
{table_id="grid-zWlGZ80Vvc"}
{urlload: https://coda.io/apis/v1/docs/{=doc_id}/tables/{=table_id}/columns; method=GET; done=(res) ->["columns":catch(fromJSON(res)["items"], "???")]; headers=Authorization: Bearer {=personal_access_token}}
{column_map=[x["id"]:x["name"] for x in columns]}
{=column_map}

Further reading

  • The Coda API documentation is here

These snippets use advanced Text Blaze commands such as:

  • {repeat} to iterate over a list
  • {urlload} to read data from the Coda API
  • {urlsend} to write data to the Coda API
  • keyed lists are used to store and access task information
  • The first snippet uses one function as a variable (map_ids) when iterating over the Coda API response to transform it to a more useable format
  • The split function is used to get the date from the due date format provided by Coda
  • The map and filter functions are used to transform lists
3 Likes

This is amazing work Dan! We've been doing a lot more with Coda recently and your team ceases to amaze me! :grinning:

One question, How would you apply the "Status" filter to the snippet with the drop down menu? I'd like for the menu to only show active titles.

Hey @Peter_Monterubio - I'll take a look over the weekend and get back to you

Hey @Peter_Monterubio
Here's an updated snippet that filters tasks (rows) from the table that have "in Progress" status. Let me know if this is what you're looking for.
I place all the table rows into a data structure and then filter it before populating the drop down menu. {data=[[column_map[key]: value for (key, value) in row["values"]] for row in rows]} <- this creates the data structure
{active_rows=filter(data, row -> row["Status"]="In Progress")} <- this filters for the ones that are in progress.

{note: trim=yes}
{API_KEY="ADD YOUR API KEY"}
{doc_id="IU9zjBEyAV"}
{table_id="grid-zWlGZ80Vvc"}
{urlload: https://coda.io/apis/v1/docs/{=doc_id}/tables/{=table_id}/columns; method=GET; done=(res) ->["columns":catch(fromJSON(res)["items"], "???")]; headers=Authorization: Bearer {=personal_access_token}}
{column_map=[x["id"]:x["name"] for x in columns]}
{urlload: https://coda.io/apis/v1/docs/{=doc_id}/tables/{=table_id}/rows; method=GET; done=(res) ->["rows":catch(fromJSON(res)["items"], "???")]; headers=Authorization: Bearer {=personal_access_token}}
{data=[[column_map[key]: value for (key, value) in row["values"]] for row in rows]}
{active_rows=filter(data, row -> row["Status"]="In Progress")}
{formmenu: default=Please select a row; name=selected_row_name; values={=map(active_rows, row->row["Task name"])}}{endnote: trim=yes}
{if: selected_row_name<>"Please select a row"; trim=left}
{selected_row=filter(rows, row->row["name"]=={=selected_row_name})[1]["values"]}
{=selected_row}
{endif}