CRM and CX Blogs by SAP
Stay up-to-date on the latest developments and product news about intelligent customer experience and CRM technologies through blog posts from SAP experts.
cancel
Showing results for 
Search instead for 
Did you mean: 
Arne_Manthey
Advisor
Advisor

Methods for Suppression


Campaign Execution Exclusion App




One of the usages for the old Suppression Rules app have been to suppress contacts with specific email addresses or from certain domains. Luckily we now have this dedicated app to do exactly this. Additionally you can import CSV lists directly into the app and also provide a reason text for every entry.

See also documentation on Campaign Execution Exclusion.

Communication Category Limits App




Of course this app is around for a long time already but it still has a lot of value for a specific use case. However, it is not a globally active suppression method since you need to assign the communication category which has limits defined to every email or text message which need to be checked against those limits (Of course you can use that communication category already in an email template). Then the check also only looks at all emails with the same communication category. But this could also be exactly what you intend to do. The app is also restricted to email and text messages - no other communication medium is supported.

See also documentation on Communication Categories and Limits.

Segmentation / Filter with Live Target Groups




Just for completeness I also mention the segmentation as a means to suppress certain contacts. If you can build your dynamic target group already in such a way that it only holds this contacts that you want to address then you might avoid certain suppression requirements already.

Additionally you can use the segmentation to create Live target Groups which you can use as a filter in Campaign execution (look at the field 'Filter Condition' in the 'Send Email' action). This allows you to have an additional suppression method on execution level. Again this is not a global suppression rule because you have to make sure that you really use that filter condition. One way to achieve this is the usage of campaign templates with such a filter in place.

See also documentation on Filtering.

Suppression BAdI (New features and examples in 1908)




The BAdI for suppression exists for some time now but it has been improved in 1908 with some helper classes for cleaner code and examples for common use cases. The BAdI is checked right before the campaign execution like permissions, limits and the now deprecated Suppression Rules.

Of course you need to know a little ABAP to fully use the potential of this BAdI. However with the examples you can already start by just activating some of those example code snippets. In the use case section below I will explain some of the example code.

Getting Started


You find the app to define the BAdI logic in group 'Extensibility and Adaptability for Marketing' in the app 'Marketing Extensibility'. In the app you need to select 'Create Custom Fields' (A little counter-intuitive because it says nothing about logic). There you need to select the tab 'Custom Logic'.

Then you need to create a new entry for the business context 'Marketing: Permission' and the BAdI Description 'Suppression Rules Check'. Give it a name and create. Next you should have a look at the BAdI Documentation (Tab and link in the UI) and the examples (By pressing the button 'Example' on the right). Usually the example is already filled in the code editor of the draft. If not you can just copy and paste it from the example section. I would then recommend to pick one of the examples that you want to evaluate and remove the rest. However, you must not remove the first declarations above the first example! (DATA(factory) =...)

If you try to code for yourself based on the hints I give you further down, remember that you can usually get code completion information when hitting Control-Space.

You can now publish the BAdI and run a campaign to test it. Be aware that this is a global check and that any other users will also be affected by your Suppression BAdI! Once you get more familiar with the coding you could also include some restrictions during testing so that the code only affects certain campaigns, for example with a certain pattern (e.g. '_SR_') in the name:
DATA(factory)   = cl_cuan_sr_badi_api_factory=>get_instance( ).
DATA(read) = factory->create_reader( ).
DATA(suppress) = factory->create_suppressor( ).
DATA(allow) = factory->create_allowance( ).
DATA(calculate) = factory->create_calculator( ).
DATA(calendar) = factory->create_calendar( ).
suppression_rules_result = suppression_rules_input.

DATA(campaign) = read->campaign( campaign_id ).
IF campaign-CampaignName CP '*_SR_*'.
# Your suppression code comes here...
ENDIF.

Separation of Code Logic and Business Parameters


You might argue that you have certain parameters in your suppression logic which need to be adapted by business users from time to time and that it is not acceptable to allow your business users to adapt those parameters in the BAdI coding itself. There are two suggestions on how to approach this:

Split the Coding in two Sections and give Key Users Access


The easiest way, although not fool-proofed, is to split the code into a parameter section at the beginning and a logic section afterwards. You can use a lot of comments in the parameter section to explain the parameters. Then you give access to the app to change the BAdI to a limited number of key users and explain to them that they are allowed to change the first section but that they must not do any changes below. Here is an example:
*** Parameters ********************************************************
DATA(email_hours) = 12. "Delay between emails
DATA(email_count) = 2. "Number of emails allowed in the delay period

*** Code – Do not change **********************************************
IF action_id = 'SEND_EMAIL'.
suppress->with_recent_interactions(
EXPORTING
interaction_type = 'EMAIL_OUTBOUND'
period = calculate->period_hours( email_hours )
count = email_count
CHANGING
results = suppression_rules_result ).
ENDIF.

