DEV Community

Cover image for How We Track Developers Speaking Opportunities at Percona, using Notion, Slack, and Python
Edi🦕
Edi🦕

Posted on

How We Track Developers Speaking Opportunities at Percona, using Notion, Slack, and Python

In developer relations, we constantly need to track CFPs and speaking opportunities across open source, cloud-native, programming, database, and developer events. Doing this manually takes time, and opportunities can easily be missed if deadlines are hidden across many websites or shared too late internally.

A big part of this problem is solved by developers.events, an open-source project created by my friend Aurélie Vache. It is a great source for discovering tech events around the world, both virtual and in person, and it is kept up to date with the support of the community.
It is also important to mention that the data JSON files used by developers.events are licensed under CC-BY-NC, which means they can be shared and adapted with attribution, but not used for commercial purposes. People and companies can sponsor the website or repository to support the project and help it continue growing. In 2027, developers.events will celebrate its 10th anniversary, an amazing milestone for an open-source community project.

How can I integrate it into my workflow?

I built an open-source tool that runs every day, finds every open Call for Papers from developers.events , serialises them using Python, tracks them in Notion, and pings your team on Slack. It has been super useful for us; we use the data, and we also help to add new entries directly in that source.
The project is on GitHub, and it is called Conference CFP Tracker. Here is how it works and how you can set it up for your own team.

You can also see all community events Percona is attending on our website:https://percona.community/

The Data Source: developers.events

developers.events aggregates CFP data from hundreds of community-driven tech conferences into two public JSON feeds:

This project is the main source of our tracker. All CFP data flows from here.

Conference CFP Tracker

The tracker is a Python pipeline that runs on GitHub Actions every morning at 04:00 UTC, and in summary, it does:

  • Fetches all currently open CFPs from developers.events
  • Merges them into a local JSON database (data/events.json) committed to the repo
  • Syncs the database to a Notion database, creating new entries, updating existing ones, and marking closed CFPs
  • Leaves the rest to your team: review the Notion board, mark promising CFPs as "Slacked", and a Notion automation posts them to your Slack channel automatically

The full pipeline looks like this:

developers.events (public API)
        ↓
  Fetch & filter open CFPs daily
        ↓
  Local JSON database (data/events.json)
        ↓
  Sync to Notion (create / update / close)
        ↓
  Team reviews → sets status to "Slacked"
        ↓
  Notion automation → posts to #speaking-opportunities on Slack

Enter fullscreen mode Exit fullscreen mode

Then our Notion database becomes the central hub for all open CFPs your team might care about.

Each row is a conference with its CFP deadline, event dates, location, and technology tags pulled directly from developers.events. The [CFP] Status column is where your team acts: you review the list, find relevant ones, and flip the status to Slacked.
When that happens, a Notion automation fires and posts to your team's Slack channel. This is an example of how it looks in Slack:

Anyone in the company can see it, react to it, or volunteer to give a talk.

How the Sync Works

Your Notion database can have two types of rows: events automatically imported from developers.events, and events your team added manually. The [CFP] Source field distinguishes them. The sync script only touches rows where [CFP] Source = developers.events, events manually entered by the team, are untouched.

For rows, the sync is careful:

  • Create: new CFPs appear with status Open and source developers.events
  • Update: only CFP Dates, CFP URL, and Technology are refreshed. Everything your team has edited, status, notes, and custom tags, is preserved
  • Reconcile: if a CFP no longer appears in the feed, its Notion row is automatically marked Closed

Here is how you can set it up

Prerequisites

  • Python 3.11+
  • A Notion account and workspace
  • A Slack workspace (for notifications)
  • A GitHub repository to host the code and run the Actions workflow

Step 1: Clone and Install

git clone https://github.com/your-org/conference-cfp-tracker.git
cd conference-cfp-tracker
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
Enter fullscreen mode Exit fullscreen mode

Step 2: Create Your Notion Database

Create a new Notion database with these properties. The names below match what we use at Percona. You can rename them, just update scripts/sync_notion.py to match.

Step 3: Connect Notion to the Project

You need a Notion internal integration to give the script API access to your database.

  • Go to https://www.notion.so/profile/integrations and create a new internal integration
  • Grant it: Can read content, Can insert content, Can update content
  • Copy the Internal Integration Secret. This is your NOTION_API_TOKEN
  • Open your Notion database → click ... (top right) → Connections → Add connection → select your integration
  • Copy the Database ID from the database URL; this is your NOTION_DATABASE_ID

Step 4: Set Up the Slack Automation

