How to Coda a notification center

Create a doc with one tasks only: notify

Christiaan Huizer

--

We all observe that Coda promotes collaboration and uses tables to keep track of tasks, meeting notes and so on. We all know that when you are in a doc, you can see everything in it. You can put info out of sight, but nothing more, the search bar will show you all there is, which is often great, but sometimes violates GDPR logic.

My main advice in many blogs is:

  • one task per doc
  • link docs via cross docs or a web hook logic
  • use native functions
  • limit packs

This all to reduce the inevitable complexity that comes on the back of any solution you craft in Coda. The tool is already difficult, to make the user experience suffer by adding avoidable complexity, you make it worse.

Coda has on workspace level no notification center where all your tasks and more are shown regardless of the docs they are in. Such a workspace would avoid you going to a doc you have no access to, but contains the required information you should act upon. You may not have access to all birthdates of everybody in your company, but you want to know when your team member’s birthday is. This dates live in a people doc managed by HR and you as manager have no access for good reasons.

A possible solution is to create for every team a doc and for every team a cross doc view showing only the people in the respective teams with the birthdates. You can do this for a few teams, but not for many. Complexity you know, you wouldn’t see the wood for the trees anymore.

I considered this solution, but as a consultant I’d like to create something robust, a solution others can maintain with the least effort.

Step 1 — set up notifications in source doc

We need a source table in the HR doc and a target table in the target doc. This time I use my own webhook based pack to communicate:

  • the date : this year, month & day
  • the user to notify — the team lead

In the source table we have a column with the birthdates this year, that is the one we use. We also need a text to tell if the birthday is today or is coming in a few days. Third we need a list of dates we can act upon. This is the difficult part I’ll elaborate on.

Creating the list of notification dates

I solved this problem already a while ago in a more complex set up. In this simple scenario we have:

  • the birthday this year
  • the rule to have a notification on the birthday
  • the rule to have a notification 3 days before the birthday
  • the rule: no notifications in the weekends
  • the rule: no notifications on official holidays
  • the rule to have a notification after the birthday when a birthday happens to be on a day off (weekend, holiday) and thus we have to take into account a scenario of a birthday on a Saturday when both Monday & Tuesdays are also days off and we need to notify on Wednesday with the correct message (bd of xx was yy days ago).

We need a formula to output a date that fits these scenario best at any given day.

Step01 — the birthday this year and the message

Our starting point

We have a person, we have a message and we have birthday this year. We start with the Birthday this year. We use the function Substitute() and the function goes as follows:

birthday.Substitute(birthday.Year(),ToDay().Year())

This is a good warming up. The weekday I show for testing purposes and is based on WeekdayName() which outputs only English weekday names. With AI you can always change outcomes in a separate column, may you feel the need.

The message relates to the function Today() as you can see below.

The message logic

I am used to apply Format() and that is what you see, however the main logic is the SwitchIf() and the understanding that a calculation with dates in Coda results in specific outcomes:

  • i.e. 5 days — future
  • - ( — present : we replace this ‘ -’ with a phrase: ‘that is today’)
  • i.e. 5 days ago — past

We use this logic in our SwitchIf() as you can see and logical operators define an outcome type ‘true or false’.

This part is not self evident, but good to follow. We move to the harder part.

Step 02 — getting the right date

We want two notifications, on the birthdate and 3 days before, but in case the birthday is on a day off, we cannot notify on that day, we take the first working day after.

This means we have two scenarios. Below I share the code you need, this is both difficult and complex due to the business rules. Important details on how the main part of this code operates you find in this previous blog.