Define a Custom Business Object for Suppression Parameters


This method is more advanced and I have described the process in this blog post: 'Suppression: Separating Business Parameters from BAdI Coding using a Custom Business Object'. Here is the summary of process steps:

  1. Specify the use case to derive the structure of the CBO

  2. Create a CBO which includes the desired parameters as fields. It is easy to generate a UI for this where you can then add new entries as a line with multiple columns. Then add the generated UI to a business catalog to give your business users the possibility to maintain those parameters.

  3. Develop a generic code inside your suppression BAdI which reads line by line of your CBO and executes the suppression logic accordingly.


Useful Helper Methods


In the following sections I explain some of the most useful helper methods which have been introduced in 1908. However there might be more when you read this at a later time - so this is only a limited choice.

Please note that for all examples shown below (and generally for the entire coding) it is necessary that you have the following declaration at the top of the coding (as its is in the example coding):
DATA(factory)   = cl_cuan_sr_badi_api_factory=>get_instance( ).
DATA(read) = factory->create_reader( ).
DATA(suppress) = factory->create_suppressor( ).
DATA(allow) = factory->create_allowance( ).
DATA(calculate) = factory->create_calculator( ).
DATA(calendar) = factory->create_calendar( ).
suppression_rules_result = suppression_rules_input.

 

Suppress with Recent Interactions


Suppress contacts which had a certain number of a specific interaction in a given time period (in seconds). This should be one of the most commonly used methods.

Example: Suppress all contacts that had 3 or more emails in the last 7 days (25200 seconds)
suppress->with_recent_interactions(
EXPORTING
interaction_type = 'EMAIL_OUTBOUND'
period = 25200
count = 3
CHANGING
results = suppression_rules_result ).

 

Suppress with Interactions


This method suppresses contacts that had a specific number of interactions of a certain type regardless of any period.

Example: Suppress all contacts with 3 soft bounces or more.
suppress->with_interactions(
EXPORTING
interaction_type = 'EMAIL_BOUNCE_SOFT'
count = 3
CHANGING
results = suppression_rules_result ).

 

Suppress Contacts


This method allows the specific suppression of a list of contacts that has been prepared by any coding before.

Example: See example in section 'Read Contacts and their Attributes' below.

 

Allow ...


This works similarly as the suppress class (it has the same methods, see above) but it reverses the effect. This might be useful as a code block at the end to include certain test contacts again into the execution regardless of any previous suppression rules.

Example: Re-introduce all contacts with email addresses of the domain 'tester.domain'
allow->with_email_address (
EXPORTING
email_pattern = '*@tester.domain'
CHANGING
results = suppression_rules_result ).

 

Read Campaign Attributes


Retrieve campaign attributes from the campaign ID.

Example: Run suppression code only if the campaign name matches the pattern '_SR_'
DATA(campaign) = read->campaign( campaign_id ).
IF campaign-CampaignName CP '*_SR_*'.
#...
ENDIF.

 

Read Contacts and their Attributes


Retrieve contacts together with all contact attributes.

Example: Get all contacts which live in 'Banned Street' and suppress them.
DATA(contacts) = read->contacts( suppression_rules_result ).

DELETE contacts WHERE StreetName <> 'Banned Street'.

suppress->contacts(
EXPORTING
contacts = contacts
CHANGING
results = suppression_rules_result ).

 

Calculate different Periods into Seconds


Since all suppression methods which involve a period use seconds as a unit this is a useful method for better readability. The following methods are available: period_days, period_hours, period_minutes.

Example: Suppress all contacts with an email in the last 7 days.
suppress->with_recent_interactions(
EXPORTING
interaction_type = 'EMAIL_OUTBOUND'
period = calculate->period_days( 7 )
count = 1
CHANGING
results = suppression_rules_result ).

There are some other related methods that do not take any parameter but return the number of seconds since the start of an actual period: period_current_monthperiod_current_weekperiod_today.

Example: Suppress all contacts that have already received an email in the current week.
suppress->with_recent_interactions(
EXPORTING
interaction_type = 'EMAIL_OUTBOUND'
period = calculate->period_current_week( )
count = 1
CHANGING
results = suppression_rules_result ).

 

Use Cases / Examples


Here are the most common use cases that we have identified in numerous customer interactions:


  1. Suppress email addresses and domains (Exclusion List)

  2. Suppress based on a contact attribute (e.g. flag ‚Do not contact‘)

  3. Suppress based on past interaction types (e.g. hard bounces)

  4. Restrict outbound interactions to a certain number in a time interval

  5. Ensure a certain time interval between outbound interactions

  6. Ensure a certain time interval between outbound interactions depending on the Campaign Priority


