Introduction:

Twitter is an important channel for businesses to connect with new and existing customers, to increase brand awareness or provide timely customer service, also to connect with brand advocates and influencers.
SAP Hybris Marketing omni-channel experience provides a framework to integrate with Twitter to launch Campaigns, in our use-case, to respond in the form of Direct Message to Twitter users who are follow our Official twitter handle. This is also an example to showcase how the integration of various other channels can be realised similarly.

For this prototype implementation, we rely on the generic Action framework and this prototype implementation is specific to SAP Hybris marketing only (On Premise), the architecture for integration with S/4 HANA Cloud Marketing Edition can be found here.

Configuration

1. Establishing connection to Twitter

a. With the intent of sending Direct Messages from a common account (Twitter Handle), define an App in apps.twitter.com
Note down the Consumer Key, Secret, User Token and Secret for use in steps 1.d and 1.e

b. We use TWIBAP open source program for Connectivity and Authorization (https://scn.sap.com/community/abap/
connectivity/blog/2010/08/12/twibap-the-abap-twitter-api)
c. Use the report Z_OAUTH_SETUP_1_API_KEY to register (From Twibap) the application
The program accepts
1. Consumer Key
2. Consumer Secret
3. API Host (api.twitter.com)
and leave the default selection for radio buttons as is.
d. Use the report Z_OAUTH_SETUP_2_REGISTER_USER (From Twibap) to allow the program to handle actions on behalf of user
This report triggers the OAUTH authentication process to get Access Token
e. SM59: Define RFC destination TWITTER for using Twitter APIs
Create a new RFC destination as shown in the screenshot

2. Interaction Contact (CEI_IMG->Contacts and Profiles->Interaction Contacts)

a. Define Origins of Contact ID: To capture the Twitter handle, we define a new Origin ID

b. Use the Import functionality in Data Management to import new /updates for Interaction Contact (mainly to store twitter handle using the newly defined ORIGIN ID)
1. In the Fiori Launchpad, open the application ‘Import Data’
2. In the Data Management section, select the Contacts option
3. Download the CSV template, and introduce a new header column at the very beginning, named ‘ID_ORIGIN’.
4. Maintain the values in the downloaded template, in our case a Contact with the newly created/defined ORIGIN_ID
5. Upload the file to create or update a Contact, verify the logs and the Contact to see if the uploaded data is in the system. A screenshot of a sample upload file is below.

6. screenshot of successful upload of Contacts

3. Campaigns /Action Framework (CEI_IMG->Campaigns->Campaign)

a. Define Provider Configuration:
A new provider for Twitter with RFC destination and a Provider class
CL_CUAN_MKT_EXEC_TWITTER, which implements IF_CUAN_MKT_EXEC_HTTP_OUTBOUND. In our case, derived from CL_CUAN_MKT_EXEC_SMS

b. Define Sender Profile:
Marketing area specific, unites Provider with sender profile (Sender name and communication medium)

c. Define Campaign Categories and Actions :
Define a new action “TWI_DIRECT_MESSAGE”, with an action class implementing interface IF_CUAN_MKT_EXEC_EXECUTE_ACTN
and IF_CUAN_MKT_EXEC_ACTION_PARAM. In our example, derived from CL_CUAN_MKT_EXEC_EXECUTE_SMS and also implementing the interface
IF_CUAN_MKT_EXEC_ACTION_PARAM.

Once a new Action is defined, assign it to an existing Campaign Category or Create a new Campaign Category.

4. Interactions (CEI_IMG->Data Management->Interactions)

a. Define Interaction Types:
An interaction type, a new type DM_OUTBOUND for every successful Direct Message sent.
For Interaction type OUTBOUND_FAILED, we add new reasons TWITTER_ERROR, TWITTER_LIMIT_EXCEED, and
TWITTER_OPTIN_MISSIN for failure to send Direct Messages

b. Assign Interaction Types and Communication Media to Channels:
Assign DM_OUTBOUND to Twitter (TW) communication medium and Social Channel
Assign OUTBOUND_FAILED to Twitter (TW) communication medium and Social Channel

Implementation Details


Sequence Diagram for the Twitter Campaign execution process

The ABAP code for both Adapter class and Action class is available in the Appendix section of this blog

1. Implementation of Adapter class:

CL_CUAN_MKT_EXEC_TWITTER
This provider class typically implements the interface IF_CUAN_MKT_EXEC_HTTP_OUTBOUND, which enables us to influence the HTTP request, process the HTTP response, and also to check the connection.
In this implementation of Action for sending Twitter Direct Messages, we are deriving the provider class from CL_CUAN_MKT_EXEC_EXECUTE_SMS, which gives us some implementation for free. We may as well implement the interface directly.

