A watchful tree and extensible Slack messenger to keep you informed of how your civic tech projects are being used.
Not everything that can be counted counts, and not everything that counts can be counted. (Albert Einstine, on the wall of his study in Princeton. Quoted in Can We Know Better?, Robert Chambers, 2017)
This project is an attempt to get useful information about how a project is used, to the people who maintain, run, and build it.
While working on PlanningAlerts we’ve noticed that:
Jacaranda is an experiment to see the impact of regular feedback on the people developing PlanningAlerts. It aims to keep you more informed of the use and impact of PlanningAlerts; to remind you of the effort you’ve put in to achieve this; and to do this in an quick and unobtrusive way.
Jacaranda collects information about people using PlanningAlerts and the work we do to make it better for them. It then sends a short fortnightly message to our Slack channel to give us a sense of how things are going.
This is a very basic start. We’ve interested to see how getting these messages impacts us and what we do with the information.
Currently Jacaranda tells you about:
While the number of users isn’t a great measure of PlanningAlerts’ impact, it’s a start to see how the feedback works for us. Feel free to change the text or the information in presents to what you think will have a better impact.
The time frames that this claims to show subscribers for aren’t accurate because they're displayed as it they were recorded in local time, but they're actually counted in UTC.
Currently Jacaranda tells you about:
Ensure you have Ruby + Bundler installed, then run:
git clone https://github.com/openaustralia/jacaranda.git
cd jacaranda
bundle
Then run the scraper with:
bundle exec ruby scraper.rb
And run the tests with:
bundle exec rspec
This scraper requires these environment variables:
MORPH_SLACK_CHANNEL_WEBHOOK_URL
to post the message to a channel in Slack. You can get a URL by adding an Incoming Webhook customer integration in your Slack org.MORPH_LIVE_MODE
determines if the scraper actually posts to the Slack channel #townsquare
and save to the databaseWhen developing locally, you can add these environment variables to a .env
file so the scraper loads them when it runs:
MORPH_SLACK_CHANNEL_WEBHOOK_URL="https://hooks.slack.com/services/XXXXXXXXXXXXX"
MORPH_LIVE_MODE=false
Create a .env
file using the supplied example by running:
cp .env.example .env
Then edit to taste.
You can also run this as a scraper on Morph.
To get started see the documentation
You can optionally set MORPH_RUNNERS
to choose what runners are executed. Go to the settings page of the scraper, and set the value to be a comma separated list of runners:
RightToKnow,PlanningAlerts
Jacaranda has a very simple model for adding new runners.
Runners pull information from (sometimes multiple) sources, and posts a message into Slack.
To add a new runner, create a file in lib/runners/
and define the following class:
# lib/runners/my_service.rb
module MyService
# A new runner for my new service
class Runner < Jacaranda::BaseRunner
class << self
def build
[
'My text here.'
]
end
end
end
end
Then run the scraper:
MORPH_LIVE_MODE=false bundle exec ruby scraper.rb --runners MyService
Note: The --runners
option is used only in development. Morph will run the scraper with no arguments.
*Note: You can use the --list-runners
option to get a list of all runners Jacaranda knows about.
You'll see output something like this:
These are the runners we will execute:
MyService
[MyService] We have not posted an update during this fortnight.
[MyService] Not posting to Slack.
[MyService] Not recording the message in the database.
> My text here.
That's it.
While displaying some static text is a nice start, you'll want to call out to your app to pull information in:
# lib/runners/my_service.rb
module MyService
# A new runner for my new service
class Runner < Jacaranda::BaseRunner
class << self
def build
[
MyService::Website.status_text(period: last_fortnight),
]
end
end
end
end
We're using a built-in helper method called last_fortnight
to give us a date range for the last fortnight:
last_fortnight # => [ Mon, 31 Jul 2017, Tue, 01 Aug 2017, ... ]
We pass this as the period
parameter to the status_text
method on the Website
class.
Both the MyApp
class and status_text
method don't exist yet. Let's add them:
# lib/runners/my_service.rb
# MyApp stats from MyApp
module MyService
class Website
class << self
def status_text(period:)
[
':tada:',
count('requests:new', period: period),
'new requests were made through My Service in the last fortnight.'
].join(' ')
end
def count(query, period)
start = period.first
finish = period.last
# Make a call out to your service here ...
end
end
end
end
The status_text
method is very simple – it accepts a time period it needs to produce text for, and returns a string of text.
Typically there is a count
method used to get hit some endpoint or scrape some pages, and generate aggregate statistics. The exact implementation is up to you! Check out the PlanningAlerts
and RightToKnow
runners to see some more complex use cases.
The Jacaranda Slack avatar is cropped from a photograph of the Jacaranda trees on Gowrie St, Newtown, Sydney by Flickr user murry. Thanks murry for making it available under a creative commons license.