Notifications in Fiori – Step-by-Step Guide to create your own Notification Provider

To make users aware of a situtation that requires timely action or attention you have to notify them. In times before Notifications in Fiori this functionality was provided mostly with emails. Due to the large number, automatically generated emails were usually quickly moved to a seperate folder in the mail application cause the user got overwhelmed by them. Since the implementation of notifications in Fiori, there is an easy way that is reminiscent of Facebook Twitter and Co. Users can access there notifications by clicking the bell icon in the shell bar at the top right of their screen/fiori launchpad.

In this blog post we will create our own Notification Provider to create customized notifications. The use case is assigning a CRM task. When a user assigns a task to someone else, we want to inform that person.

Let’s get started!

Prerequisites

Inbefore starting to create your own notificationprovider and get it running we need to make sure that the initial setup was performed successfully. Check out one of the following links for the initial setup:

Create your provider class

⚠️ Depending on the system architecture (central hub deployment vs embedded deployment), you will have one system or a hub/gateway and a backend system. The creation of the provider and its registration takes places in the backend system.

Create a z-class based on the interface /IWNGW/IF_NOTIF_PROVIDER. Depending on your installed software components and product version of your sap system you may also can use the interface /IWNGW/IF_NOTIF_PROVIDER_EXT.

GET_NOTIFICATION_TYPE

This method defines which actions a notification type should have. In this example we have the notification type TASK_ASSIGNMENT which will contain one action to discard the notification DiscardActionKey.

METHOD /IWNGW/IF_NOTIF_PROVIDER~GET_NOTIFICATION_TYPE.  
	DATA ls_naction LIKE LINE OF et_notification_action.  
  
	IF iv_type_key = 'TASK_ASSIGNMENT'.  
  
*--- Notification type and version  
		es_notification_type-is_groupable = abap_true.  
		es_notification_type-type_key = iv_type_key.  
		es_notification_type-version = iv_type_version.  
  
*--- Define actions of the notification  
		ls_naction-action_key = 'DiscardActionKey'.  
		ls_naction-nature = /iwngw/if_notif_provider=>gcs_action_natures-negative.  
		APPEND ls_naction TO et_notification_action.  
  
	ENDIF.  
ENDMETHOD.

GET_NOTIFICATION_TYPE_TEXT

This method defines the text that will be displayed as a notification as well as the text of the individual actions of the notification. When creating a notification, parameters can be specified. These can be addressed via curly brackets, {assignedby}.

💡 For an example of passing the parameters have a look at the example programm to create notifications

METHOD /iwngw/if_notif_provider~get_notification_type_text.  
	DATA ls_action_text TYPE /iwngw/if_notif_provider=>ty_s_notification_action_text.  
  
	SET LANGUAGE iv_language.  
  
	IF iv_type_key = 'TASK_ASSIGNMENT'.  
  
*--- Notificationtitle without sensitive data  
		es_type_text-template_public = TEXT-003. "&1 has assigned you a task!  
		REPLACE '&1' WITH '{assignedby}' INTO es_type_text-template_public.  
  
*--- Notificationtitle with sensitive data  
		es_type_text-template_sensitive = TEXT-002. "&1 has assigned you a task!  
		REPLACE '&1' WITH '{assignedby}' INTO es_type_text-template_sensitive.  
  
*--- Notificationtitle when grouped  
		es_type_text-template_grouped = TEXT-004. "&1 tasks assigned to you!  
		CONCATENATE '{' /iwngw/if_notif_provider=>gcs_parameter_reserved_names-group_count '}' INTO DATA(lv_group_count).  
		REPLACE '&1' WITH lv_group_count INTO es_type_text-template_grouped.  
  
*--- Actiontexts of the notification  
		ls_action_text-action_key = 'DiscardActionKey'.  
		ls_action_text-display_text = TEXT-005. "Ignore  
		ls_action_text-display_text_grouped = TEXT-005. "Ignore  
		APPEND ls_action_text TO et_action_text.  
  
	ENDIF.  
ENDMETHOD.

GET_NOTIFICATION_PARAMETERS

Based on the notification Id, further data can be read in this method. The data is then available in the method GET_NOTIFICATION_TYPE_TEXT.

💡 For an example check out the class CL_SWF_PUSH_NOTIF_PROVIDER in your system. Its the standard notificationprovider of sap for the business workflow.

