Request: Live Trello Updates (Webhooks)

Live updates of trello goals pretty please? For us skate the YBR people. Currently the Beeminder bot pretends that nothing happened in Trello land until right on the deadline.
So logically the bot shouts at you constantly because supposedly you ain’t doing anything from its point of view.

Have a look at this:

we have built a system that allows your application to hook into updates on various members such as Boards, Lists, and Cards. Whenever a member with a Webhook is changed, we make an HTTP request to the endpoint of your choosing.

More about that: Redirecter

Also in case this didn’t exist when you made the Trello integration in the first place: client.js Reference

1 Like

What happens if you hit refresh in a Trello goal, rather than waiting for autodata to grab on its own schedule?

1 Like

Then it grabs the data as expected. While this certainly helps to calm the bot, I don’t want to have to do this.
And the webhooks api looks really nice :upside_down_face:

1 Like

I couldn’t resist, went ahead and made this. I’m a bit surprised it was that easy (33 minutes), but the trello API documentation is excellent and so is the Beeminder API documentation. Together with the really nice vs code REST client extension I quickly hacked together something that does trigger a data fetch via webhook:

Code
@APIKey = your_trello_api_key
@APIToken = your_trello_api_token
@tbase = https://api.trello.com/1

@bbase = https://www.beeminder.com/api/v1
@bauth = your_beeminder_auth_token
@u = your_user
@g = your_slug
@refresh = {{bbase}}/users/{{u}}/goals/{{g}}/refresh_graph.json?auth_token={{bauth}}

### Get trello boards
# @name getBoards
GET {{tbase}}/members/me/boards?key={{APIKey}}&token={{APIToken}}

### Now we got the id of the relevant board
@boardId = {{getBoards.response.body.$[?(@.name=='your_board_name')].id}}

# @name createHook
POST {{tbase}}/tokens/{{APIToken}}/webhooks/?key={{APIKey}} HTTP/1.1
Content-Type: application/x-www-form-urlencoded

description=refresh graph
&callbackURL={{refresh}}
&idModel={{boardId}}

###

@hookId = {{createHook.response.body.$.id}}

### This gave us a hook
# which we can look at
GET {{tbase}}/tokens/{{APIToken}}/webhooks/{{hookId}}?key={{APIKey}} HTTP/1.1

### and finally delete again
DELETE {{tbase}}/tokens/{{APIToken}}/webhooks/{{hookId}}?key={{APIKey}} HTTP/1.1

### List all webhooks just to make sure we got them all
GET {{tbase}}/tokens/{{APIToken}}/webhooks/?key={{APIKey}} HTTP/1.1

Paste this into VS Code, throw this extension at it and you should be good.

Since the Beeminder API docs are very explicit about not doing this too often I included a snippet to delete the webhook again.
Ideally one would directly PUT the new data point value into Beeminder instead of merely telling the api to refresh. But hey for a good half an hour I’m quite pleased.

2 Likes

The attentive reader might have already guessed that there is a slight problem with the slapdash code I posted POSTed.
But for those who did not GET it, here’s a quick rundown:
Trello sends web hooks using POST but Beeminder does not expect a POST for refreshing goals but a GET and only that. And that’s really all there is to it.

The upside is that in that POST Trello does actually provide a lot of details about what action triggered the hook. I’m pretty sure there’s everything in there that Beeminder would need to update the goal without it having to query anything else.

Obviously that’s another code path that needs implementing, testing, etc. but IF processing time and bandwidth ever are a concern then maybe this will compare favourably to simply refreshing the entire goal.

I sat down and wrote a tiny web service which listens for a POST and sends a GET to Beeminder causing the goal to refresh.

I quickly threw it onto my VPS and this is how you use it:

POST http://doerfler.io:8027/refresh/goalygoal?auth_token=foobar HTTP/1.1

So set this up as your webhook in Trello, put your goal name in there and your auth_token and Bob’s your uncle.

Except don’t. Because right now it’s just running HTTP without TLS so your precious auth_token would be totally exposed. That’s gonna change eventually, though.

Even with TLS, people would still be giving you auth_tokens…

Yeah switching to OAuth is the next thing right after adding TLS.

Of course if either Trello would use GET for their hooks or Beeminder would (also) listen for POST none of this would be necessary in the first place.
This is all just an elaborate band aid for anyone who is bothered by stale data as much as I am.

@adamwolf ok I’m a bit torn on this. I see basically two options:

  1. I leave it as it is right now which means anyone who wants to use it can clone the repo and host the web service themselves (which is super easy) or use my hosted instance trusting I won’t do shenanigans with their auth_token. Oauth or not doesn’t change that an auth_token is necessary to refresh graphs.
  2. I make this into a dockerfile/image and Beeminder hosts it? Is that unreasonable? That way the trust question would be out of the way.
    I could flesh this out a bit so that it also talks to Trello and registers the web hook on its own if ya want but that’s not super high on my priority list right now.

I’m gonna take a wild guess that it’s gonna end up with option 1 but I’m just throwing this out there. Surprise me! :slight_smile:

Edit: I mean clearly the Beehive got bigger fish to worry about such as the yellow brick halfpipe (I’ll just keep calling it that way) or the interactive graphs and all that. And the even easier option would, again, be to just make refresh_goal.json also listen for POST. So hosting another component probably does not make terribly much sense right now. Yeah. I’m kinda talking myself out of it.

I have quite a few integrations just like that, and I haven’t yet jumped the hurdle myself. I wish Glitch and such were 30% easier for non engineers to use.

I do not have a clear idea of how I think you should go forward. Maybe one of our glorious founders could pop in?

1 Like

Marvellous idea! Alloweth us summon those folk f’r those ladies and gents might knoweth!
@bee and @dreev enlighten us f’r we knoweth not the way!

Is it true that Oauth’ed applications can’t refresh a graph? Maybe that’s a UVI worth tackling quick…

1 Like

Maybe there is a misunderstanding here. As far as i read the Beeminder API you still get an auth_token when using Oauth, but not necessarily the auth_token. In theory Beeminder could hand the app a less powerful token. I don’t know if it does. Does it?

BTW and if I remember correctly the Oauth spec is very explicit about not putting auth information into the URL because those tend to get treated “less securely” than the rest of the request (even on HTTPS). Beeminder allows the auth_token in the body at least for POST endpoints iirc. The API docs have an example somewhere. Still the majority of examples have it simply as query parameter.
I don’t think it’s the biggest problem, but at least worth pointing out while we are at it.

1 Like

@adamwolf I read it wrong! Haha!

It gives you an access_token, not an auth_token. They look… strikingly similar and my brain went ahead and merged both into one I suppose. But if this note is any indication I am in good company:

Note: A common mistake is to pass the personal auth token but call the parameter access_token, or vice-versa. The parameter name for your personal auth token should be auth_token.

Of course at the end of the day this doesn’t prove a thing about whether this has any consequences for refreshing graphs (and neither did my previous interpretation of the API) so I might as well stop writing now.

Nope, definitely not true! Oauth’ed applications can most definitely refresh a graph. I added oauth to mine and the response very much looks like without oauth.
Adding oauth was btw a purely academic exercise because let’s face it, other than me nobody is going to use this and I was perfectly fine with using the auth_token and also oauth requires me to actually store the access_token whereas the auth_token just passed through and was not stored (other than maybe in the logfile of the nginx which provides SSL because it’s part of the query string instead of being in the body).