- Post History
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
10-10-2024 07:27 PM - edited 11-12-2024 09:33 AM
Table of Contents
Introduction
ServiceNow to microsoft teams integration is very widely used for approvals, virtual agent, live agent functionality. This document covers how to update approval card in teams notification.
Solution Overview
Teams notification card looks like below, in order to update approval for: text below changes would be needed.
Script Include : sn_now_teams.MSTeamsApprovalNotificationUtil requires update.
Data flow
When a user requests approval for an RITM, change request or request it invokes business rules listed here
These BRs inturn invoke scriptinclude function sendApprovalNotification will finally result in creation of push notifications, push notifications can be seen in push notification log, table name : sys_push_notification
Example push notification for change approval would look like below
{"data":{"instance_id":"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX=","instance_name":"instancedev","aps":{"sound":"default","category":"approve-rejectwcomments-itsm"},"Layout":{"Status":{"Label":"Requested","Style":{"background_color":"null","font_color":"#5297C4"}},"Identifier":{"Label":"CHG0XXXXXXXXXXXXXX"}},"Actions":[{"Context":{"ContextType":"RECORD","TableName":"sysapproval_approver","UniversalLinkContext":null,"ContextDestinationFormFieldValues":null,"RefreshContext":{"ParentScreenRedirectedId":null,"ItemStreamSegmentId":null,"ParentTableName":null,"TableName":null,"ItemStreamId":null,"UniversalLinkContext":null,"ParentRecordId":null,"ParentScreenCacheKey":null,"RecordId":null,"ParentScreenId":null},"RecordId":"XXXXXXXXXXXXXXXXXXXXXXXX","QueryCategory":null},"ActionType":"write_back","Label":"Approve","Foreground":false,"PushActionId":"XXXXXXXXXXXXXXXXXX","Name":"approve","ResponseType":"simple"},{"Context":{"ContextType":"RECORD","TableName":"sysapproval_approver","UniversalLinkContext":null,"ContextDestinationFormFieldValues":null,"RefreshContext":{"ParentScreenRedirectedId":null,"ItemStreamSegmentId":null,"ParentTableName":null,"TableName":null,"ItemStreamId":null,"UniversalLinkContext":null,"ParentRecordId":null,"ParentScreenCacheKey":null,"RecordId":null,"ParentScreenId":null},"RecordId":"XXXXXXXXXXXXXXXXXXXXXXXXX","QueryCategory":null},"ActionType":"write_back","Label":"Reject","Foreground":false,"PushActionId":"XXXXXXXXXXXXXXXXXXXXXXXXXXXXX","PlaceHolderText":null,"Name":"reject","ResponseType":"text_response"}],"ScreenId":"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX","actionable":true,"mobileRequestId":"XXXXXXXXXXXXXXXXXXXXXXXXX","message":"You have a pending approval for CHG0XXXXXXXXXXXXXXXXXX","Link":"https://instancedev.service-now.com/mobileapplink?snapp=agent¶ms=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX...","PushId":"a25ab9611b501010d4ee8778ec4bcb3d"},"registration_ids":["XXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"]}
Similarly a sample push notification for RITM Approval would look like below
{"data":{"instance_id":"XXXXXXXXXXXXXXXXXXXXX=","instance_name":"instancedev","aps":{"sound":"default"},"Layout":{"Status":{"Label":"Requested","Style":{"background_color":"null","font_color":"#5297C4"}},"Identifier":{"Label":"RITM0XXXXXXXXXXXX"},"Description": {"Label":"For order XXXXXX "}},"mobileRequestId":"XXXXXXXXXXXXXXXXXXXX","message":"You have a pending approval for RITM0XXXXXXXXXXXXXXXXX","Link":"https://instancedev.service-now.com/mobileapplink?snapp=agent¶ms=XXXXXXXXXXXXXXXXXXXXXXXXXXXXX"},"registration_ids":["XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"]}
Below is the explanation of this json
**JSON Explanation**
====================
The provided JSON (JavaScript Object Notation) is a complex data structure that appears to be a notification payload for a mobile application, likely built on top of the Firebase Cloud Messaging (FCM) or Google Cloud Messaging (GCM) service.
### Top-Level Properties
* `data`: An object containing metadata about the notification.
* `registration_ids`: An array of device registration tokens, which are used to send notifications to specific devices.
### `data` Object
* `instance_id`: A unique identifier for the instance.
* `instance_name`: The name of the instance.
* `aps`: An object containing Apple Push Notification Service (APNs) settings.
* `sound`: The default sound to play when the notification is received.
* `Layout`: An object defining the layout of the notification.
* `Status`: An object with the following properties:
### Status Object
* `Label`: The label for the status.
* `Style`: An object defining the style of the status.
* `background_color`: The background color of the status (set to `null` in this example).
* `font_color`: The font color of the status (set to `#5297C4` in this example).
* `Identifier`: An object with the following properties:
### Identifier Object
* `Label`: The label for the identifier.
* `Description`: An object with the following properties:
### Description Object
* `Label`: The label for the description.
* `mobileRequestId`: A unique identifier for the mobile request.
* `message`: The message to be displayed to the user.
* `Link`: The URL of the link to be opened when the notification is clicked.
### Example Use Case
This JSON may be used in a mobile app to display a notification to the user with a pending approval for an order. When the user clicks on the notification, the app would open the specified link in the `Link` property.
```json
{
"data": {
"instance_id": "XXXXXXXXXXXXXXXXXXXXX=",
"instance_name": "instancedev",
"aps": {
"sound": "default"
},
"Layout": {
"Status": {
"Label": "Requested",
"Style": {
"background_color": "null",
"font_color": "#5297C4"
}
},
"Identifier": {
"Label": "RITM0XXXXXXXXXXXX",
"Description": {
"Label": "For order XXXXXX "
}
}
},
"mobileRequestId": "XXXXXXXXXXXXXXXXXXXX",
"message": "You have a pending approval for RITM0XXXXXXXXXXXXXXXXX",
"Link": "https://instancedev.service-now.com/mobileapplink?snapp=agent¶ms=XXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
},
"registration_ids": ["XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"]
}
Script include #1: MSTeamsNotificationBuilderUtil()
Explanation
This is a ServiceNow script include that defines a new class called `MSTeamsNotificationBuilderUtil`. The class is defined using the `Class.create()` method, which is a part of the ServiceNow scripting language.
The `MSTeamsNotificationBuilderUtil` class is a subclass of `MSTeamsNotificationBuilderUtilSNC`, which is a built-in class in ServiceNow that provides functionality for building Microsoft Teams notifications. The `MSTeamsNotificationBuilderUtil` class extends the `MSTeamsNotificationBuilderUtilSNC` class by adding a new `initialize` method and a new `type` property.
The `initialize` method is called when an instance of the `MSTeamsNotificationBuilderUtil` class is created. It calls the `initialize` method of the parent class, `MSTeamsNotificationBuilderUtilSNC`, using the `apply` method. This ensures that the parent class's initialization code is executed when an instance of the `MSTeamsNotificationBuilderUtil` class is created.
The `type` property is set to `'MSTeamsNotificationBuilderUtil'`, which is the name of the class. This property is used to identify the class and is used in various places in the ServiceNow platform, such as in the UI and in the scripting language.
Overall, this script include defines a new class called `MSTeamsNotificationBuilderUtil` that extends the built-in `MSTeamsNotificationBuilderUtilSNC` class and adds a new `initialize` method and a new `type` property.
Script include #1: MSTeamsNotificationBuilderUtilSNC()
Explanation
This is a ServiceNow script include that provides a utility class for building Microsoft Teams notifications. It includes methods for sending notifications for various ServiceNow events, such as comments on a record, approvals, and incident communication tasks.
Here's a breakdown of the methods in the script include:
- `initialize`: This method sets up some variables for use by other methods, including `new_line` and `lines`.
- `_isEntitled`: This method checks whether the user has the necessary entitlements to receive notifications.
- `sendCommentNotification`: This method sends a notification about a comment on a ServiceNow record. It retrieves the comment data and then creates a dictionary of input values to pass to a Flow API action. Finally, it calls the Flow API action to send the notification via Microsoft Teams.
- `getPlainComment`: This method removes HTML tags from a comment and returns only the plain text. This allows the bot to display the comment correctly in Microsoft Teams without any formatting issues.
- `addNewLines`: This method adds one more new line for a single new line in a comment.
- `sendICTNotification`: This method sends a notification for an incident communication task. It creates an adaptive card with the necessary information and then sends it to the user via Microsoft Teams.
- `getTranslatedString`: This method gets the string message in the user's preferred language.
- `getTranslatedFieldLabelWithLang`: This method gets the translated field label in the user's preferred language.
- `getTranslatedChoiceValueWithLang`: This method gets the translated choice field value in the user's preferred language.
- `getUserLang`: This method gets the user's preferred language if it exists, otherwise it returns the default language.
- `getUpdatedCard`: This method returns the updated adaptive card wherein the send reply action will be removed.
- `getAdaptiveCard`: This method gets the adaptive card for the given table, sys_id, card_type, card_data, and user_id.
- `prependResponse`: This method prepends a response message to the adaptive card if the state is changed to approved or rejected.
Script include function : sendApprovalNotification
Explanation
This function first checks whether the user has entitlement using the `_is Entitled()` method and then proceeds to create an event queue for non-actionable approval with parameters as event name, approval group record (approval Gr), and the ID of the approver. If the user does not have entitlement, it returns from the method without performing further operations. Otherwise, it initializes an instance of `MSTeamsPersonalMessageUtils` class and calls the `handleApproval` method on this object passing the appropriate arguments i.e., approver's ID, table name, and unique system identifier value.
Script include : MSTeamsPersonalMessageUtils
Explanation
The given code snippet provides an implementation of a JavaScript class that contains various functions related to sending messages and handling approvals using Microsoft Teams API. The class includes methods such as `postComment` for posting comments on records, `sendBulkMessage` for sending bulk messages to multiple users, `handleOutboundMessage` for handling outbound messages, `handleApproval` for handling record approval requests, and internal helper method `_insertOutboundMsgRecord`.
Based on the provided code structure, it can be inferred that the class utilizes Microsoft Teams Adaptive Cards for creating richly formatted messages and interactions within the Microsoft Teams platform. Additionally, the class likely makes use of Microsoft Graph API for interacting with Microsoft Teams resources and managing user communication within the platform.
Script include function : sendApprovalNotification
Explanation
This is a JavaScript function that handles the creation and dispatching of an adaptive card for an approval notification. The function takes three parameters: `userId`, which is the ID of the user who needs to be notified about the approval; `table`, which is the name of the table associated with the record being approved; and `sysId`, which is the system ID of the record being approved.
- **List of Actions**: This function performs several actions:
- It checks whether the required parameters are provided (`userId`, `table`, and `sysId`). If any of them is missing, it returns without performing any further action.
- It retrieves the source record using the `MSGraphUtils` class's `getSourceRecord()` method, passing the `table` and `sysId` as arguments.
- It creates an instance of the `MSTeamsApprovalNotificationUtil` class and calls its `buildCardFieldsObj()` method, passing the retrieved `sourceGR` as argument. This method builds an object containing the necessary data for the adaptive card based on the fields present in the source record.
- It then calls the `getAdaptiveCard()` method of the same `approvalUtil` instance, passing the `table`, `sysId`, `cardType`, `cardData`, and `'create'` as arguments. This method generates the JSON payload for the adaptive card by formatting the data obtained from the previous step.
- Next, it queries the `sys_user_delegate` table to retrieve all records related to active delegations for the specified `userId`.
- For each matching record found during the query, the function calls another internal method called `handleOutboundMessage()`, passing the corresponding values extracted from the delegate record along with the previously generated adaptive card payload. This method dispatches the adaptive card using Microsoft Graph API.
- **Calls to Other Classes**: As mentioned earlier, this function makes use of two custom classes named `MSGraphUtils` and `MSTeamsApprovalNotificationUtil`. The former provides utility methods for working with Microsoft Graph API, whereas the latter contains business logic specific to generating and handlingadaptive cards used for notifications.
- **GlideRecord Initialization**: None. The entire operation happens within this single function without touching any database tables directly via the GlideRecord class.
Script include : MSTeamsApprovalNotificationUtil
Explanation
Here are the requested information about that code snippet:
- List of actions: The Java Script provides functions related to creating an Adaptive Card in Microsoft Teams based on different types of notifications like creation or updating of requests, tasks etc., It also checks for certain conditions before deciding whether to make the notification actionable or not.
- Calls to other classes: This JavaScript uses few classes from other scripts which might be present in same application such as `MSTeamsAdaptiveCardsUtil`, `MSTeamsMessageActionsUtil` & `MSTeamsNotificationBuilderUtil`. These classes have methods used by this script to generate required data structures.
- GlideRecord initialization: The script initializes `GlideRecord` objects to fetch records from tables like E-Signature Registry, Change Request, sc_ Req_Item etc..
Script include function : MSTeamsApprovalNotificationUtil buildCardFieldsObj
Explanation
This code snippet is written in JavaScript and is used by ServiceNow to create an object that contains information about various fields related to an approval record (`approvalGr`). The `buildCardFieldsObj` function takes this approval record as input and returns the `cardFieldsObj`, which includes information such as the title of the message ("card_msg_heading"), additional details about the approval process ("card_description"), specific fields from the approval record that should be displayed on the notification card ("card_fields"), and more.
The function first checks if the provided `approvalGr` exists, and if not, it simply returns an empty object. If the `approvalGr` does exist, then the function proceeds to initialize some variables, including creating an instance of another utility class called `MSTeamsNotificationBuilderUtil`. This utility class is likely being used to perform various operations that are needed throughout the code. Additionally, the function retrieves the user's preferred language using the `getUserLang()` method and uses this value to retrieve any necessary translations for strings that will be shown to end users.
Next, the function creates several variables that contain different pieces of data extracted from the `approvalGr`. These values are later combined into the final output `cardFieldsObj`. One interesting aspect of this function is how it handles the creation of the "shortDescription" variable based on the type of approval record being processed. For example, if the approval record relates to a standard catalog item request, the short description will just display the name of the requested item. However, if the approval record relates to one or more change requests, then the function first builds a longer string containing additional details about those change requests before ultimately truncating it down to fit within the size limits imposed by Microsoft Teams.
After defining all these helper functions, the main body of the `buildCardFieldsObj` function begins by initializing an empty `cardFieldsObj` object. It then adds two properties to this object: "card_msg_heading" and "card_description". The former is set to the previously calculated "shortDescription", while the latter is set to the "description" variable that was also defined earlier in the function.
Following this, the function determines which subset of fields should be included in the `cardFieldsObj` based on the type of approval record being processed. To do this, it consults a nested dictionary named `cardFieldsPerTable`, which maps each supported table type (such as "sc_req_item" or "change_request") to a list of field names that should be included when displaying notifications related to records of that type. If the current table type is present in this map, then the corresponding list of fields is assigned to the `cardFieldsObj`'s "card_fields" property. Otherwise, the default set of fields specified in the "default" entry of `cardFieldsPerTable` is used instead.
In addition to determining which fields should be displayed, the function must also determine whether the approval record represents a single-item request or something more complex like a multi-item request or a series of interrelated change requests. To make this determination, it inspects the "source_table" property of the `approvalGr` record and assigns a boolean flag accordingly. If the source table matches what would typically indicate a simple catalog item request ("sc_ Catalog_Item_Request"), then the flag remains false since the request only involves a single item. However, if the source table indicates that the approval pertains to either sc_req_item records (which would suggest a multi-item request) or a change request itself, then the flag is set to true so that appropriate messaging can be generated.
Implementing code changes
It may be required that in some scenarios the OOB (out of the box) notification card may not provide relevant information or customer may want to add additional information to the existing card, in such cases code changes would be required to OOB configuration. An example of such scenario is to update the approval for field (it is showing null for change requests), based on above data flow its identified that code update is needed in function Script include function : MSTeamsApprovalNotificationUtil buildCardFieldsObj where additional logic is added to include change request short description and type in approval for attribute.
if (global.JSUtil.notNil(approvalGr.sysapproval)) {
var chgShortDesc = 'Change request';
chgShortDesc = approvalGr.getDisplayValue("sysapproval.short_description") + "-" + approvalGr.getDisplayValue("sysapproval.type");
if (approvalGr.sysapproval.sys_class_name == 'change_request') {
shortDescription = translatedString.replace('{0}', chgShortDesc);
}
}
//end
//update card fields list to include type
var cardFieldsPerTable = {
"default": ["sysapproval.number", "sysapproval.requested_for", "sysapproval.price", "sysapproval.due_date", "state"] "change_request": ["sysapproval.number", "sysapproval.risk", "sysapproval.start_date", "sysapproval.end_date", "state","sysapproval.type"]
};
Updated notification card would look like below
- 3,263 Views
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi,
This is vert helpful.
I am trying to implement this but even after activating the br i am not receiving any notifications.
I receive other notifications in teams so no issue with my integration.