The Slack notification doesn't require any code; it runs entirely inside Notion as an automation.
Inside your Notion database, click Automate (top right) and create a new automation:

  • Trigger: [CFP] Status is set to Slacked
  • Action: Post to your Slack channel (we use #speaking-opportunities)

Once saved, it will appear in your automations list:

You can customise the message with something like this.

Step 5: Configure GitHub Actions

Add these two secrets to your GitHub repository under Settings → Secrets and variables → Actions:

  • NOTION_API_TOKEN
  • NOTION_DATABASE_ID

The workflow file at .github/workflows/daily-update.yml is already configured to use them. It runs every day at 04:00 UTC.
To trigger it manually at any time: go to Actions → Daily CFP Update → Run workflow.

Testing Locally

Before pointing the script at your live Notion database, test each stage locally.

Fetch only, no Notion required

python -m scripts.main --limit 10

This fetches 10 CFPs from developers.events and saves them to data/events.json. You'll see a table of events and a summary:

Run started at 2026-05-10 04:00:01 UTC
Updated data/events.json: total=10 | added=8 | updated=2 | closed=0

First 10 events (table):
Name                                         | External ID                          | CFP closes   | Link
---------------------------------------------+--------------------------------------+--------------+-----
KubeCon EU 2026                              | developers.events::kubecon...         | 2026-06-01   | https://...

Summary:
| fetched: 10
| added: 8
| updated: 2
| closed: 0
| cfp close window: 2026-05-15 → 2026-08-30
Enter fullscreen mode Exit fullscreen mode

Preview the Notion sync without writing anything

export NOTION_API_TOKEN='secret_...'
export NOTION_DATABASE_ID='xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
python -m scripts.sync_notion --dry-run --limit 10
Enter fullscreen mode Exit fullscreen mode

Output shows exactly what would happen, with no changes made:

[DRY-RUN] CREATE: KubeCon EU 2026 (https://kccnceu2026.sched.com)
[DRY-RUN] UPDATE: PyCon US 2026 (https://us.pycon.org/2026)
...
Summary:
| created: 8
| updated: 2
| processed: 10
| dry-run
Enter fullscreen mode Exit fullscreen mode

Apply to Notion
Start small to verify everything looks right:

# Small batch first
python -m scripts.sync_notion --reconcile-missing --limit 10

# Full run once you're confident
python -m scripts.sync_notion --reconcile-missing

Enter fullscreen mode Exit fullscreen mode

Important: Always test locally before running against a Notion database that already has data. And back up your Notion database before the first full run.

Day-to-Day Workflow

Once running, the team workflow is simple:

  1. Every morning, the GitHub Action fetches new CFPs and updates Notion automatically
  2. Someone on the DevRel team does a quick review of the Notion board, filtering by [CFP] Status = Open
  3. For CFPs worth sharing, they change the status to Slacked
  4. The Notion automation posts the CFP details to #speaking-opportunities on Slack
  5. Engineers who want to spea k can reply, react, or reach out directly

Adapting It to Your Team

The project is intentionally simple to adapt.

  • Different Notion field names? Update the property names in scripts/sync_notion.py in the build_properties() function.
  • Different Slack channel? Change it in the Notion automation UI , no code change needed.
  • Different status names? Update the [CFP] Status options in your Notion database and adjust the create_page() function in sync_notion.py to match.
  • Want to filter by technology or region? Add filtering logic in scripts/fetch_data.py after the fetch_and_clean() function builds the list.
  • No GitHub Actions? Run the scripts on any cron system, a VPS, or locally. The scripts are standalone Python scripts and have no platform-specific dependencies.

Open Source

This tool has been running for our events at Percona, and it is super helpful. We went from a manual weekly process to automated several steps with a daily pipeline that the whole team benefits from.
We share it because the problem is universal. Every DevRel team at every tech company deals with this.
The code is straightforward Python. The only external services are Notion (for the database and automation) and Slack (for notifications), both of which most tech teams already use. The data comes from developers.events, which is free and open.

Get Started

The project is here. Clone it, adapt the field names to match your Notion setup, add two secrets to GitHub, and the pipeline takes care of itself from there.
If you run into issues or have ideas for improvements, contributions are welcome.
You can contribute to developers.events adding event you are organising, or if you know some of the events that should be in this platform, the reach audience is huge.

Credits and thanks

  • Aurélie Vache, creator of developers.events, the open-source platform that makes this whole project possible
  • The developers.events community for maintaining the conference and CFP data that powers the feed
  • And thanks to Daniil Bazhenov (my collegue) for providing feedback for this project

Top comments (0)