Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
Showing results for 
Search instead for 
Did you mean: 

In the Part 4 of this blog series you showed user’s achievements in the profile page. In this blog post you will show notifications from the game.

It is important to provide immediate feedback on achievements to the users. Here you will use pop-up messages to notify the users about Experience Points assigned to him for creating issues.

In order to implement this, first you will retrieve notifications using gamification service API and then you will show the relevant notification by creating a pop-up message.


1) Retrieve notifications:


1. Replace the code in the file located at package with code GamificationProxy.txt .

import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.HttpClients;

* This is the proxy class for calling Gamification Service APIs.
public class GamificationProxy {
private static String SCHEME = "https";
private static String PATH = "/gamification/api/tech/JsonRPC";
public static final String GAMIFICATION_SERVICE_APPNAME = "JIRA";

* This is used for sending gamification event to the Gamification Service.
* @param playerId
* @param priority
* @return
* @throws URISyntaxException
* @throws ClientProtocolException
* @throws IOException

public Integer sendEvent(String playerId, String priority,
String eventName) throws URISyntaxException,
ClientProtocolException, IOException {
URIBuilder builder = new URIBuilder();
String value = "{" + "\"method\":\"" + "handleEvent" + "\","
+ "\"params\":[" + "{" + "\"type\":\"" + eventName
+ "\"," + "\"playerid\":\"" + playerId
+ "\"," + "\"data\":{" + "\"relevance\":\""
+ priority + "\"" + "}" + "}" + "]" + "}";
URI url =;
HttpClient client = HttpClients.createDefault();
HttpPost post = new HttpPost(url);
// If you are running this behind behind some corporate network fire
// wall the you need to set the proxy
if (EnvironmentUtility.proxy != null
&& !EnvironmentUtility.proxy.equalsIgnoreCase("")) {
HttpResponse doPostResponse = client.execute(post);
return Integer.valueOf(doPostResponse.getStatusLine().getStatusCode());

private static void setHttpHostProxy(HttpRequestBase request) {
HttpHost httpProxy = new HttpHost(EnvironmentUtility.proxy,
Integer.parseInt(EnvironmentUtility.port), "http");
RequestConfig config = RequestConfig.custom().setProxy(httpProxy)

private static String getBase64Auth(String login, String pass) {
String source = login + ":" + pass;
String ret = "Basic " + Base64.encodeBase64String(source.getBytes());
return ret;

public static void main(String arg[]) throws Exception{
// arg[0] - player Id
// arg[1] – priority of the issue created
GamificationProxy gamificationProxy=new GamificationProxy();
String eventName="issueCreated";
gamificationProxy.sendEvent(arg[0], arg[1], eventName);




 Copy-and-paste the contents to the file

The class GamificationProxy

The class GamificationProxy has a method getPlayerNotifications() which uses Technical Endpoint to retrieve notifications by invoking gamification service method getNotificationsForPlayer(). The HTTP POST request will look like the following:


https://<gamification service host>/gamification/api/tech/JsonRPC?json={"method":"getNotificationsForPlayer",params":["",1442061177178]}&app=JIRA



Query parameter



method getNotificationsForPlayer() and parameters (retrieves notifications for given player which have been created after the provided timestamp)


JIRA (name of the app which contains the game mechanics as defined in the gamification workbench)


Input parameter



Player name/Player email id


Timestamp (to retrieve notifications created just after this)


The class Gamification Proxy has another method getServerTime() which uses Technical Endpoint to retrieve current server time by invoking gamification method getCurrentServerTime(). The HTTP POST request will look like the following:

https://<gamification service host>/gamification/api/tech/JsonRPC?

json= {"method":"getCurrentServerTime","params":[ ]} &app=JIRA

Query parameter



method getCurrentServerTime() and parameters (retrieves the current server time )


JIRA (name of the app which contains the game mechanics as defined in the gamification workbench)


Test the class GamificationProxy: 


The class GamificationProxy defines a method main() to test retrieving notifications using gamification service API.

public static void main(String arg[]) throws Exception{

   // arg[0] - player id

   //reading Environments values


   GamificationProxy gamificationProxy= new GamificationProxy();

   // Step 1: Getting the server time

   String serverTimeResp=gamificationProxy.getSeverTime();

   String serverTime = serverTimeResp.split(",")[0].split(":")[1];

   System.out.println("Server Time "+ serverTime);

   // Step 2: Sending ‘issueCreated’ event to the gamification service    

   String eventName="issueCreated";

   gamificationProxy.sendEvent(arg[0], "Major", eventName);

   //Step 3: Retrieving notifications created after the provided server time

   String notifications = gamificationProxy. getPlayerNotifications (




1. Run the configuration (which you created in the previous blog) to execute the class GamificationProxy. As a result following output will be displayed in console


Server Time 1442061177178

{"result":[{"id":672384,"message":"Ticket created","category":"POINT","type":"ADD","subject":"Experience Points","detail":"2","dateCreated":1442061178360}],"error":null,"type":null}


Now let’s see how this was achieved. In step 1 server time is calculated and in step 2 gamification relevant event issueCreated is sent. Step 3 retrieves the notifications created after the provided server time and in the current case only one event is sent which means only one notification is created.



Create Rest service for notifications


1. Add the following lines of code to the method doGet() of class UserAchievementsServlet.

if (request.getPathInfo().equalsIgnoreCase("/servertime")) {

      String serverTime = null;

      try {

              serverTime = gamificationProxy.getSeverTime();

      }  catch (Exception e) {

                log.error(" Error during accessing server time", e.getMessage());

      }"Server time response", serverTime);



else if (request.getPathInfo().equalsIgnoreCase("/notifications")) {

      String serverTime = request.getParameter("serverTime");

      String playerNotifications = null;

        try {


          } catch (Exception e) {

                  log.error(" Error during accessing player notifications",e.getMessage());

        }"Player's notification response", playerNotifications);



The doGet() method should look like the following:

2.) Show notification:

To show notification, you need to create a JavaScript file and embed it in JIRA pages.


1. Create a folder with name widgets in folder /src/main/resources as shown in the screenshot below


2. Create a file with name sap_gs_notifications.js and place it at folder location /src/main/resources/widgets. Substitute the code from sap_gs_notifications.txt. 
var GSNotifications = (function() {
var _interval; // holds the interval
var _config = { // configurations at runtime
gamificationServerTimePath : "/jira/plugins/servlet/gamification/servertime",
gamificationNotificationsPath : "/jira/plugins/servlet/gamification/notifications",
interval : 2000,
currentServerTime : "",
var _notifications = {
toBeDisplayed : [],
function _init() {
_interval = setInterval(_poll, _config.interval);
console.log("[GamificationService] Notification module loaded");
function _poll() {
_getNotificationsForPlayer(function(data) {
if (data !== null) {
if (data.result.length > 0) {
for (var i = 0; i < data.result.length; i++) {
} else {
console.log("[GamificationService] No new notifications available.");

} else {
console.log("[GamificationService] Server Error: "+ data.error);
function _prepareAndInjectNotifications() {
var limit = _notifications.toBeDisplayed.length;
var message = "";
for (var i = 0; i < limit; i++) {
var n = _notifications.toBeDisplayed[i];
message = "";
switch (n.category) {
case "POINT":
message += "+" + n.detail + " " + n.subject;
if (n !== undefined) {
_notifications.toBeDisplayed.length = 0;
function _getCurrentServerTime() {
function(response, status) {
if (status === "success") {
var serverTimeRespose = JSON.parse(response);
_config.currentServerTime = serverTimeRespose.result;
console.log("[Gamification Service] Current server time: "+ _config.currentServerTime);
function _getNotificationsForPlayer(fnSuccessCallback) {
AJS.$.get(_config.gamificationNotificationsPath, {
"serverTime" : _config.currentServerTime
}, function(response, status) {
if (status === "success") {
console.log("[GamificationService Notifications]" + response);
var data = JSON.parse(response);
} else {
console.log("[GamificationService] Server Error on request.");

return {
init : _init, // setup for first start
AJS.toInit(function() {
if (AJS.params.loggedInUser !== '') {

Copy-and-paste the contents to the file sap_gs_notifications.js.

The web resource Plugin Module:


The web resource Plugin Module allows JIRA plugins to define downloadable resources. If your plugin requires the application to serve additional static Javascript or CSS files, you will need to use downloadable web resources to make them available.


In the current case, JavaScript file sap_gs_notifications.js will be used as downloadable web resource to shows notification exactly the time when an issue is created in the JIRA. Now let’s understand how it works?


The file sap_gs_notifications.js has functions _getNotificationsForPlayer() and _getCurrentServerTime() which retrieves notifications and server time by making Ajax calls to the REST service.

The function _poll() schedule the repeating execution of these functions to continually check whether any gamification relevant event has occurred for which there is a notification to the user. If there are notifications they will be shown on the screen using the function _prepareAndInjectNotifications().


_prepareAndInjectNotifications() uses following JIRA API to show notification message


Embed the JavaScript file in JIRA pages


1. Add the following web-resource Plugin module in the atlassian-plugin element of jira-gamification-plugin/atlassian-plugin.xml.

<web-resource name="Resources" key="resources">

  <resource name="sap_gs_notifications.js" type="download" location="widgets/sap_gs_notifications.js"/>





Here, web resource context is atl.general which means the widget sap_gs_notifications.js will be included on all screens of JIRA except administration screens.

The atlassian-plugin.xml should look like:

Test Integration with JIRA:

1. Open a command prompt and run the following set of commands to set environment variables.

set user_name=<HANA Cloud Platform user name>

set user_password=<HANA Cloud Platform password>

set host = < gamification service host>

If you are running this application behind the firewall you also need to set http_proxy_host and http_proxy_port by using following commands.

set http_proxy_host= <Http proxy name> 

set http_proxy_port= <Http port number>

2. Change directory to the folder jira-gamification-plugin and run the following command



3. Once JIRA has started successfully, open the URL printed in the message.


4. Log in with username and create an issue as described in the previous blog and notification would be visible as shown in the snapshot below



Congratulation!! :smile: You are done with Part 5 and with this integration of SAP HCP gamification service with JIRA is complete :smile: :smile: .  Next blog post Part 6 you will introduce the advance game mechanics like levels, badges, leaderboard and these elements will be visible in the User profile page.