This integration makes an HTTP request and fetches the datapoint value from the JSON response (and uses a secret key stored in the .env
file).
The fields and endpoints for integrations are defined in JSON. Here is an example of the format, with comments, that Akrasia uses to include an integration:
// This is an example of the JSON that Akrasia will
// use to configure the integration
{
// The key is a unique slug that identifies each integration:
"beeminder_forum_posts": {
// The title of the integration (to be displayed to users):
"title": "Beeminder Forum Posts Count",
// The description of the integration
// (to be displayed to users) (optional):
"description": "Use an odometer goal for this integration.",
// The endpoint that Akrasia will call (via POST request)
// when it wants a new datapoint fetched. See server.js
// for an example implementation to handle this request.
"fetch_url": "https://forum-minder.glitch.me/fetch",
// The configuration/options for this integration.
// Akrasia will ask users to provide these fields
// when setting up the integration. These values
// will be passed to the fetch_url when Akrasia
// makes a request. All values will be passed as
// strings. Parsing and validation should be done
// by the integration's fetch endpoint.
"fields": {
// A unique key for each field. (Fields will
// be in request.body.user_options.field_key
// when passed to the integration fetch endpoint)
"forum_username": {
// The name of the field (to be displayed to users)
"name": "Beeminder Forum Username",
// Additional description for the field
// (to be displayed to users) (optional)
"description": "Your Beeminder Forum username."
}
}
}
}
If you make a new integration following these patterns, let me know and I can add the definition for the integration to Akrasia.
When Akrasia receives an autofetch request from Beeminder, it makes a POST
request to the integration’s fetch_url
, with the user’s configs for the integration in the request body (as JSON) in the following format:
POST <your_integration_fetch_url>
{
"session": "some-random-uuid",
"user_options": {
"my_field_name": "user's input value for my_field_name"
}
}
The fetch endpoint handler can then pull these details from the request body (this example is in Node.js and Express):
app.post("/fetch", function(request, response) {
// Get the session and user options from Akrasia's request
var callbackSession = request.body.session;
var userOptions = request.body.user_options;
// Get the user's forum name (set and stored through Akrasia)
// from the passed options
var forumUsername = userOptions.forum_username;
The session
value (also passed by Akrasia in the request body) is used in the POST
request back to Akrasia (after the integration has done its logic and gotten the datapoint) and is used to map the datapoint back to the corresponding Beeminder user and goal. The integration should POST
to the following endpoint with a JSON body in the following format when it is ready to add the datapoint:
POST https://akrasia.on.csu.io/integrations/callback
{
"session": "the-session-received-earlier",
"result": {
"value": 3.0, // the datapoint value
// other permitted keys here are:
// timestamp, daystamp, comment, requestid
// (see Beeminder API documentation for what they do)
}
}
Finally, here are some screenshots of what this ends up looking like to the user.
After logging in, the user sees their goals, along with which Akrasia integrations are connected, if any:
After clicking “Add” on a goal, the user is presented with a list of all the integrations Akrasia knows of:
After selecting an integration to add, the user is presented with a form to input the options/fields needed for the integration (the form fields come from the JSON definition for the integration):
And that’s it! If you have any questions, feel free to contact me.