-
Notifications
You must be signed in to change notification settings - Fork 46
Badge Issued Webhooks
In this guide we will demonstrate how you can respond to a badge being issued in your BadgeKit API webhook. If you followed the guides on Application Review Webhooks and Awarding Badges, you will be able to build what we do in this guide on your existing code. When an issuer calls on the BadgeKit API endpoints to issue a badge, an award
notification is sent to the webhook. You can then carry out any follow-up tasks you need, for example offering to push the earner's new badge to a backpack.
For an explanation of how assessment works in BadgeKit, see Assessment with BadgeKit.
The initial API guides will use node.js examples to demonstrate the key processes you need to connect BadgeKit to your own earner-facing site. Over time we will add to the guides with examples for other languages/ platforms.
- Overview
- Config
- Authentication
- Example Data Received
- Badge Issuing Flow
- Webhook Configuration
- Badge Actions
- The Award Action
- Processing the Award Data
- Assertion Data
- Communicating with the Earner
- Next Steps
Below is a detailed guide to using the API in the context of a node.js app - here's the short version!
To receive data at a webhook URL, you first need to add it to your BadgeKit API database, in the webhooks
table.
You can authenticate data received from the API at your webhook URL as follows:
- Verify the JWT token sent in the Authorization header - use the secret you included in the API
webhooks
table. - Check the hash sent in the Authorization header token against a hash of the received body data.
See the Authorization document for more.
Data sent to the webhook when a badge is issued includes the action
, uid
, badge
, email
, assertionUrl
, issuedOn
and comment
objects:
{
"action": "award",
"uid": "abcde12345",
"badge":
{
"id": 1,
"slug": "great-badge",
"name": "Great Badge",
"strapline": "Does great stuff.",
"earnerDescription": "This badge shows how great you are.",
"consumerDescription": "The earner of this badge is great.",
"issuerUrl": "issuersite.com",
"rubricUrl": "",
"timeValue": 0,
"timeUnits": "minutes",
"limit": 0,
"unique": 0,
"created": "2014-05-05T14:17:46.000Z",
"imageUrl": "http://issuersite.com/images/badge/1",
"type": "",
"archived": false,
"system":
{
"id": 1,
"slug": "badgekit",
"url": "http://systemsite.com",
"name": "Excellent System",
"email": null,
"imageUrl": null
},
"criteriaUrl": "http://issuersite.com/system/badgekit/badge/great-badge/criteria",
"criteria":
[
{
"id": 1,
"description": "Does great things often.",
"required": 1,
"note": ""
},
{
"id": 2,
"description": "Is generally great.",
"required": 1,
"note": ""
}
],
"categories":
[
]
},
"email": "[email protected]",
"assertionUrl": "http://issuersite.com/public/assertions/abcde12345",
"issuedOn": 1400094712,
"comment": null
}
BadgeKit API is designed to let you choose an issuing flow that suits your own community of earners. The following outlines the optional steps you can implement if you are letting your earners apply for badges:
- earner applies for badge
- badge application is reviewed
- review data is sent to webhook URL
- webhook emails earner, offering badge if application was a success
- earner chooses to accept the badge via the issuer site
- issuer site awards the badge:
- creates a badge instance
- marks the application as processed
- award data is sent to the webhook*
- issuer communicates with the earner*
- for example offering to push their new badge to a backpack
*In this guide we will demonstrate these parts of the process.
If you have not done so already, you need to configure a webhook for your BadgeKit instance by inserting a record in the API webhooks
table. Include the address at which you plan on processing the webhook notification, a secret to carry out authentication and the ID for the system the webhook is associated with. See the following example:
INSERT INTO 'webhooks' ('id', 'url', 'secret', 'systemId') VALUES (null, 'http://issuersite.com/hook', 'asecret', 1);
The sample node app we have been building requires the following resources:
var http = require("http");
var jws = require('jws');
var bodyParser = require('body-parser');
app.use(bodyParser.json());
var crypto = require("crypto");
var qs = require("qs");
In Application Review Webhooks we created a function in a node app in which we receive data sent from BadgeKit API. Our webhook function is included as follows:
app.post('/hook', function(req, res) {
//process hook data
});
The API sends notifications for a few different badging actions, including an application being reviewed and a badge being issued. In the application review webhook guide, we added a switch statement so that the same function could handle more than one of these actions. The review
hook code is as follows:
var action = req.body.action;
var info="";
var emailTo="";
switch(action) {
//review event
case 'review':
//earner email
emailTo=req.body.application.learner;
//build badge name into email
info+="<p>Your application for the following badge was reviewed:"+
"<strong>"+req.body.application.badge.name+"</strong></p>";
//respond differently if approved or not
if(req.body.approved){
info+="<p>Great news - your application was approved!</p>";
//include link to accept the badge
// - alter for your url
info+="<p><a href="+
"'http://issuersite.com/accept?badge="+
req.body.application.badge.slug+
"&earner="+req.body.application.learner+
"&application="+req.body.application.slug+
"'>Accept your badge</a></p>";
}
else{
info+="<p>Unfortunately your application was unsuccessful this time. "+
"You can re-apply for the badge any time though!</p>";
}
//review includes multiple feedback and comment items
info+="<p>The reviewer included feedback for you:</p>";
info+="<ul>";
//comment field includes everything in the Finish page in BadgeKit Web app
info+="<li><em>"+req.body.review.comment+"</em></li>";
//review items array, one per criteria - build into list
var reviewItems = req.body.review.reviewItems;
var r;
for(r=0; r<reviewItems.length; r++){
info+="<li><em>"+reviewItems[r].comment+"</em></li>";
//can also include whether each criteria item was satisfied
}
info+="</ul>";
info+="<p><strong><em>Thanks for applying!</em></strong></p>";
break;
}
As you can see, the review event builds the data received into an email to the earner, offering them the badge if their application was a success. We will be able to include a case
in the switch statement for the award
action. In Awarding Badges we created a badge instance - this is what will prompt the award
webhook to fire.
Let's add a section to the switch statement, after the break
statement for the review
case:
case 'award':
//process award hook
The action
will be award
when a new badge instance has been created. In this new case
section, we can process the data sent from the API. This is an example of the structure it will have:
{
"action": "award",
"uid": "abcdefghijkl123456789098",
"badge":
{
"id": 11,
"slug": "dowell-and-co-new-group-leader",
"name": "DoWell and Co New Group Leader",
"strapline": "The Group Leader badge acknowledges dynamic, effective leadership amongst peers in the realm of program facilitation.",
"earnerDescription": "The Group Leader badge communicates that you are a leader amongst your peers. With it you demonstrate that you have effectively performed at least four of the following skills at DoWell and Co - communication, delegation, organization, responsibility & ownership, and passionate commitment.",
"consumerDescription": "The DoWell & Co Group Leadership badge communicates important leadership values that we hold dear at DoWell & Co. Values that will serve an earner throughout their life. This badge represents breadth and depth of commitment to at least four of the five necessary leadership skills: communication, delegation, organization, responsibility & ownership, and passionate commitment. Along with the other DoWell & Co badges, particularly Group Management and Time Management, the earning of this badge acknowledges exemplary achievement of the highest sort at DoWell & Co for groups of 7-12 members.",
"issuerUrl": "dowellandco.co",
"rubricUrl": "",
"timeValue": 0,
"timeUnits": "minutes",
"limit": 0,
"unique": 0,
"created": "2014-05-14T17:34:16.000Z",
"imageUrl": "http://issuersite.com/images/badge/251",
"type": "",
"archived": false,
"system":
{
"id": 1,
"slug": "badgekit",
"url": "http://systemsite.com",
"name": "Best System",
"email": null,
"imageUrl": null,
"issuers":
[
]
},
"criteriaUrl": "http://issuersite.com/system/badgekit/badge/dowell-and-co-new-group-leader/criteria",
"criteria":
[
{
"id": 31,
"description": "The Group Leader badge recognizes achievement in the realm of program facilitation. It acknowledges dynamic, effective interaction with peers in the completion of a group project. Group Leaders possess some form of at least four of the following five skills: superior communication skills, effective delegation skills, advanced organization skills, personal responsibility & ownership skills, passionate commitment.",
"required": 1,
"note": ""
},
{
"id": 41,
"description": "This badge illustrates expertise in reaching goals involving complex collaborative environments of groups ranging in size between 7 and 12 members.",
"required": 0,
"note": ""
}
],
"categories":
[
],
"tags":
[
]
},
"email": "[email protected]",
"assertionUrl": "http://issuersite.com/public/assertions/abcdefghijkl123456789098",
"issuedOn": 1400094712,
"comment": null
}
Which data items you need will naturally depend on your own site. Note that the badge assertion URL is included in the assertionURL
field.
In our award
case statement, let's process this by building an email to the earner:
emailTo=req.body.email;
info+="<p>You've been awarded this badge:</p>";
info+="<img src='"+req.body.badge.imageUrl+"' alt='badge'/>";
info+="<p><a href='http://issuersite.com/viewBadge?assertion="+
req.body.assertionUrl+
"'>View Badge</a></p>";
//can offer to push to backpack etc
break;
We retrieve the earner email from the hook data received from the API. As a simple example, we include the badge image in the email and a link to the issuer site, passing the assertion URL as a parameter. In your own site you can then present the awarded badge within your environment. You can also offer to carry out any follow-up tasks you need at that point, such as pushing to a backpack.
For reference, this is the structure of what's at the assertion URL:
{
"uid": "123456789qwertyuio",
"recipient":
{
"identity": "sha256$12345678912346579abcdefghijklmnop",
"type": "email",
"hashed": true
},
"badge": "http://issuersite.com/public/systems/badgekit/badges/civics-participation",
"verify":
{
"url": "http://issuersite.com/public/assertions/123456789qwertyuio",
"type": "hosted"
},
"issuedOn": 1399994347
}
Note that although the user email is referenced, BadgeKit API only stores a hash of the email address for security. Sites looking to verify the earner of a badge can therefore hash the earner email and compare it to the value stored in the assertion.
After the switch statement, the code we created for the review
webhook email will also work for the award
webhook action:
var mail = require("nodemailer").mail;
mail({
from: "Badge Issuer <[email protected]>",
to: emailTo,
subject: "Badge",
generateTextFromHTML: true,
html: info // html body
});
This is the simple email we've outlined above:
You can then implement any processes you need at the URL you included in the email. Of course you may alternatively wish to simply encourage the earner to log into your site and process their badge data there.
The award
webhook represents the final stage in the process of using BadgeKit API to facilitate earner applications for badges through an issuer site. If you are using the BadgeKit Web app, it handles some parts of the process (creating badges, storing applications, submitting reviews). By using the endpoints in conjunction with this functionality, you can implement all of the parts in a typical badge issuing system.
Coming next: a guide to using claim codes with BadgeKit, including the claim
webhook.
For support working with BadgeKit or Open Badges, use any of the following channels:
- Post general questions in our Community Google Group and post technical questions in our Dev Google Group.
- Reach members of the Open Badges team directly on IRC (irc.mozilla.org) on the #badges channel.
- Email questions directly to [email protected] and a member of the team will follow-up.
- Follow or tweet the Open Badges team @OpenBadges.
- Get involved or submit issues via the GitHub repos - feedback is always appreciated!