💡 Remember, you can also enter parameters when creating a notification. For an example have a look at the example programm to create notifications

METHOD /IWNGW/IF_NOTIF_PROVIDER~GET_NOTIFICATION_PARAMETERS.  
	SET LANGUAGE iv_language.  
	"have a look at the class CL_SWF_PUSH_NOTIF_PROVIDER  
ENDMETHOD.

HANDLE_ACTION

What happens when an notification action gets pressed. Right this method gets executed. But there is a problem… You can’t access the parameters of the notification given at the beginning. The notification id should therefore either contain the id of the object or all relevant data must be stored in an z-table when creating a notification.

💡 SAP itself simply uses the workitem id as the notification id. This makes it easy to load further data if required. Look at class CL_SWF_PUSH_NOTIF_PROVIDER.

METHOD /iwngw/if_notif_provider~handle_action.  
	DATA: lt_notif_id TYPE /iwngw/if_notif_provider=>ty_t_notification_id.  
  
*--- Set success to false  
	es_result-success = abap_false.  
  
*--- Check required fields  
	CHECK iv_notification_id IS NOT INITIAL AND iv_action_key IS NOT INITIAL.  
  
*--- Act on action key  
	CASE iv_action_key.  
		WHEN 'DiscardActionKey'.  
			"TODO: Do stuff  
			"To act on a Notification you either need to pass the parameters into the id. 		Otherwise you need some sort of z-table  
			"Otherwise you cant determine the object  
			es_result-success = abap_true.  
			es_result-delete_on_return = abap_true.  
		WHEN OTHERS.  
	ENDCASE.  
  
*--- Delete notification/cleanup  
	lt_notif_id = VALUE #( ( id = iv_notification_id type_key = iv_type_key type_version = iv_type_version ) ).  
  
	TRY.  
		/iwngw/cl_notification_api=>delete_notifications(  
			EXPORTING  
				iv_provider_id = 'ZTASK_PROVIDER_POC' "TODO: Adjust to your provider id  
				it_notification_id = lt_notif_id  
		).  
	CATCH /iwngw/cx_notification_api INTO DATA(lrx_api).  
		"TODO: Add error handling  
	ENDTRY.  
ENDMETHOD.

Register and activate your provider class

Now that we have created our own Notification Provider class we have to registrate it.

⚠️ As mentioned earlier, registration and activation of the provider takes place in the backendsystem if your on an centrul hub deployment system architecture

To do this we navigate to the corresponding customizing in the transaction spro.


First of all register the new notification provider in the activity “Register Notification Providers”.

Register Notification Providers


Afterwards yo can activate the newly registered notification provider via the activity “Manage Notification Providers”.

Manage Notification Providers

Example programm to create notifications

That’s it. Configuration is done. What’s missing? Right an programm or sth. to trigger notifications. In the following example programm, a notification is generated and sent out to user A.

💡 By specifying the navigation parameters and the semantic object, it is possible to give the notification a navigation intent. If the user clicks on the notification itself, and not on an action, he is forwarded directly to the app where he can view and maintain the opportunity.

⚠️ Changes to the notification provider are usually not transferred directly to the hub system. If changes are not visible during development, execute transaction /IWNGW/H_CLEAR_NOTIF in the hub system.

*&---------------------------------------------------------------------*  
*& Report ZR_TASK_NOTIFICATION_POC  
*&---------------------------------------------------------------------*  
*&  
*&---------------------------------------------------------------------*  
REPORT zr_task_notification_poc.  
  
