Skip to content

Import Action Network events (incl. campaign events) with scheduled refresh#462

Merged
joaquimds merged 1 commit into
mainfrom
feat/action-network-events
Jul 23, 2026
Merged

Import Action Network events (incl. campaign events) with scheduled refresh#462
joaquimds merged 1 commit into
mainfrom
feat/action-network-events

Conversation

@joaquimds

Copy link
Copy Markdown
Member

What

Adds event import to the Action Network data source adaptor (previously people-only), plus a daily scheduled refresh since Action Network has no events webhook.

Why the two-crawl approach

Action Network events live in two places: the flat /api/v2/events collection and inside event campaigns (/event_campaigns/{id}/events). Some events only appear via a campaign. Verified against a real key:

Set Events
Flat /events 12
Distinct across campaigns 27
In both 2
Only reachable via campaigns 25
Total union 37

Importing from /events alone would miss ~68% of events. So the adaptor crawls campaigns first (capturing each campaign's title), then the flat collection, deduping by event id. A live run of the adaptor yielded 37 events, all geocoded, 27 with campaign names, zero duplicates.

Changes

  • Config: recordType: "people" | "events" on the Action Network config (defaults to people), with a migration backfilling existing sources to people.
  • Adaptor: two-crawl + dedupe event fetch; normalizeEvent flattens title/dates/status/venue/address/postcode and Action Network's server-side coordinates; fetchFirst works for campaign-only orgs; events are read-only (no write-back / tagging).
  • Create flow: event sources default to Coordinates geocoding on latitude/longitude with title as name and start_date as date column — map-ready with no geocoding pass.
  • UI: People / Events selector in the new data source form.
  • Scheduled refresh: importActionNetworkEventDataSources sweep job (mirrors importZetkinDataSources), registered in the worker and scheduled at 5am daily.
  • Tests: mocked unit tests for the crawl/dedupe/read-only behaviour.

Scope

Read-only import (no attendances/RSVPs, no write-back) and daily cron refresh (no live webhook — Action Network doesn't offer one for events).

Migration

Run npm run migrate to apply 1784819176587_action_network_config_record_type.

🤖 Generated with Claude Code

…uled refresh

Action Network data sources can now import events, not just people. Events
can live in two places — the flat /events collection and inside event
campaigns — and some events only appear via a campaign, so the adaptor crawls
event campaigns first (capturing each campaign's title) then the flat
collection, deduping by event id. Events arrive geocoded by Action Network, so
new event sources default to Coordinates geocoding with title/start_date roles.

Events have no webhook, so they are kept up to date by a daily scheduled
re-import sweep, mirroring how Zetkin sources are refreshed.

- Add recordType ("people" | "events") to the Action Network config, with a
  migration backfilling existing sources to "people"
- Two-crawl + dedupe event fetch, normalizeEvent, read-only guards
- importActionNetworkEventDataSources sweep job, registered + scheduled at 5am
- People/Events selector in the new data source form
- Mocked unit tests for the crawl/dedupe/read-only behaviour

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@joaquimds
joaquimds merged commit feea96d into main Jul 23, 2026
1 check passed
@joaquimds
joaquimds deleted the feat/action-network-events branch July 23, 2026 15:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant