This site contains the documentation that is relevant to older WSO2 product versions and offerings.
For the latest WSO2 documentation, visit https://wso2.com/documentation/.

Manage Notifications in Canvas

The second use case in the /wiki/spaces/CONNECTORS/pages/48465394 is managing notifications. This page describes the relevant tasks and the operations you use in the Canvas connector and the other ESB connectors. It contains the following sections:

Overview

The flow for managing notifications is illustrated in the following diagram. The ESB connectors for Facebook and Google Calendar will be used to connect to each service. Facebook can be used to share details about a course and notify relevant personnel regarding appointments, events, courses, etc. Google Calendar can be used as a communication medium through which the students could be notified/reminded about appointments and notifications.

Steps

Before you begin, make sure a Facebook private group has been created for the course, which is an offline process.

  1. Retrieve calendar events that are appointments, assignments, or quizzes in Canvas using the listCalendarEvents operation.

  2. Add those events as a calendar entry in Google Calendar using the createEvent operation.

  3. Add these calendar events as a post in the group created in Facebook using the createGroupPost operation.  

    This functionality occurs on a daily basis. Calendar events are retrieved by a batch process, and those created for the day are added as a calendar entry and as a post.

Facebook operations
Canvas operations
Google Calendar operations

Samples

Sample template for adding Canvas events in Google Calendar and posting in Facebook groups
<?xml version="1.0" encoding="UTF-8"?>
<!-- This template is used to add events retrieved from Canvas to the Google Calendar and to post in the Facebook group.-->
<template xmlns="http://ws.apache.org/ns/synapse" name="addCalenderEventsAndGroupPosts">
   <!--Google calender parameters-->
   <parameter name="googleCalendar.apiToken" description="Encrypted alphanumeric string to authenticate the google calender credentials." />
   <parameter name="googleCalendar.apiUrl" description="The googleCalender API URL." />
   <parameter name="googleCalendar.calendarId" description="The id of the calender." />
   <parameter name="googleCalendar.startDate" description="The start day of the canvas which an event begin. " />
   <parameter name="googleCalendar.endDate" description="The end date of the canvas which event will be finished." />
   
   <!-- Facebook parameters-->
   <parameter name="facebook.apiToken" description="Encrypted alphanumeric string to authenticate the facebook credentials." />
   <parameter name="facebook.apiUrl" description="The facebook API URL." />
   <parameter name="facebook.groupId" description="The id of the group." />
   <parameter name="facebook.urlMessage" description="The url message containing event details." />
   <parameter name="facebook.url" description="The url of the canvas event." />
   
   <!--Common parameters-->
   <parameter name="event.idObj" description="Id as Key value pair(s) for response handler (Ex. id1:value1,id2:value2)." />
   <parameter name="event.title" description="The title of the canvas calender event." />
   
   <sequence>
      <property name="googleCalendar.apiUrl" expression="$func:googleCalendar.apiUrl" />
      <property name="googleCalendar.apiToken" expression="$func:googleCalendar.apiToken" />
      <property name="googleCalendar.calendarId" expression="$func:googleCalendar.calendarId" />
      <property name="googleCalendar.startDate" expression="$func:googleCalendar.startDate" />
      <property name="googleCalendar.endDate" expression="$func:googleCalendar.endDate" />
	  
      <property name="facebook.apiUrl" expression="$func:facebook.apiUrl" />
      <property name="facebook.apiToken" expression="$func:facebook.apiToken" />
      <property name="facebook.groupId" expression="$func:facebook.groupId" />
      <property name="facebook.urlMessage" expression="$func:facebook.urlMessage" />
      <property name="facebook.url" expression="$func:facebook.url" />
	  
      <property name="event.idObj" expression="$func:event.idObj" />
	  <property name="event.title" expression="$func:event.title" />
	  
      <!--Process creating the Google Calendar only if the access token is given.-->
      <filter source="boolean(get-property('googleCalendar.apiToken'))" regex="true">
         <then>
            <property name="messageType" value="application/json" scope="axis2" />
           	<payloadFactory media-type="json">
               <format>
					{
						"start":{ "dateTime": "$1"},
						"end":{ "dateTime": "$2"}															
					}
				</format>
               <args>
                  <arg expression="get-property('googleCalendar.startDate')" />
                  <arg expression="get-property('googleCalendar.endDate')" />
               </args>
            </payloadFactory>
			
            <property name="googleCalendar.startDate" expression="json-eval($.start)" />
            <property name="googleCalendar.endDate" expression="json-eval($.end)" />
			
			<!-- Calling the Google Calendar connector createEvent method. -->
			<googlecalendar.init>
               <apiUrl>{$ctx:googleCalendar.apiUrl}</apiUrl>
               <accessToken>{$ctx:googleCalendar.apiToken}</accessToken>
            </googlecalendar.init>
            <googlecalendar.createEvent>
               <calendarId>{$ctx:googleCalendar.calendarId}</calendarId>
               <start>{$ctx:googleCalendar.startDate}</start>
               <end>{$ctx:googleCalendar.endDate}</end>
               <summary>{$ctx:event.title}</summary>
            </googlecalendar.createEvent>
			
            <property name="eventId" expression="json-eval($.id)" />
			
            <filter source="boolean(get-property('eventId'))" regex="false">
               <then>
                  <property name="status" value="Error" />
                  <property name="message" expression="json-eval($.)" />
               </then>
               <else>
                  <property name="status" value="Success" />
                  <property name="message" expression="fn:concat('Google calender event has been created with the id - ',get-property('eventId'))" />
               </else>
            </filter>
            <call-template target="responseHandlerTemplate">
               <with-param name="id" value="{$ctx:event.idObj}" />
               <with-param name="activity" value="googleCalendar_createEvent" />
               <with-param name="status" value="{$ctx:status}" />
               <with-param name="message" value="{$ctx:message}" />
            </call-template>
         </then>
      </filter>
	  
      <!--Process creating a Facebook group post only if the access token is given.-->
      <filter source="boolean(get-property('facebook.apiToken'))" regex="true">
         <then>
            <property name="messageType" value="application/json" scope="axis2" />
			
			<!-- Calling the Facebook connector createGroupPost method. -->
            <facebook.init>
               <apiUrl>{$ctx:facebook.apiUrl}</apiUrl>
               <accessToken>{$ctx:facebook.apiToken"}</accessToken>
            </facebook.init>
            <facebook.createGroupPost>
               <groupId>{$ctx:facebook.groupId}</groupId>
               <link>{$ctx:facebook.url}</link>
			   <name>{$ctx:event.title}</name>
			   <caption>Click here to view canvas calender events</caption>
			   <description>{$ctx:facebook.urlMessage}</description>
            </facebook.createGroupPost>
			
			<header name="Facebook-API-Version" action="remove" scope="transport" />
			
            <property name="groupPostId" expression="json-eval($.id)" />
			
            <filter source="boolean(get-property('groupPostId'))" regex="false">
               <then>
                  <property name="status" value="Error" />
                  <property name="message" expression="json-eval($.)" />
               </then>
               <else>
				  <property name="status" value="Success" />
                  <property name="message" expression="fn:concat('Group post is created with the id - ',get-property('groupPostId'))" />
               </else>
            </filter>
            <call-template target="responseHandlerTemplate">
               <with-param name="id" value="{$ctx:event.idObj}" />
               <with-param name="activity" value="facebook_createGroupPost" />
               <with-param name="status" value="{$ctx:status}" />
               <with-param name="message" value="{$ctx:message}" />
            </call-template>
         </then>
      </filter>
   </sequence>
</template>
Sample proxy for retrieving calendar events for the courses in Canvas
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="canvas_addCalenderEventsAndGroupPosts" transports="https http" startOnLoad="true" trace="disable">
   <description />
   <target>
      <inSequence onError="faultHandlerSeq">
         <!-- Canvas Properties-->
         <property name="canvas.apiUrl" expression="json-eval($.canvasApiUrl)" />
         <property name="canvas.accessToken" expression="json-eval($.canvasAccessToken)" />
         <property name="canvas.courseId" expression="json-eval($.canvasCourseId)" />
         <property name="canvas.contextCodes" expression="fn:concat('course_',get-property('canvas.courseId'))" />
		 
         <!-- Google Calendar Properties-->
         <property name="googleCalender.apiUrl" expression="json-eval($.googleCalenderApiUrl)" />
         <property name="googleCalender.apiToken" expression="json-eval($.googleCalenderApiToken)" />
         <property name="googleCalender.id" expression="json-eval($.googleCalenderId)" />
		 
         <!-- Facebook Properties-->
         <property name="facebook.apiUrl" expression="json-eval($.facebookApiUrl)" />
         <property name="facebook.apiToken" expression="json-eval($.facebookApiToken)" />
         <property name="facebook.groupId" expression="json-eval($.facebookGroupId)" />
		 
         <!-- List all the calendar events in the Canvas for the given course.-->
         <canvas.init>
            <accessToken>{$ctx:canvas.accessToken}</accessToken>
            <apiUrl>{$ctx:canvas.apiUrl}</apiUrl>
         </canvas.init>
         <canvas.listCalendarEvents>
            <allEvents>true</allEvents>
            <contextCodes>{$ctx:canvas.contextCodes}</contextCodes>
         </canvas.listCalendarEvents>
		 
         <!--Process only if an event list is retrieved successfully.-->
         <filter source="$axis2:HTTP_SC" regex="200">
            <then>
               <property name="messageType" value="application/xml" scope="axis2" />
               <property name="responseString" value="" scope="operation" />
               <property name="eventsCount" expression="count(//jsonArray/jsonElement)" scope="operation" />
               <property name="eventIndex" expression="0" scope="operation" />
               <property name="todayEvents" value="false" scope="operation" />
               <property name="count" expression="0" scope="operation" />
               <filter xpath="get-property('operation', 'eventsCount') != 0">
                  <then>
                     <iterate continueParent="true" id="eventIterator" preservePayload="true" expression="//jsonArray/jsonElement" sequential="true">
                        <target>
                           <sequence>
                              <property name="canvas.createdDate" expression="//jsonElement/created_at/text()" />
                              <property name="canvas.startDate" expression="//jsonElement/start_at/text()" />
                              <property name="canvas.endDate" expression="//jsonElement/end_at/text()" />
                              <property name="canvas.eventId" expression="//jsonElement/id/text()" />
                              <property name="canvas.eventUrl" expression="//jsonElement/html_url/text()" />
                              <property name="canvas.title" expression="//jsonElement/title/text()" />
                              <property name="canvas.idObject" expression="fn:concat('event_id:',get-property('canvas.eventId'))" />
                              <property name="facebook.message" expression="fn:concat('Starting time - ',get-property('canvas.startDate'),'   End time - ',get-property('canvas.endDate'))" />
                  
							  <property name="dateComparison" value="false"/>
				  
                              <script language="js"><![CDATA[var canvasCreatedDate = mc.getProperty('canvas.createdDate');
								var comparedDate = mc.getProperty('dateComparison');
								var createdDate = "";
							
								var currentDate=new Date();
								var currentday=""+currentDate.getDate();
		
								if(currentday.length==1){
									currentday="0"+currentday;
								}
								var dateString=currentDate.getFullYear() + "-" + Number(currentDate.getMonth()+1) + "-" + currentday ;
								if (canvasCreatedDate != null && canvasCreatedDate != "") {
									createdDate = canvasCreatedDate.split('T')[0];
								}
								if(dateString == createdDate) {
									comparedDate = "true";
								}
								mc.setProperty("dateComparison", comparedDate);]]></script>
						
							  <!--Create events in google calender and facebook for the current date only-->
                              <filter source="get-property('dateComparison')" regex="true">
                                 <then>
                                    <property name="todayEvents" value="true" scope="operation" />
                                    
									<!-- Remove custom headers before calling the addCalenderEventsAndGroupPosts template.-->
                                    <sequence key="removeResponseHeaders" />
                                    
									<!-- Calling the addCalenderEventsAndGroupPosts template to create events in Google Calendar and
									post in the Facebook group.-->
                                    <call-template target="addCalenderEventsAndGroupPosts">
                                       <!-- Parameter values will be passed on to a sequence template. -->
                                       (
                                       <with-param name="googleCalendar.apiUrl" value="{$ctx:googleCalender.apiUrl}" />|
                                       <with-param name="googleCalendar.apiToken" value="{$ctx:googleCalender.apiToken}" />|
                                       <with-param name="googleCalendar.calendarId" value="{$ctx:googleCalender.id}" />|
                                       <with-param name="googleCalendar.startDate" value="{$ctx:canvas.startDate}" />|
                                       <with-param name="googleCalendar.endDate" value="{$ctx:canvas.endDate}" />|
                                       <with-param name="event.title" value="{$ctx:canvas.title}" />|
                                       <with-param name="event.idObj" value="{$ctx:canvas.idObject}" />|
									   <with-param name="facebook.apiUrl" value="{$ctx:facebook.apiUrl}" />|
									   <with-param name="facebook.url" value="{$ctx:canvas.eventUrl}" />|
									   <with-param name="facebook.apiToken" value="{$ctx:facebook.apiToken}" />|
									   <with-param name="facebook.groupId" value="{$ctx:facebook.groupId}" />|
									   <with-param name="facebook.urlMessage" value="{$ctx:facebook.message}" />|
                                       ) *
                                    </call-template>
                                 </then>
                              </filter>
							  
                              <property name="eventIndex" expression="get-property('operation','eventIndex') + 1" scope="operation" />
                           </sequence>
                        </target>
                     </iterate>
                     <filter xpath="get-property('operation','eventIndex') = get-property('operation', 'eventsCount')">
                        <then>
                           <filter source="get-property('operation','todayEvents')" regex="false">
                              <then>
								 <property name="id" value="{}" />
                                 <property name="status" value="Skipped" />
                                 <property name="message" value="No events for the day." />
                                 <call-template target="responseHandlerTemplate">
                                    <with-param name="activity" value="retrieveEventsAndAddGoogleCalenderEvents" />
									<with-param name="id" value="{$ctx:id}" />
                                    <with-param name="status" value="{$ctx:status}" />
                                    <with-param name="message" value="{$ctx:message}" />
                                 </call-template>
                              </then>
                           </filter>
                           <loopback />
                        </then>
                     </filter>
                  </then>
               </filter>
            </then>
			<else>
				<property name="id" value="{}" />
				<property name="status" value="Error" />
                <property name="message" expression="json-eval($.)" />
				<call-template target="responseHandlerTemplate">
					<with-param name="activity" value="retrieveEventsAndAddGoogleCalenderEvents" />
					<with-param name="id" value="{$ctx:id}" />
                    <with-param name="status" value="{$ctx:status}" />
                    <with-param name="message" value="{$ctx:message}" />
                </call-template>
				<loopback/>
			</else>
         </filter>
      </inSequence>
      <outSequence>
         <property name="messageType" value="application/json" scope="axis2" />
         <payloadFactory media-type="json">
            <format>{
				"Response":{
					"process":"canvas_retrieveEventsAndAddGoogleCalenderEvents",
					"activityResponse":[$1]
				}
				}</format>
            <args>
               <arg expression="get-property('operation', 'responseString')" />
            </args>
         </payloadFactory>
         <send />
      </outSequence>
   </target>
</proxy>                       
Sample request for retrieving calendar events for the courses in Canvas
{
	"canvasApiUrl":"https://orion-city.acme.instructure.com",
	"canvasAccessToken":"51451~fwK08jirhrTKFiuyua8H3rpFVQtZJu7D7rf3mi7pecuHxMglbY24XOxQ42UWTvam",
	"canvasCourseId":"101",
	"googleCalenderApiUrl":"https://www.googleapis.com",
	"googleCalenderApiToken":"ya29.zwA0pjk2udUSvQJkOJYzEcqRVWbs9N9bFBrqlCc88u7fmG7XCAM8IkiTrj74vP00JVcCO_XZNsSW5g",
	"googleCalenderId":"eb03k6g1vdrdu6edigk2lkbsi4@group.calendar.google.com",
	"facebookApiUrl":"https://graph.facebook.com",
	"facebookApiToken":"CAACEdEose0cBANijywbMMrgIPyQKzGYQukhtwLInM6U3gftjZBX2HEVBusvdGQvOdxHhgGocsAyZBPn1yqWbQdlcGq5HNy1iPiyNl2ZCG2ZCoQxabhrObrc4AdU5ZAZBJUbhJ8Ba2WYtuvY7tewi4cNEfa5IxBrSPelZC7IsMlVxRs3m6tZBBRA7fQHTP4x4P9eNAxbNoQZBnZBOgXilWR0THfGYLt6l0ZCkGIZD",
	"facebookGroupId":"423020501183924"
}