IF_CUAN_MKT_EXEC_HTTP_OUTBOUND~BUILD_REQUEST
We build the HTTP request URI, Signature base string, HTTP body consisting of OAUTH parameters and sign the message
We begin with building necessary parameters like ‘oauth_nonce’, ‘oauth_timestamp’, ‘text’, ‘screen_name’, Followed by building the URI (‘ /1.1/direct_messages/new.json’). Set the request_uri, request_method, content_type and host for the HTTP request
(sample code is available for download at the end of this blog post)

IF_CUAN_MKT_EXEC_HTTP_OUTBOUND~PROCESS_RESPONSE
Get the HTTP response code
Get the cdata from the response object

Set the values for structure es_member_status

IF_CUAN_MKT_EXEC_HTTP_OUTBOUND~CHECK_CONNECTION
As the name suggests, the connection is checked and returns abap_true or abap_false

2. Implementation of Action class:

CL_CUAN_MKT_EXEC_EXECUTE_TWIT
This action class implements the action interface IF_CUAN_MKT_EXEC_EXECUTE_ACTN, which provides methods for processing the Target Group entries in different stages.This also implements 2nd Interface for Action Parameters IF_CUAN_MKT_EXEC_ACTION_PARAM, which helps implementing partner defines new parameters, the method SET_ACTION_DETAILS helps us select an icon, and method SET_ACTION_PARAMETER helps us in giving a name, data type.
Our prototype implementation derives from an abstract class CL_CUAN_MKT_EXEC_EXECUTE_ACTN which provides some free implementation for checking marketing permission, to check if the segmentation object is valid, posting interactions, and excluding members after restart for those which were executed successfully.

IF_CUAN_MKT_EXEC_ACTION_PARAM~SET_ACTION_DETAILS
set Action Icon URL
Example:
es_action-icon_url = 'https://pbs.twimg.com/
profile_images/2284174872/7df3h38zabcvjylnyfe3_bigger.png'.

IF_CUAN_MKT_EXEC_ACTION_PARAM~SET_ACTION_PARAMETER
Define the parameter name, type
action_parameter – The ID of the parameter, must start with “Z” (ZOC_EXPORT_DESCRIPTION)
action_parameter_name – Label for the parameter used
action_parameter_type – controls how the parameter is rendered on the UI
(if_cuan_mkt_orch_constants=>action_param_type-string)
action_parameter_values (optional) – Possible values for parameter, if the parameter type is defined as dropdown

Example:
APPEND VALUE #( action_parameter = 'ZOC_EXPORT_DESCRIPTION'
action_parameter_name = 'Message'
action_parameter_type = if_cuan_mkt_orch_constants=>action_param_type-string ) TO
et_action_parameter.

IF_CUAN_MKT_EXEC_EXECUTE_ACTN~PRE_PROCESS
As the method name suggests, this is called before the members are processed and is used in our case to build the OAUTH parameters
and also parameters from Sender Profile
Example:
cl_cuan_mkt_exec_sms=>get_parameters( EXPORTING iv_sender = 'ZTWI'
IMPORTING et_parameters = et_param
et_messages = DATA(lt_message)
ev_error = ev_error ).

IF_CUAN_MKT_EXEC_EXECUTE_ACTN~PROCESS
Read all the member info extract the twitter handle for the member, by reading the facet which stores the twitter handle create outbound object
Example:
READ TABLE it_param WITH KEY param_name = if_cuan_mkt_exec_c=>c_param_adapter_class
ASSIGNING FIELD-SYMBOL().
CREATE OBJECT eo_sms TYPE (-param_value)
EXPORTING
it_parameters = it_param.

Send the HTTP request (via the outbound object), refer to method SEND_SMS in action implementation for SMS
Finally, write the outbound interactions in the system, refer to method PROCESS in action implementation for SMS

Testing of the Campaigns Integration with Twitter
a. Create /Update Interaction Contact to contain the facet “twitter handle”
b. Create Target Group consisting of Interaction Contacts with a valid Twitter Handle
c. Create a Campaign of category TW (whichever was created and Action assigned), In Automation Tab, select
the Twitter action and whatever message you would like to send to your official channel followers
d. Save and Execute the campaign
e. and Voila, the program would send the direct message on your behalf


Screenshot of a campaign to send Twitter direct message

Screenshot of the Direct Message received from the Hybris Marketing System

Appendix

ABAP code for the Adapter and Action class