SwitchIf(

// we check first if BD is not in a weekend or on a holiday, if so we take the first free day afer

thisRow.bdThisYear.Filter(CurrentValue.IsoWeekday().Contains(6,7) OR
[DB Holiday Dates].theDate.Contains(CurrentValue)).IsNotBlank(),

Sequence(thisRow.bdThisYear ,thisRow.bdThisYear + 6).ForEach(CurrentValue.WithName(theDateRanges,

theDateRanges.Filter(
CurrentValue.Contains([DB Holiday Dates].theDate).Not() AND
CurrentValue.IsoWeekday().Contains(6,7).Not()
))).ListCombine().First().ToDate().WithName(firstDateAfter,

// step 2, we get the days before and the BD on working days

List( thisRow.bdThisYear-3).WithName(root, // normal scenario
Sequence(1, root.Count()).ForEach(CurrentValue.WithName(dateNbr,
Sequence(
root.Nth(dateNbr),
root.Nth(dateNbr)-10).ForEach(CurrentValue.WithName(theDateRanges,

theDateRanges.Filter(
CurrentValue.Contains([DB Holiday Dates].theDate).Not() AND
CurrentValue.IsoWeekday().Contains(6,7).Not()
)
)
).ListCombine()
).First().ToDate()
).Sort()
).WithName(dateBefore,

ListCombine(dateBefore,firstDateAfter))).WithName(outcome,

If(Today() < outcome.First(),
outcome.First(),
outcome.Last())),

// below the standard scenario

List(thisRow.bdThisYear,thisRow.bdThisYear-3).WithName(root,
Sequence(1, root.Count()).ForEach(CurrentValue.WithName(dateNbr,
Sequence(
root.Nth(dateNbr),
root.Nth(dateNbr)-10).ForEach(CurrentValue.WithName(theDateRanges,

theDateRanges.Filter(
CurrentValue.Contains([DB Holiday Dates].theDate).Not() AND
CurrentValue.IsoWeekday().Contains(6,7).Not()
)
)
).ListCombine()
).First().ToDate()
).Sort()
).WithName(outcome,

If(Today() < outcome.First(),
outcome.First(),
outcome.Last())
)
)

When the BD is on a day off, we look forward and check for the first working day. We also want to have a notification 3 days before. I repeat, this combination increases complexity in our formulas.

two dates we communicate on the a birthday in a weekend or on a holiday day

The second and standard scenario I explained in the previous blog.

Step03 — a button

In this button we apply the webhook. Below the screenshot, it is a good to follow set up. You select the columns you want to push and that order you need to keep in mind in the target doc where the action is executed the moment the webhook is triggered. The URL and the token are stored in webhook table that stores all URLs and tokens related to all webhooks.

In this set up we can have multiple team leads because people are part of different teams at the same time. We generate per team lead a notification in the target doc.

Step04 — an automation

We have an automation running daily early in the morning pressing the web hook buttons. These buttons are active only when today matches the notification date. In that scenario a row is added in the target doc: the notification center.

a time based notification

Most people in these teams work in Europe, a few on the USA West Coast which is 6 hours late (normally) compared to Europe. To avoid a missed celebration I decided to work like this. Coda is not very smart with dates, times, time zones, weekdays etc. We often have to work around issues. I never understood why the Coda team decided to have two outcomes for one function all depending on your doc configuration. They should solve it yesterday.

step 2 — automations in notification doc / center

There are a few but I am going to restrict myself to the most important one, the webhook:

a webhook based automation

This one only runs when the buttons in the source doc are active. The second automation sends the notification. I normally would do that as part of the webhook using the data send via the webhook (because then you need a button). The logic as below is for most users not easy to follow.

 thisRow.[Step 1 Result].ParseJSON("$.column1"),

Instead I push the buttons in the table, that is all via a runActions(). The buttons do the rest. Every maker with a bit of experience understands this logic.

Step 3 — extending the functionalities

What we can do for birthdates, we can do for other information types as well. Take for example reminders on 1 month with us, 6 months with us, reviews etc. When the source data is sensitive (like a start date or a birth date) this set up works. By the way I implemented for a client both scenarios and I expect to see more use cases for this notification approach.

I hope you enjoyed this article. If you have questions feel free to reach out. My name is Christiaan and blog about Coda. Though this article is for free, my work (including advice) won’t be, but there is always room for a chat to see what can be done. You find my (for free) contributions in the Coda Community and on Twitter. the Coda Community provides great insights for free once you add a sample doc (without I am likely not helping you).

All the AI features we are starting to see appear — lower prices, higher speeds, multimodal capability, voice, large context windows, agentic behavior — are about making AI more present and more naturally connected to human systems and processes. If an AI that seems to reason like a human being can see and interact and plan like a human being, then it can have influence in the human world. This is where AI labs are leading us: to a near future of AI as coworker, friend, and ubiquitous presence. I don’t think anyone, including OpenAI, has a full sense of all of the implications of this shift, and what it will mean for all of us

coda brain — coda & snowflake

--

--

Christiaan Huizer

I write about how to Coda . You find blogs for beginners and experienced makers. I publish about 1 / week. Welcome!