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.
![](https://bloggingwithjan.com/wp-content/uploads/2023/01/Fiori_Notifications_Bell.png)
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:
- How to Setup Notifications in Fiori 2.0 step-by-step
- 2488945 – How to setup notifications in Fiori 2.0
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
.
![](https://bloggingwithjan.com/wp-content/uploads/2023/01/spro_notification_provider_settings.png)
First of all register the new notification provider in the activity “Register Notification Providers”.
![](https://bloggingwithjan.com/wp-content/uploads/2023/01/Notification_Provider_Registration-1.png)
Afterwards yo can activate the newly registered notification provider via the activity “Manage Notification Providers”.
![](https://bloggingwithjan.com/wp-content/uploads/2023/01/Manage_Notification_Provider-1.png)
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.