Queuing mechanism for E-Mail push scenarios
1 Requirement
The ICI has always been an asynchronous and non-queuing interface. In certain channels (such as telephony) this is not a critical issue as the agent still has the possibility to manually identify a customer, even if there wasn’t an inbound signal before.
However, in E-Mail scenarios where the initial inbound is done in the CRM the missing queuing functionality like in classical middleware scenarios is a mandatory requirement in most projects. The CTI middleware can be not accessable for various reasons (connection lacks, HTTP errors, etc.). In those cases, where no pull scenario is provided, no agent will ever know whether there has been an inbound E-Mail or not.
2 Proposal
Using a classical TRFC queuing, the outbound SOAP request can be handled and resent where required.
3 Implementation Steps
Basically, the solution can be done by registering a new queue and little implementation.
3.1 Queue
In some systems the Queue CN* is already registered. If not, just register it with the transaction code SMQR.
3.2 Push-Exit
The standard uses the class CL_CRM_IC_ERMS_PUSH_EXIT during workitem execution to check whether a push needs to be done or not. In order to encapsulate the SOAP request a enhancement needs to be done in method IF_SWF_IFS_WORKITEM_EXIT~EVENT_RAISED.
*|----------------------------------------------------------------------
*|-- Referenzes
DATA: lo_exit TYPE REF TO zcl_crm_ic_erms_push_exit.
*|----------------------------------------------------------------------
*|-- Create Object
CREATE OBJECT lo_exit.
*|-- Push E-Mail
CALL METHOD lo_exit->push_email
EXPORTING
im_event_name = im_event_name
im_workitem_context = im_workitem_context.
*|-- Don't run the standard logic afterwards
RETURN.
3.3 New Push Logic
The implementation in method PUSH_EMAIL is basically identical to the standard, except the request itself which is encapsulated in a function module.
*|----------------------------------------------------------------------
*|-- Variables
DATA: lv_scenario_id TYPE string,
lv_mail_id TYPE crmt_erms_connection_id,
lv_workitem_id TYPE sww_wiid.
*|-- Structures
DATA: ls_action_item TYPE crm_ici_action_item,
ls_officeobject TYPE obj_record,
ls_swo_objid TYPE swotobjid.
DATA: BEGIN OF ls_mail_id,
folder_id TYPE soodk,
object_id TYPE soodk,
END OF ls_mail_id.
*|-- Referencen
DATA: lo_wf_container TYPE REF TO if_swf_ifs_parameter_container,
lo_mail_data TYPE REF TO cl_crm_email_data.
*|----------------------------------------------------------------------
*|-- Push only once
IF im_event_name <> 'CREATED'.
RETURN.
ENDIF.
*|-- Check debug mode
check_debug_mode( ).
*|-- Get workitem container
lo_wf_container = im_workitem_context->get_wf_container( ).
*|-- Check whether the action was already executed
IF was_already_executed( lo_wf_container ) NE abap_true.
RETURN.
ENDIF.
*|-- Get E-Mail-ID
TRY.
lv_workitem_id = im_workitem_context->get_workitem_id( ).
CALL METHOD lo_wf_container->get
EXPORTING
name = 'OfficeDocument'
IMPORTING
value = ls_officeobject.
CALL FUNCTION 'SWO_OBJECT_ID_GET'
EXPORTING
object = ls_officeobject-handle
IMPORTING
objid = ls_swo_objid.
lv_mail_id = ls_swo_objid-objkey.
IF lv_mail_id IS INITIAL.
RETURN.
ENDIF.
CATCH cx_swf_cnt_container .
CATCH cx_root.
RETURN.
ENDTRY.
*|-- Get E-Mail data
ls_mail_id = lv_mail_id.
CLEAR ls_mail_id-folder_id.
lo_mail_data = cl_crm_email_utility_base=>get_mail_data_from_so( iv_object_id = ls_mail_id-object_id ).
CHECK lo_mail_data IS BOUND.
*|-- Fill action item
ls_action_item-_action_item_attributes = get_attributes( lo_mail_data ).
ls_action_item-_request_id = lv_workitem_id.
ls_action_item-_process_id = lv_mail_id.
*|-- Create queue entry
CALL FUNCTION 'TRFC_SET_QUEUE_NAME'
EXPORTING
qname = 'CN_EMAIL_PUSH'
EXCEPTIONS
invalid_queue_name = 1
OTHERS = 2.
IF sy-subrc <> 0.
RETURN.
ENDIF.
*|-- Start request in background
CALL FUNCTION 'ZCRM_ERMS_PUSH_EMAIL'
IN BACKGROUND TASK AS SEPARATE UNIT
DESTINATION space
EXPORTING
is_action_item = ls_action_item
it_routing_attributes = get_routing_attributes( )
iv_scenario_id = lv_scenario_id.
COMMIT WORK.
3.4 Function Module
The function module only calls the push logic of the standard. In addition, a potential occuring ICI exception is catched and in those cases the background task is restarted again.
*|----------------------------------------------------------------------
*| Variables
DATA: lv_user_id TYPE string,
lv_item_id TYPE string.
*| Referencen
DATA: lo_action TYPE REF TO cl_erms_action.
*|----------------------------------------------------------------------
*|-- Create routing instance
lv_user_id = sy-uname.
CREATE OBJECT lo_action
EXPORTING
userid = lv_user_id.
*|-- SOAP Request
TRY.
CALL METHOD lo_action->route
EXPORTING
item_data = is_action_item
routing_attributes = it_routing_attributes
scenario_id = iv_scenario_id
IMPORTING
action_item_id = lv_item_id.
CATCH cx_crm_ici_exception
cx_root.
"In terms of a failure the task is restarted
CALL FUNCTION 'RESTART_OF_BACKGROUNDTASK'.
EXIT.
ENDTRY.
4 Summary
In situation where the CTI middelware is fighting with connection problems the SOAP requests are still not lost. The queuing mechanism is standard and so are the monitoring processes, respectively.