Webhook API
ShMcK opened this issue · 7 comments
Webhooks are a way for apps to communicate between them automatically.
Requirements
- default url
- optional url overwrites
- token based authentication
Config
CodeRoad could send HTTP POST requests to a target endpoint based on desired events. A Webhooks can be specified in the CodeRoad config.
config:
webhook:
endpoint: “https://api.com/api/v1/coderoad”
headers:
x-token: $CODEROAD_WEBHOOK_TOKEN
events:
init: false
reset: false
step_complete: true
level_complete: true
tutorial_complete: trueEvent
An suggested example webhook POST request
{
"type": “step_complete”,
"levelId": “some-level-id",
"stepId": “some-step-id”,
"tutorialId": "some-tutorial-id"
}Authentication
Authentication: we will need a standardized format for using a CODEROAD_WEBHOOK_TOKEN, perhaps a global string variable that can be passed in and evaluated.
Ideally not having to interpret a string, like "Bearer $CODEROAD_WEBHOOK_TOKEN", would save some development time.
Follow Up
This proposal could later be followed up with:
- webhook error handling
- retry strategy
- batch processing
I have a few questions about using level/step ids. If a tutorial is changed, these will update. The webhook API would be expected to understand which level/step id it is mapped to. Let me know if this is a problem.
Resources
I have a few questions about using level/step ids. If a tutorial is changed, these will update. The webhook API would be expected to understand which level/step id it is mapped to. Let me know if this is a problem.
I'm not sure I understand what's being asked here. If a user completes a step, maybe step 50 - then I have to go change step 50 to step 51 and create a different step 50. I suppose it would show that they already finished 50, and 51 would show up as not finished? I don't really see a problem with that.
I had a thought that maybe the best way to go would be to just have one event at the end when a tutorial/project is finished. The whole thing is either done, or it's not. It would simplify things a bit. Although, it would be nice to maybe show the progress on a tutorial as well.
A single event at the end of the tutorial would be simpler.
I suppose the value to knowing progress would be to include a progress bar, or to identify areas where users might struggle or drop off.
I've been working on this on my end - I have basically generated tokens for users. I think we will need to have them copy and paste it into CodeRoad. Or any other thoughts @ShMcK? How would I get it into the config of the repo? Not sure that's possible. We could set it as an env variable by passing it to CodeAlly, which then passes it to you or adds it as an env variable. I was leaning towards the copy/paste method for now.
So the config might be:
config:
webhook:
endpoint: “https://freecodecamp.org/api/...”
events:
init: false
reset: false
step_complete: false
level_complete: false
tutorial_complete: true
And the request body:
{
"type": “tutorial_complete”,
"tutorialTitle": "title_of_tutorial"
}
And the token they pasted would be in the header or body or something. By using the title of the tutorial, we could control if/when they change or what they are on our end. When you mentioned using the id's, would that be the commit hashes? or maybe some additional property in the markdown?
Edit: ahh, they would be the numbers of the levels/steps - 1.1, 2.1, etc...? So what would the tutorialId be? Those don't have a number - the title works for me, but if you have any other thoughts - let me know.
Also, I was planning on just having the one event for when an entire tutorial or project is complete for now. Hopefully that makes it a little easier.
I've drafted up a pull request (in progress), @moT01 I'd love your feedback.
Here's an example of the events for init/step/level/tutorial complete
init - {"tutorialId":"coderoad/fcc-learn-npm:v0.4.2", coderoadVersion: "0.14.5" }
step - {"tutorialId":"coderoad/fcc-learn-npm:v0.4.2", "levelId":"4","stepId":"4.1"}
level - {"tutorialId":"coderoad/fcc-learn-npm:v0.4.2",, "levelId":"4"}
tutorial - {"tutorialId":"coderoad/fcc-learn-npm:v0.4.2" }
Is the tutorialId sufficient? You can parse out the name and the version separated by :v.
In regards to how to identify the user, I was thinking of two options.
I was thinking you could pass in a CODEROAD_WEBHOOK_URL that includes the users id
An example: "https://some-url.com/user/1234/coderoad_hook`
The router should be able to parse out the user id as a request param.
Setup the webhook URL in the config, as you showed above.
Pass in the user id as an env variable
Then I would pass that in the event body as `{ userId: '1234' }
Here's an example of the events for init/step/level/tutorial complete
I can work with that 👍
Completed, ready for next releaser