Data Subscriptions is a standalone microservice for CKAN that allows users to subscribe to notifications of dataset changes. Notifications are available in several forms: web, email, and SMS (in development). Users can subscribe and unsubcribe to changes, configure the medium for notifications etc. It is feature complete and actively deployed in production.
The core job story is:
When I am interested in a given dataset I want to get notifications (in a dashboard, via email etc) when that dataset is updated (or other changes happen) so that I can take action e.g. update my application, check if security issue etc
For the end-users, it works like this:
Every 10 minutes, it communicates with CKAN Classic to store the latest updates in a local database. Every 30 minutes, it sends an aggregated notification to users. The worker sends notifications only to users with an active subscription to datasets changed in the past minutes. You can configure all the time frequencies via environment variables.
This service also has a REST API to:
To list all available routes in the app, you can run the following docker-compose command:
docker-compose run --rm web data_subscriptions routes
Base URI: /api/v1/
Endpoint: /nonsubscribable_datasets/<string:dataset_id>
By default, all datasets are subscribable. It is the data curator's work to disable subscriptions for a dataset.
Available methods:
GET - Check if a dataset is non-subscribable.POST - Make a dataset non-subscribable, i.e., disable subscriptions.DELETE - Delete a dataset from list of non-subscribable datasets, i.e., make it subscribable again.Endpoint: /subscription_status
Available methods:
POST - Check the a user's subscription status.
{"dataset_id": <string:dataset_id>, "kind": "DATASET", "user_id": <string:user_id>} //for a single dataset subscription{"kind": "NEW_DATASETS", "user_id": <string:user_id>} //for a new dataset subscriptionEndpoint: /subscription
Available methods:
POST - Subscribe a user to notifications.
{"dataset_id": <string:dataset_id>, "kind": "DATASET", "user_id": <string:user_id>, "username": <string:username>, "email": <string:email> } //for a single dataset subscription{"kind": "NEW_DATASETS", "user_id": <string:user_id>, "username": <string:username>, "email": <string:email>} //for a new dataset subscriptionDELETE - Unsubscribe a user from notifications.
{"dataset_id": <string:dataset_id>, "kind": "DATASET", "user_id": <string:user_id>} //for a single dataset subscription{"kind": "NEW_DATASETS", "user_id": <string:user_id>} //for a new dataset subscriptionEndpoint: /user/<string:user_id>
Available methods:
GET - Get list of subscriptions for a given authorized user.**Endpoint: /dataset/<string:dataset_id>
Available methods:
DELETE - Delete the subscriptions for given dataset.Endpoint: /stat
Available methods:
GET - Get report of all subscribers in JSON.GET - Get report of all subscribers in CSV.
download=yesTo setup the project using Docker containers:
$ make setup
The project is backed by a test suite, which can be run with a single command:
$ make test
Finally, to start the services and get to see the logs in real time:
$ docker-compose up
We do continuous deployment to Heroku via GitLab CI.
When using the data in this data portal I want to be notified (e.g. via email) when one of the key datasetsis updated so that I know to integrate that updated data with my workflow
As a sysadmin user, I want to be able to select (and deselect), from all the datasets on the portal, datasets that can be subscribed to, so that I can use this dataset level flag to build out email and text (sms) subscription services.
When an Admin of a data portal I want to view stats on subscriptions so that I can manage this and report to other stakeholders
When configuring the subscription system I want to be able to create and modify email template so that I can brand and customize the email user's receive
tuple(account, dataset, {event-type-filter}, [frequency?], ...)
tuple(account, filter-function-on-activity-stream)tuple(account, media[web|email|sms|newsletter], other options)Alternatively could seem them as any filter operation on an overall activity stream => leads us into event bus type territory …
In the most general sense, A "subscription" (for notifications) is a function f:
f(event stream) = user's event stream
And notifications are:
g(user's event stream, settings) => emails/sms etc
Required but probably external
Notes
sequenceDiagram
Frontend->>API: POST /subscription?dataset=123&account=qwe&event-type=xxx
API->>Authz: check authorization for {user, dataset}
Authz-->>API: OK
API->>DB: UPSERT INTO subscriptions {timestamp, account, dataset, event-type}
API-->>Frontend: HTTP 201 CREATED
Frontend->>Frontend: Update UI
INSERT INTO (dataset, eventType, message)sequenceDiagram
EventStream->>Notifier: POST /event
loop for xmedium in [email, sms]
Notifier->>SubsDB: SELECT FROM subscribers JOIN subs_settings WHERE dataset = ? AND eventType = ? AND medium = xmedium
SubsDB-->>Notifier: returns(account[])
Notifier-->>Settings: get Email/SMS Template
Notifier->>Emailer/SMS: send(account.email/mobile[], msg)
end
nonsubscribable_datasetssequenceDiagram
Frontend->>Frontend: is user logged in?
Frontend->>API: GET /is_subscribable?dataset=xxx?
API->>DB: SELECT NOT xxx FROM nonsubscribable_datasets
API-->>Frontend: yes/no [if no, done]
Frontend->>API: GET /subscription?dataset=123&account=qwe
API->>Authz: check authorization for {user, dataset}
Authz-->>API: OK
API->>DB: SELECT subscriptions {timestamp, account, dataset, event-type}
DB-->>API: return subscriptions[]
API-->>Frontend: return event-type or null
Frontend->>Frontend: showSubscribeUI(current-event-type | default-event-type)
NB: github has got a lot more complex over the years so user flow isn't quite as smooth as it once was.
graph TD
root[Profile Dropdown in navbar]
settings[Settings]
notifications[Notifications Subsection - config e.g. what medium]
watching[github.com/watching<br/>list of what you are watching]
dashboard[User dashboard<br/>prime info is notifications]
root --> settings
settings --> notifications
notifications --> watching
root --> dashboard



Content type
Image
Digest
sha256:a23dd30f3…
Size
387.6 MB
Last updated
over 3 years ago
docker pull datopian/data-subscriptions