In the following sections I discuss each of these use cases in more detail together with recommendations on the preferred solution and alternatives. Some of the use cases are also available in the BAdI examples.

Suppress email addresses and domains (Exclusion List)

















Description Suppress all contacts with a specific email address or an address from a specific domain (Exclusion List scenario).
Preferred Solution Campaign Execution Exclusion List (See above in section 'Alternative Methods for Suppression')

  • Dedicated app for the use case

  • Easy to maintain


Alternative(s) Suppression BAdI, Live Target Groups

 

Suppress based on a contact attribute (e.g. flag ‚Do not contact‘)




















Description Exclude contacts based on specific contact attributes.
Preferred Solution Suppression BAdI
Alternative(s) Live Target Groups
Example: Suppress all contacts not located in Germany for a campaign with marketing area ‘Germany’
DATA(contacts) = read->contacts(suppression_rules_result).

IF campaign-marketingarea EQ 'GERMANY'.

LOOP AT contacts ASSIGNING FIELD-SYMBOL(<contact>)
WHERE country NE 'DE'.

suppress->contact(
EXPORTING
contact_key = <contact>-InteractionContact
CHANGING
results = suppression_rules_result ).

ENDLOOP.

ENDIF.


 

Suppress based on past interactions




















Description Do not send emails for a contact if a specific interaction had been created in the past. (e.g. Hard bounces,
Preferred Solution

  • For hard bounces nothing needs to be done since the system removes any email adress which resulted in a hard bounce (see Handling Bounces).

  • For emails which have been classified as spam an automatic opt-out can be done if the ESP supports it (see Enabling Complaints for Emails)

  • For all other cases: Suppression BAdI


Alternative(s) None
Example: Do not send emails to contacts with 3 or more soft bounces
suppress->with_interactions(
EXPORTING
interaction_type = 'EMAIL_BOUNCE_SOFT'
count = 3
CHANGING
results = suppression_rules_result ).

 

 

Restrict outbound interactions to a certain number in a time interval




















Description Allow a certain number of outbound communication interactions per time frame.
Preferred Solution Suppression BAdI

  • Any communication medium possible

  • Flexible time intervals

  • Global rule


Alternative(s) Communication Category Limits (Was not possible with the Suppression Rules app)
Example: Suppress contacts with 3 or more emails every 7 days
IF action_id = 'SEND_EMAIL'.
suppress->with_recent_interactions(
EXPORTING
interaction_type = 'EMAIL_OUTBOUND'
period = calculate->period_days( 7 )
count = 3
CHANGING
results = suppression_rules_result ).
ENDIF.


 

Ensure a certain time interval between outbound interactions




















Description Ensure a certain time interval between outbound communication interactions. Also consider different combinations of communication media (e.g. different intervals between 2 emails and between an email and a phone call).
Preferred Solution Suppression BAdI

  • Any communication medium possible

  • Dependencies between different communication media possible

  • Flexible time intervals

  • Global rule


Alternative(s) Communication Category Limits (Limit set to 1)
Example: Do not send an email during 10 days after a phone call and during 4h after an email
IF action_id = 'SEND_EMAIL'.

suppress->with_recent_interactions(
EXPORTING
interaction_type = 'TELEPHONE_OUTBOUND'
period = calculate->period_days(10)
count = 1
CHANGING
results = suppression_rules_result).

suppress->with_recent_interactions(
EXPORTING
interaction_type = 'EMAIL_OUTBOUND'
period = calculate->period_hours(24)
count = 1
CHANGING
results = suppression_rules_result ).

ENDIF.​


 

Ensure a certain time interval between outbound interactions depending on the Campaign Priority




















Description Enhanced variant of use case 3 with additional condition based on campaign data like the campaign priority
Preferred Solution Suppression BAdI

  • Additional conditions based on contact and campaign attributes

  • Any communication medium possible

  • Dependencies between different communication media possible

  • Flexible time intervals

  • Global rule


Alternative(s) None
Example: For campaigns with priority ‘Low’ do not send an email during 10 days after a phone call and during 24h after an email.
IF campaign-campaignpriority = '4'.

IF action_id = 'SEND_EMAIL'.

suppress->with_recent_interactions(
EXPORTING
interaction_type = 'TELEPHONE_OUTBOUND'
period = calculate->period_days( 10 )
count = 1
CHANGING
results = suppression_rules_result).

suppress->with_recent_interactions(
EXPORTING
interaction_type = 'EMAIL_OUTBOUND'
period = calculate->period_hours( 24 )
count = 1
CHANGING
results = suppression_rules_result ).

ENDIF.

ENDIF.


 

Conclusion


After reviewing all of the sections above you should be able to make an informed decision on the suppression method you can use.
12 Comments