Skip to content
This repository has been archived by the owner on Sep 2, 2020. It is now read-only.

Badge Issued Webhooks

SueSmith edited this page Sep 28, 2014 · 9 revisions

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. BadgeKit will not contact the earner when you create a badge instance for their email address - this is the purpose of the award webhook notification, where you can handle earner communication in a way that suits your community.

For an explanation of how assessment works in BadgeKit, see Assessment with BadgeKit.

The API guides use node.js examples to demonstrate the key processes you need to connect BadgeKit to your own earner-facing site. If you're using other languages/ platforms, you should be able to see how you can use BadgeKit to deliver your implementation.

Contents

Overview

Below is a detailed guide to using the API in the context of a node.js app - here's the short version!

Config

To receive data at a webhook URL, you first need to add it to your BadgeKit API database, in the webhooks table. You should include the URL you want to use as your webhook and a secret you will use to decode the data received there.

See the API docs for more on the badge issued webhook.

Authentication

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.

Example Data Received

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
}

For a more detailed overview of handling the badge issued webhook, read on.

Badge Issuing Flow

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.

Note that a badge instance can also be revoked, at which point the revoke action is sent to the webhook.

Webhook Configuration

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);

See the API docs for more on the badge issued webhook.

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
});

Badge Actions

The API sends notifications for a few different badging actions, including an application being reviewed, a badge being issued and a badge being revoked. 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.

The Award Action

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.

Processing the Award Data

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.

Assertion Data

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.

Communicating with the Earner

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:

Award Email

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.

Next Steps

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 - with you in control over interaction with your earners and BadgeKit handling the back-end admin.