class CL_CUAN_MKT_EXEC_TWITTER definition public inheriting from CL_CUAN_MKT_EXEC_SMS create public . public section. methods CONSTRUCTOR importing !IT_PARAMETERS type CUAN_T_MKT_EXEC_PARAM optional . methods IF_CUAN_MKT_EXEC_BOUNCE~GET_BOUNCE_COLLECTION_MODE redefinition . methods IF_CUAN_MKT_EXEC_HTTP_OUTBOUND~BUILD_REQUEST redefinition . methods IF_CUAN_MKT_EXEC_HTTP_OUTBOUND~CHECK_CONNECTION redefinition . methods IF_CUAN_MKT_EXEC_HTTP_OUTBOUND~GET_PARAMETERS redefinition . methods IF_CUAN_MKT_EXEC_HTTP_OUTBOUND~PROCESS_RESPONSE redefinition . protected section. private section. data OAUTH type ref to ZCL_OAUTH . data PARAMETERS type CUAN_T_MKT_EXEC_PARAM . ENDCLASS. CLASS CL_CUAN_MKT_EXEC_TWITTER IMPLEMENTATION. * ---------------------------------------------------------------------------------------+ * | Instance Public Method CL_CUAN_MKT_EXEC_TWITTER->CONSTRUCTOR * +-------------------------------------------------------------------------------------------------+ * | [--->] IT_PARAMETERS TYPE CUAN_T_MKT_EXEC_PARAM(optional) * +-------------------------------------------------------------------------------------- METHOD constructor. super->constructor( it_parameters = it_parameters ). me->parameters = it_parameters. ENDMETHOD. * ---------------------------------------------------------------------------------------+ * | Instance Public Method CL_CUAN_MKT_EXEC_TWITTER->IF_CUAN_MKT_EXEC_BOUNCE~GET_BOUNCE_COLLECTION_MODE * +-------------------------------------------------------------------------------------------------+ * | [ METHOD if_cuan_mkt_exec_bounce~get_bounce_collection_mode. ENDMETHOD. * ---------------------------------------------------------------------------------------+ * | Instance Public Method CL_CUAN_MKT_EXEC_TWITTER->IF_CUAN_MKT_EXEC_HTTP_OUTBOUND~BUILD_REQUEST * +-------------------------------------------------------------------------------------------------+ * | [--->] IO_REQUEST TYPE REF TO IF_HTTP_REQUEST * +-------------------------------------------------------------------------------------- METHOD if_cuan_mkt_exec_http_outbound~build_request. DATA: appendix TYPE string, url TYPE string. DATA: ls_param LIKE LINE OF parameters. FIELD-SYMBOLS:  TYPE cuan_s_mkt_exec_param. "1. Get consumer and User credentials and Build parameters for OAUTH "this is done in pre-process of action class "2. Build parameters for a new DM oauth ?= zcl_oauth=>get_instance( ). ls_param-param_name = 'oauth_nonce'. "#EC NOTEXT ls_param-param_value = oauth->create_nonce( length = 8 ). INSERT ls_param INTO TABLE parameters. ls_param-param_name = 'oauth_timestamp'. "#EC NOTEXT ls_param-param_value = oauth->create_timestamp( ). INSERT ls_param INTO TABLE parameters. ls_param-param_name = 'text'. "parameter for Twitter API * data(lv_text) = |viaActionFrw { sy-datum }-{ sy-timlo }|. data(lv_text) = me->mv_body. ls_param-param_value = oauth->percent_encode( lv_text ). INSERT ls_param INTO TABLE parameters. ls_param-param_name = 'screen_name'. "Recipient name in Twitter API * ls_param-param_value = 'DevFlashTwi'. ls_param-param_value = me->mv_recipient. INSERT ls_param INTO TABLE parameters. * ENDIF. "3. build URI CONCATENATE '/1.1' 'https://learntips.b-cdn.net/direct_messages/new.json' INTO appendix. "*--- set url ---* CONCATENATE zcl_twa_api=>api_protocol zcl_twa_api=>api_host appendix INTO url. "4. Set request uri DATA: http_body TYPE string, oauth_signature TYPE string, uri TYPE string. SORT me->parameters BY param_name. data: lt_parameters like TABLE OF . LOOP AT me->parameters ASSIGNING  FROM 6. http_body = |{ http_body }{ -param_name }={ -param_value }|. IF sy-tabix parameters ). http_body = |{ http_body }&|. ENDIF. INSERT  INTO TABLE lt_parameters. ENDLOOP. * url = |{ url }&{ http_body }|. oauth->set_oauth_url( url ). oauth->set_parameters( parameters = lt_parameters ). oauth->sign_message( ). IF oauth->get_oauth_signature( ) IS NOT INITIAL. * me->oauth_signature = percent_encode( me->oauth_signature ). oauth_signature = oauth->percent_encode( oauth->get_oauth_signature( ) ). http_body = |{ http_body }&oauth_signature={ oauth_signature }|. ls_param-param_name = 'oauth_signature'. "#EC NOTEXT ls_param-param_value = oauth_signature. INSERT ls_param INTO TABLE parameters. ENDIF. uri = |{ appendix }|."?{ http_body }|. io_request->set_header_field( EXPORTING name = '~request_uri' value = uri ). io_request->set_header_field( name = '~request_method' value = 'POST' ). io_request->set_header_field( name = 'Content-Type' value = 'application/x-www-form-urlencoded' ). io_request->set_header_field( name = 'host' value = 'api.twitter.com' ). "6. set request->cdata io_request->set_cdata( http_body ). DATA: lt_headerfields TYPE tihttpnvp. io_request->get_header_fields( CHANGING fields = lt_headerfields ). DATA(lv_cdata) = io_request->get_cdata( ). ENDMETHOD. * ---------------------------------------------------------------------------------------+ * | Instance Public Method CL_CUAN_MKT_EXEC_TWITTER->IF_CUAN_MKT_EXEC_HTTP_OUTBOUND~CHECK_CONNECTION * +-------------------------------------------------------------------------------------------------+ * | [--->] IV_HTTP_CODE TYPE I * | [--->] IV_REASON TYPE STRING * | [--->] IV_CDATA TYPE STRING * | [--->] IV_CONNECTION_TYPE TYPE STRING(optional) * | [ METHOD if_cuan_mkt_exec_http_outbound~check_connection. ev_success = abap_true. ENDMETHOD. * ---------------------------------------------------------------------------------------+ * | Instance Public Method CL_CUAN_MKT_EXEC_TWITTER->IF_CUAN_MKT_EXEC_HTTP_OUTBOUND~GET_PARAMETERS * +-------------------------------------------------------------------------------------------------+ * | [ METHOD if_cuan_mkt_exec_http_outbound~get_parameters. ENDMETHOD. * ---------------------------------------------------------------------------------------+ * | Instance Public Method CL_CUAN_MKT_EXEC_TWITTER->IF_CUAN_MKT_EXEC_HTTP_OUTBOUND~PROCESS_RESPONSE * +-------------------------------------------------------------------------------------------------+ * | [--->] IO_RESPONSE TYPE REF TO IF_HTTP_RESPONSE * | [] CT_REQUEST_PARAM TYPE CUAN_T_MKT_EXEC_PARAM(optional) * +-------------------------------------------------------------------------------------- METHOD if_cuan_mkt_exec_http_outbound~process_response. DATA: lv_http_code TYPE i, lv_reason TYPE string, lv_cdata TYPE string, lv_message TYPE string. io_response->get_status( IMPORTING code = lv_http_code reason = lv_reason ). DATA: lt_headerfields TYPE tihttpnvp. io_response->get_header_fields( CHANGING fields = lt_headerfields ). lv_cdata = io_response->get_cdata( ). CASE lv_http_code. WHEN 200. "Success es_member_status-ia_type = 'DM_OUTBOUND'. WHEN OTHERS. "Error FIND FIRST OCCURRENCE OF REGEX '"message":"(.*)"' IN lv_cdata SUBMATCHES DATA(lv_error). FIND FIRST OCCURRENCE OF REGEX '"code":(.*),"message"' IN lv_cdata SUBMATCHES DATA(lv_error_code). IF lv_error IS INITIAL. MESSAGE e004(cuan_mkt_exec_frw) INTO lv_message WITH lv_http_code lv_reason lv_cdata. ELSE. MESSAGE e063(cuan_mkt_exec_frw) WITH lv_error INTO lv_message. ENDIF. cl_cuan_mkt_exec_messages=>add_message( CHANGING ct_messages = et_messages ). IF lv_error_code = 32 OR lv_error_code = 64 OR lv_error_code = 88 OR lv_error_code = 130 OR lv_error_code = 131 OR lv_error_code = 215. ev_stop_sending = abap_true. ENDIF. es_member_status-ia_type = 'OUTBOUND_FAILED'. CASE lv_error_code. WHEN 88. es_member_status-ia_reason = 'TWITTER_LIMIT_EXCEED'. WHEN 111. es_member_status-ia_reason = 'TWITTER_OPTIN_MISSIN'. WHEN OTHERS. es_member_status-ia_reason = 'TWITTER_ERROR'. ENDCASE. ENDCASE. ENDMETHOD. ENDCLASS.

 

class CL_CUAN_MKT_EXEC_EXECUTE_TWIT definition public inheriting from CL_CUAN_MKT_EXEC_EXECUTE_SMS create public . public section. methods IF_CUAN_MKT_EXEC_ACTION_PARAM~SET_ACTION_DETAILS redefinition . methods IF_CUAN_MKT_EXEC_ACTION_PARAM~SET_ACTION_PARAMETER redefinition . methods IF_CUAN_MKT_EXEC_EXECUTE_ACTN~PRE_PROCESS redefinition . methods IF_CUAN_MKT_EXEC_EXECUTE_ACTN~PROCESS redefinition . protected section. data OAUTH type ref to ZCL_OAUTH . methods CHECK_COMMUNICATION_LIMITS redefinition . methods CHECK_MARKETING_PERMISSION redefinition . methods GET_COMM_ID redefinition . methods WRITE_HASHES_INTERACTIONS redefinition . methods READ_DEP_DATA redefinition . private section. data PARAMETERS type CUAN_T_MKT_EXEC_PARAM . data MV_DM_TEXT type STRING . methods APPEND_OAUTH_PARAMETERS changing !CT_PARAM type CUAN_T_MKT_EXEC_PARAM . methods CREATE_OUTBOUND_OBJECT importing !IT_PARAM type CUAN_T_MKT_EXEC_PARAM exporting !EO_SMS type ref to CL_CUAN_MKT_EXEC_SMS !EV_ERROR type BOOLE_D . ENDCLASS. CLASS CL_CUAN_MKT_EXEC_EXECUTE_TWIT IMPLEMENTATION. * ---------------------------------------------------------------------------------------+ * | Instance Private Method CL_CUAN_MKT_EXEC_EXECUTE_TWIT->APPEND_OAUTH_PARAMETERS * +-------------------------------------------------------------------------------------------------+ * | [] CT_PARAM TYPE CUAN_T_MKT_EXEC_PARAM * +-------------------------------------------------------------------------------------- METHOD append_oauth_parameters. FIELD-SYMBOLS:  TYPE cuan_s_mkt_exec_param. INSERT INITIAL LINE INTO TABLE ct_param ASSIGNING . -param_name = 'oauth_consumer_key'. "#EC NOTEXT -param_value = oauth->get_consumer_key( ). INSERT INITIAL LINE INTO TABLE ct_param ASSIGNING . -param_name = 'oauth_signature_method'. "#EC NOTEXT -param_value = 'HMAC-SHA1'. "#EC NOTEXT INSERT INITIAL LINE INTO TABLE ct_param ASSIGNING . -param_name = 'oauth_token'. "#EC NOTEXT -param_value = oauth->get_oauth_token( ). INSERT INITIAL LINE INTO TABLE ct_param ASSIGNING . -param_name = 'oauth_version'. "#EC NOTEXT -param_value = '1.0'. "#EC NOTEXT ENDMETHOD. * ---------------------------------------------------------------------------------------+ * | Instance Protected Method CL_CUAN_MKT_EXEC_EXECUTE_TWIT->CHECK_COMMUNICATION_LIMITS * +-------------------------------------------------------------------------------------------------+ * | [--->] IV_COMM_MEDIUM TYPE CUAN_CE_COMM_MEDIUM * | [] CT_MEMBER_STATUS TYPE CUAN_T_MKT_EXEC_MEMBER_STATUS * +-------------------------------------------------------------------------------------- method CHECK_COMMUNICATION_LIMITS. endmethod. * ---------------------------------------------------------------------------------------+ * | Instance Protected Method CL_CUAN_MKT_EXEC_EXECUTE_TWIT->CHECK_MARKETING_PERMISSION * +-------------------------------------------------------------------------------------------------+ * | [--->] IV_COMM_MEDIUM TYPE CUAN_CE_COMM_MEDIUM * | [--->] IV_REASON_FAILED TYPE CUAN_CE_IA_REASON(optional) * | [] CT_MEMBER_STATUS TYPE CUAN_T_MKT_EXEC_MEMBER_STATUS * +-------------------------------------------------------------------------------------- method CHECK_MARKETING_PERMISSION. "check for valid data endmethod. * ---------------------------------------------------------------------------------------+ * | Instance Private Method CL_CUAN_MKT_EXEC_EXECUTE_TWIT->CREATE_OUTBOUND_OBJECT * +-------------------------------------------------------------------------------------------------+ * | [--->] IT_PARAM TYPE CUAN_T_MKT_EXEC_PARAM * | [ METHOD create_outbound_object. DATA lv_message TYPE string. DATA lx_root TYPE REF TO cx_root. READ TABLE it_param WITH KEY param_name = if_cuan_mkt_exec_c=>c_param_adapter_class ASSIGNING FIELD-SYMBOL(). IF sy-subrc  0. MESSAGE e007(cuan_mkt_exec_frw) INTO lv_message WITH 'UNEXPECTED_NO_ADAPTER_CLASS'. me->add_message( ). ev_error = abap_true. ENDIF. TRY. CREATE OBJECT eo_sms TYPE (-param_value) EXPORTING it_parameters = it_param. CATCH cx_root INTO lx_root. MESSAGE e012(cuan_mkt_exec_frw) INTO lv_message WITH -param_value. me->add_message( ). ev_error = abap_true. ENDTRY. ENDMETHOD. * ---------------------------------------------------------------------------------------+ * | Instance Protected Method CL_CUAN_MKT_EXEC_EXECUTE_TWIT->GET_COMM_ID * +-------------------------------------------------------------------------------------------------+ * | [] CT_EXEC_MEMBER_STATUS TYPE CUAN_T_MKT_EXEC_MEMBER_STATUS * | [] CT_MESSAGE TYPE BAL_TT_MSG * +-------------------------------------------------------------------------------------- METHOD get_comm_id. DATA lt_ic_key TYPE /bobf/t_frw_key. DATA lt_facet TYPE cuan_t_ce_ic_facet. LOOP AT ct_exec_member_status ASSIGNING FIELD-SYMBOL(). APPEND VALUE #( key = -contact_key ) TO lt_ic_key. ENDLOOP. DATA(lo_srv_ic) = /bobf/cl_tra_serv_mgr_factory=>get_service_manager( iv_bo_key = if_cuan_ce_interact_contact_c=>sc_bo_key ). lo_srv_ic->retrieve_by_association( EXPORTING iv_node_key = if_cuan_ce_interact_contact_c=>sc_node-root iv_association = if_cuan_ce_interact_contact_c=>sc_association-root-facet it_key = lt_ic_key iv_fill_data = abap_true IMPORTING et_data = lt_facet ). LOOP AT ct_exec_member_status ASSIGNING . READ TABLE lt_facet ASSIGNING FIELD-SYMBOL() WITH KEY root_key = -contact_key id_origin = 'ZTWITTER'. IF sy-subrc  0. CONTINUE. ENDIF. -comm_id = -id. ENDLOOP. ENDMETHOD. * ---------------------------------------------------------------------------------------+ * | Instance Public Method CL_CUAN_MKT_EXEC_EXECUTE_TWIT->IF_CUAN_MKT_EXEC_ACTION_PARAM~SET_ACTION_DETAILS * +-------------------------------------------------------------------------------------------------+ * | [ METHOD if_cuan_mkt_exec_action_param~set_action_details. es_action-icon_url = 'https://pbs.twimg.com/profile_images/2284174872/7df3h38zabcvjylnyfe3_bigger.png'. ENDMETHOD. * ---------------------------------------------------------------------------------------+ * | Instance Public Method CL_CUAN_MKT_EXEC_EXECUTE_TWIT->IF_CUAN_MKT_EXEC_ACTION_PARAM~SET_ACTION_PARAMETER * +-------------------------------------------------------------------------------------------------+ * | [ METHOD if_cuan_mkt_exec_action_param~set_action_parameter. APPEND VALUE #( action_parameter = 'ZOC_EXPORT_DESCRIPTION' action_parameter_name = 'Message' action_parameter_type = if_cuan_mkt_orch_constants=>action_param_type-string ) TO et_action_parameter. ENDMETHOD. * ---------------------------------------------------------------------------------------+ * | Instance Public Method CL_CUAN_MKT_EXEC_EXECUTE_TWIT->IF_CUAN_MKT_EXEC_EXECUTE_ACTN~PRE_PROCESS * +-------------------------------------------------------------------------------------------------+ * | [--->] IV_EXEC_RUN_KEY TYPE /BOBF/CONF_KEY * | [ METHOD if_cuan_mkt_exec_execute_actn~pre_process. me->read_dep_data( EXPORTING iv_exec_run_key = iv_exec_run_key IMPORTING ev_error = ev_error ). DATA: token_secret TYPE string, consumer_secret TYPE string, secret TYPE string. FIELD-SYMBOLS:  TYPE cuan_s_mkt_exec_param. oauth ?= zcl_oauth=>get_instance( consumer_name = 'ZKGPMKT' screen_name = 'kgpblr' password = 'Welcome1' ). IF oauth->is_authorized( ) IS INITIAL. "raise exception ENDIF. me->append_oauth_parameters( CHANGING ct_param = et_param ). consumer_secret = oauth->get_consumer_secret( ). token_secret = oauth->get_oauth_token_secret( ). secret = |{ consumer_secret }{ token_secret }|. oauth->set_oauth_secret( secret ). * add process relevant parameters from content sender profile TRY. cl_cuan_mkt_exec_sms=>get_parameters( EXPORTING iv_sender = 'ZTWI' IMPORTING et_parameters = et_param et_messages = DATA(lt_message) ev_error = ev_error ). CATCH cx_root. MESSAGE e010(cuan_mkt_exec_frw) WITH me->ms_campaign_content-sending_profile INTO DATA(lv_message). cl_cuan_mkt_exec_messages=>add_message( CHANGING ct_messages = lt_message ). ev_error = abap_true. RETURN. ENDTRY. ENDMETHOD. * ---------------------------------------------------------------------------------------+ * | Instance Public Method CL_CUAN_MKT_EXEC_EXECUTE_TWIT->IF_CUAN_MKT_EXEC_EXECUTE_ACTN~PROCESS * +-------------------------------------------------------------------------------------------------+ * | [--->] IV_EXEC_RUN_KEY TYPE /BOBF/CONF_KEY * | [--->] IT_TG_MEMBER TYPE /BOBF/T_FRW_KEY * | [--->] IT_CONTENT_ATTR TYPE CUAN_T_MKT_EXEC_PERS_ATTR * | [--->] IT_PARAM TYPE CUAN_T_MKT_EXEC_PARAM * | [--->] IV_PACKAGE_NUMBER TYPE CUAN_MKT_EXEC_PACKAGE_NO * | [ METHOD if_cuan_mkt_exec_execute_actn~process. DATA: lt_exec_member_status TYPE cuan_t_mkt_exec_member_status, lt_pers_content TYPE cuan_t_mkt_exec_pers_content, lr_key_table TYPE REF TO data, lv_sms_addr TYPE ad_telnrlg, lo_sms TYPE REF TO cl_cuan_mkt_exec_sms. * clear messages from log clear_messages( ). * read data of assigned objects me->read_dep_data( EXPORTING iv_exec_run_key = iv_exec_run_key it_tg_member = it_tg_member IMPORTING ev_error = ev_error ). IF ev_error IS NOT INITIAL. et_message = me->get_messages( ). RETURN. ENDIF. IF ev_error IS NOT INITIAL. et_message = me->get_messages( ). RETURN. ENDIF. * convert it tg member to segmentation key structure me->convert_tg_members( EXPORTING it_tg_member = it_tg_member IMPORTING er_key_table = lr_key_table et_ic_key = DATA(lt_ic_key) et_ia_key = DATA(lt_ia_key) et_root_ia_key = DATA(lt_root_ia_key) et_object_type_key = DATA(lt_segobj_key) et_object_type_ds_key = DATA(lt_segobj_ds_key) ev_error = ev_error ev_ic_comp_name = DATA(lv_ic_comp_name) ev_ia_comp_name = DATA(lv_ia_comp_name) ). IF ev_error IS NOT INITIAL. et_message = me->get_messages( ). RETURN. ENDIF. me->initialize_member_status( EXPORTING it_ic_key = lt_ic_key it_ia_key = lt_ia_key it_root_ia_key = lt_root_ia_key ir_key_table = lr_key_table it_object_type_key = lt_segobj_key iv_ic_comp_name = lv_ic_comp_name iv_ia_comp_name = lv_ia_comp_name it_content_attr = it_content_attr IMPORTING et_exec_member_status = lt_exec_member_status et_pers_content = lt_pers_content ev_error = ev_error ). IF ev_error IS NOT INITIAL. APPEND LINES OF me->get_messages( ) TO et_message. RETURN. ENDIF. * read IC root data (TODO integrate with comm ID retrieval) cl_cuan_mkt_exec_helper=>get_ic_root_data( IMPORTING ev_error = ev_error CHANGING ct_pers_content = lt_pers_content ct_member_status = lt_exec_member_status ). * read communication ids (Twitter Handle) me->get_comm_id( IMPORTING ev_error = ev_error CHANGING ct_exec_member_status = lt_exec_member_status ct_message = et_message ). IF ev_error IS NOT INITIAL. RETURN. ENDIF. * continue only with successfully checked members LOOP AT lt_exec_member_status ASSIGNING FIELD-SYMBOL(). READ TABLE lt_pers_content ASSIGNING FIELD-SYMBOL() WITH KEY tg_member_key = -tg_member_key BINARY SEARCH. CHECK sy-subrc IS INITIAL. "todo error handling * for successful checks create email or sms class IF -ia_type IS INITIAL. * create email instance and set email address lv_sms_addr = -comm_id. create_outbound_object( EXPORTING it_param = it_param IMPORTING eo_sms = lo_sms ev_error = ev_error ). IF ev_error = abap_true. et_message = me->get_messages( ). RETURN. ENDIF. -sms_message_ref = lo_sms. -sms_message_ref->if_cuan_mkt_exec_sms~set_recipient( iv_recipient = lv_sms_addr ). -sms_message_ref->if_cuan_mkt_exec_sms~set_body( mv_dm_text ). ELSE. * checks not successful write hash to outbound ID and delete entry from personalization table -outbound_id = -personalization_hash. DELETE lt_pers_content WHERE tg_member_key = -tg_member_key. ENDIF. ENDLOOP. * call http send requests send_sms( EXPORTING it_param = it_param it_pers_content = lt_pers_content CHANGING ct_member_status = lt_exec_member_status ). * persist hashes & interactions DATA(lv_error) = me->write_hashes_interactions( it_exec_member_status = lt_exec_member_status iv_exec_run_key = iv_exec_run_key ). IF ev_error IS NOT INITIAL. RETURN. ENDIF. ENDMETHOD. * ---------------------------------------------------------------------------------------+ * | Instance Protected Method CL_CUAN_MKT_EXEC_EXECUTE_TWIT->READ_DEP_DATA * +-------------------------------------------------------------------------------------------------+ * | [--->] IV_EXEC_RUN_KEY TYPE /BOBF/CONF_KEY * | [--->] IT_TG_MEMBER TYPE /BOBF/T_FRW_KEY(optional) * | [ METHOD read_dep_data. DATA: lt_key TYPE /bobf/t_frw_key, lt_root_key TYPE /bobf/t_frw_key, lt_root TYPE cuan_t_marketing_orch_root, lt_campaign_root TYPE cuan_t_initiative_root, lt_action_parameter TYPE cuan_t_marketing_orc_act_par, lv_content_id TYPE cuan_me_engagement_id. me->mv_exec_run_key = iv_exec_run_key. me->mt_tg_members = it_tg_member. CLEAR: ev_error. DATA(lo_srv_mktorc) = /bobf/cl_tra_serv_mgr_factory=>get_service_manager( iv_bo_key = if_cuan_marketing_orch_c=>sc_bo_key ). APPEND VALUE #( key = iv_exec_run_key ) TO lt_key. lo_srv_mktorc->retrieve_by_association( EXPORTING iv_node_key = if_cuan_marketing_orch_c=>sc_node-execution_run iv_association = if_cuan_marketing_orch_c=>sc_association-execution_run-to_root it_key = lt_key iv_fill_data = abap_true IMPORTING et_data = lt_root ). READ TABLE lt_root INDEX 1 ASSIGNING FIELD-SYMBOL(). IF sy-subrc = 0. me->ms_mktorc_root = . APPEND VALUE #( key = -key ) TO lt_root_key. lo_srv_mktorc->retrieve_by_association( EXPORTING iv_node_key = if_cuan_marketing_orch_c=>sc_node-root iv_association = if_cuan_marketing_orch_c=>sc_association-root-initiative it_key = lt_root_key iv_fill_data = abap_true IMPORTING et_data = lt_campaign_root ). READ TABLE lt_campaign_root INDEX 1 INTO me->ms_campaign_root. IF sy-subrc  0. * -> no error, e.g. confirmation scenario ENDIF. ENDIF. * read tg data by first entry of it_tg_member_keys READ TABLE it_tg_member ASSIGNING FIELD-SYMBOL() INDEX 1. IF sy-subrc IS INITIAL. DATA: lt_tg_root TYPE cuan_t_tg_root. DATA: lt_member_key TYPE /bobf/t_frw_key. * retrieve tg member data DATA(lo_srv_tg) = /bobf/cl_tra_serv_mgr_factory=>get_service_manager( iv_bo_key = if_cuan_target_group_c=>sc_bo_key ). APPEND VALUE #( key = -key ) TO lt_member_key. lo_srv_tg->retrieve_by_association( EXPORTING iv_node_key = if_cuan_target_group_c=>sc_node-customer_member iv_association = if_cuan_target_group_c=>sc_association-customer_member-to_root iv_fill_data = abap_true it_key = lt_member_key IMPORTING et_data = lt_tg_root ). * read tg root to determine member type for first entry READ TABLE lt_tg_root INTO me->ms_tg_root INDEX 1. IF sy-subrc  0. MESSAGE e007(cuan_mkt_exec_frw) INTO DATA(lv_message) WITH 'READ_TG_ROOT'. me->add_message( ). ev_error = abap_true. ENDIF. ENDIF. lo_srv_mktorc->retrieve_by_association( EXPORTING iv_node_key = if_cuan_marketing_orch_c=>sc_node-execution_run iv_association = if_cuan_marketing_orch_c=>sc_association-execution_run-to_parent it_key = lt_key IMPORTING et_target_key = DATA(lt_action_key) ). lo_srv_mktorc->retrieve_by_association( EXPORTING iv_node_key = if_cuan_marketing_orch_c=>sc_node-action iv_association = if_cuan_marketing_orch_c=>sc_association-action-action_parameter it_key = lt_action_key iv_fill_data = abap_true IMPORTING et_data = lt_action_parameter ). * read content ID from action parameter READ TABLE lt_action_parameter ASSIGNING FIELD-SYMBOL() WITH KEY parameter_id = 'ZOC_EXPORT_DESCRIPTION'. me->mv_dm_text = -parameter_value. ENDMETHOD. * ---------------------------------------------------------------------------------------+ * | Instance Protected Method CL_CUAN_MKT_EXEC_EXECUTE_TWIT->WRITE_HASHES_INTERACTIONS * +-------------------------------------------------------------------------------------------------+ * | [--->] IT_EXEC_MEMBER_STATUS TYPE CUAN_T_MKT_EXEC_MEMBER_STATUS * | [--->] IV_EXEC_RUN_KEY TYPE /BOBF/CONF_KEY * | [ METHOD write_hashes_interactions. * write hashes for tracking * write_hashes( it_exec_member_status ). * create interactions DATA ls_template_interaction TYPE cuan_s_ce_ia_int. ls_template_interaction = VALUE #( id_origin = 'ZTWITTER' comm_medium = 'SMS' quantifier = 1 marketing_orchestration_id = me->ms_campaign_content-id content_title = me->ms_campaign_content-name ). me->post_interactions( EXPORTING it_member_status = it_exec_member_status is_template_interaction = ls_template_interaction IMPORTING ev_error = rv_error ). ENDMETHOD. ENDCLASS.

New NetWeaver Information at SAP.com

Very Helpfull

User Rating: Be the first one !