DATA lt_notif TYPE /iwngw/if_notif_provider=>ty_t_notification.  
DATA ls_notif LIKE LINE OF lt_notif.  
DATA lt_recipient TYPE /iwngw/if_notif_provider=>ty_t_notification_recipient.  
DATA lt_nav_params TYPE /iwngw/if_notif_provider=>ty_t_navigation_parameter.  
DATA lt_notif_parameter TYPE /iwngw/if_notif_provider=>ty_t_notification_parameter.  
DATA lt_semantic_params TYPE /iwngw/if_notif_provider=>ty_t_notification_param_bundle.  
DATA lrx_api TYPE REF TO /iwngw/cx_notification_api.  
DATA lv_system_uuid TYPE REF TO if_system_uuid.  
DATA lv_provider_id TYPE /iwngw/if_notif_provider=>ty_s_provider-id VALUE 'ZTASK_PROVIDER_POC'. " Your created provider ID  
DATA ls_pr_config TYPE /iwngw/if_notif_provider=>ty_s_provider_config.  
DATA lv_count_recip TYPE i.  
DATA lv_count_invalid_recip TYPE i.  
DATA lt_invalid_recip TYPE /iwngw/cl_notification_api=>ty_t_invalid_user.  
DATA ls_invalid_recip LIKE LINE OF lt_invalid_recip.  
DATA lt_user LIKE TABLE OF sy-uname.  
DATA ls_invalid_user TYPE /iwngw/if_notif_provider=>ty_s_notification_recipient.  
DATA lv_flag TYPE abap_bool.  
  
  
*--- Get provider config  
ls_pr_config = /iwngw/cl_notification_api=>get_provider_config( lv_provider_id ).  
  
*--- Check if provider is active  
CHECK ls_pr_config-active EQ abap_true.  
  
  
*--- Example data  
DATA(lv_type_key) = 'TASK_ASSIGNMENT'. "Define your type key to identify this kind of notification  
DATA(lv_guid) = '005056ac-1fe0-1edb-9ac1-aeb786c180e8'.  
DATA(lv_assignedby) = 'Curtis Jagson'.  
  
APPEND VALUE #( name = 'assignedby' value = lv_assignedby type = /iwngw/if_notif_provider=>gcs_parameter_types-type_string is_sensitive = abap_false )  
	TO lt_notif_parameter.  
  
lt_recipient = VALUE #( ( id = 'USERA' ) ). "CHANGE to your useralias  
lt_nav_params = VALUE #( ( name = 'initialRoute' value = 'object' ) ( name = 'routingParameter' value = lv_guid ) ). "semantic object navigation params  
lt_semantic_params = VALUE #( ( language = 'EN' parameters = lt_notif_parameter ) ).  
  
*--- Create notification id  
lv_system_uuid = cl_uuid_factory=>create_system_uuid( ).  
  
*--- create notification table  
lt_notif = VALUE #( (  
id = lv_system_uuid->create_uuid_x16( )  
type_key = lv_type_key  
type_version = '1'  
priority = /iwngw/if_notif_provider=>gcs_priorities-high  
actor_id = sy-uname  
actor_type = ''  
actor_display_text = sy-uname  
recipients = lt_recipient  
parameters = lt_semantic_params  
navigation_target_object = 'ZCRM_MYTASKS_EXT'  
navigation_target_action = 'display'  
navigation_parameters = lt_nav_params  
) ).  
  
*--- create notifications  
TRY.  
	/iwngw/cl_notification_api=>create_notifications(  
		EXPORTING  
			iv_provider_id = lv_provider_id  
			it_notification = lt_notif ).  
CATCH /iwngw/cx_notification_api INTO lrx_api.  
	lrx_api->get_invalid_recip_list(  
		IMPORTING  
			et_invalid_recip = lt_invalid_recip  
	).  
	IF lt_invalid_recip IS NOT INITIAL.  
		DESCRIBE TABLE lt_invalid_recip LINES lv_count_invalid_recip.  
		READ TABLE lt_invalid_recip INDEX 1 INTO ls_invalid_recip.  
		DESCRIBE TABLE ls_invalid_recip-recipient LINES lv_count_invalid_recip.  
		DESCRIBE TABLE lt_user LINES lv_count_recip.  
		IF lv_count_recip = lv_count_invalid_recip.  
			WRITE: / TEXT-002, lrx_api->if_message~get_text( ).  
			WRITE: / TEXT-008,/ 'List of invalid recipient, source id: ',ls_notif-id,' and notification type ', ls_invalid_recip-type_key.  
			LOOP AT ls_invalid_recip-recipient INTO ls_invalid_user.  
				WRITE: / ls_invalid_user.  
			ENDLOOP.  
			RETURN.  
		ELSE.  
			lv_flag = abap_true.  
		ENDIF.  
	ELSE.  
		WRITE: / TEXT-002, lrx_api->if_message~get_text( ).  
		RETURN.  
	ENDIF.  
ENDTRY.  
  
  
COMMIT WORK.

Credits

Leave a Reply

Your email address will not be published. Required fields are marked *