Magnolia 5.7 reached extended end of life on May 31, 2022. Support for this branch is limited, see End-of-life policy. Please note that to cover the extra maintenance effort, this EEoL period is a paid extension in the life of the branch. Customers who opt for the extended maintenance will need a new license key to run future versions of Magnolia 5.7. If you have any questions or to subscribe to the extended maintenance, please get in touch with your local contact at Magnolia.

This module is deprecated. See Deprecations.

Magnolia connects to Salesforce to capture and enrich leads. This gives you the possibility to capture more precise leads and nurture leads by providing Salesforce with the data that leads are using. Magnolia's personalization feature can retrieve information from Salesforce to provide tailored content to web visitors, proving a richer user experience.

Installing

Maven is the easiest way to install the module. Add the following to your bundle. The parent POM of your webapp project should set the latest version of the module automatically. Should you need to use a specific module version, you can define it using the <version/> in the dependency.

<dependency>
  <groupId>info.magnolia.salesforce</groupId>
  <artifactId>magnolia-salesforce</artifactId>
</dependency>

Connect your SalesForce instance

Create a connected app in SalesForce admin central.

  1. Click you user name in the upper right corner and choose setup.
  2. In the menu on the left side: App Setup → Create → Apps.
  3. At the bottom: Connected Apps → New Fill:
    1. Connected App NameAPI Name  (values don't matter)
    2. Contact Email
    3. Check the section API (Enable OAuth Settings)
      1. Callback URL: list all your public instances:  http(s)://<domain>/<contextPath>/callback , e.g  http://localhost:8080/magnoliaPublic/callback
      2. Set full access in you don't need to specify more granular permissions.

  4. Save.
  5. Back in the list of apps: Click on your new app name (next to the Edit and Manage).
  6. Copy  Consumer Key Consumer Secret to your Magnolia instance (see the next section).
  7.  
  8. If you don't know your Security token yet:
    1. In the left menu: Personal Setup → My Personal Information → Reset My Security Token
    2. Copy the Security token from the email you've just received  to your Magnolia instance (see the next section).  

Read more 

Configuration

  • Provide URL of your Salesforce instance (config:/module/salesforce/rest-client/salesForceHttpClient/baseUrl).
  • Rest calls to Salesforce need to be done as administrator. Please provide credentials (config:/module/salesforce/config).
  • We need to authenticate Accounts to be able provide personalized content for them. Accounts are not logged into Salesforce as Salesforce users but only into Magnolia context. You need to provide a custom text field to Accounts module on you Salesforce instance under Setup - App Setup - Customize - Accounts - Fields where the passwords will be stored. Define the name of this field under config:server/filters/SalesForceAccountAuthenticationFilter@passwordFieldName.

    Node nameValue

     salesforce


          rest-client


              salesForceHttpsClient


                  class

    info.magnolia.resteasy.client.RestEasyClientDefinition

                  baseUrl

    https://YOUR_SALES_FORCE_INSTANCE/services

                  clientFactoryClass

    info.magnolia.resteasy.client.factory.RestEasyClientFactory

                  clientFilters


          config

    https://help.salesforce.com/apex/HTViewHelpDoc?id=connected_app_create.htm

              adminPassword

    *

              consumerSecret

    *

              adminName

    *

              adminSecurityToken

     https://help.salesforce.com/apex/HTViewHelpDoc?id=user_security_token.htm

              consumerKey

    *

    Sample pages

Commands

The first think which we need is a command which performs rest calls to the Salesforce instance. There are four basic command for authentication, get and post request already implemented. You can see the example of the rest call to retrieve all the campaigns names from Salesforce.

 

SalesForceCommands parameters
NameConstant fieldDescription values
Object nameinfo.magnolia.salesforce.command.AbstractSalesForceCommand#PARAMETER_S_OBJECT_NAME = "salesForceSObjectName" A string representing module name (e.g. Account).
Queryinfo.magnolia.salesforce.command.SalesForceQueryCommand#PARAMETER_QUERY = "salesForceQuery"

A query to be performed.

Request bodyinfo.magnolia.salesforce.command.SalesForcePostCommand#PARAMETER_BODY = "salesForceBody"An instance of org.codehaus.jackson.JsonNode.
Http methodinfo.magnolia.salesforce.command.SalesForcePostCommand#PARAMETER_HTTP_METHOD = "salesForceMethod"

info.magnolia.salesforce.command.SalesForcePostCommand#

METHOD_PATCH = "PATCH"
METHOD_POST = "POST"

public class MyTestClass {
    private final RestEasyCommandsManager commandsManager;
 
    @Inject
    public MyTestClass(RestEasyCommandsManager commandsManager) {
            this.commandsManager = commandsManager;
    }
    public JsonNode execute(final String command, final String path, final Map<String, Object> parameters) throws Exception {
            Map<String, Object> parameters = new HashMap<String, Object>();
            parameters.put(SalesForceQueryCommand.PARAMETER_QUERY, "SELECT Campaign.Name FROM Campaign");
            return this.getCommandsManager().executeCommand(SalesForceQueryCommand.CATALOG, "SalesForceQueryCommand", SalesForceQueryCommand.PARAMETER_RESULT, parameters);
    }}
}



Node nameValue

 commands


      salesforce


          SalesForceAuthorizeCommand


              class

info.magnolia.salesforce.command.SalesForceAuthorizeCommand

          SalesForceGetCommand


              class

info.magnolia.salesforce.command.SalesForceGetCommand

          SalesForceQueryCommand


              class

info.magnolia.salesforce.command.SalesForceQueryCommand

          SalesForcePostCommand


              class

info.magnolia.salesforce.command.SalesForcePostCommand


Personalization

The samples contain traits for the Personalization module. Those are able to retrieve informations from Salesforce to provide personalized content. In this chapter is described how you can create a custom trait on the provided samples. If you've never created personalized content in Magnolia, please see Creating custom traits .

Trait detector filter

Node nameValue

 SalesForceDetectorFilter


      enabled

true

      class

info.magnolia.salesforce.personalization.SalesForceDetectorFilter

      traitClass

info.magnolia.salesforce.personalization.SalesForceTraits

      queries


          Opportunity

SELECT Type FROM Opportunity o, o.Account a WHERE a.Name='{salesForceExternalName}'

          Account

SELECT Id, password__c, Name, Industry, BillingStreet, BillingState, BillingPostalCode, BillingCity, BillingCountry FROM Account WHERE Name = '{salesForceExternalName}'

          Campaign

SELECT Campaign.Name FROM Opportunity o, o.Account a WHERE a.Name='{salesForceExternalName}'

Trait voter


A trait voter decides if a certain page variant has to be served to the current user or not. There's not much difference between a  SalesForceVoter  trait voter and any other voter. The default trait voter for Salesforce doesn't use any special logic compared to  info.magnolia.externaltraits.filter.AbstractJsonTraitVoter . This voter just splits the passed String value to module name - property path - expected property value regexp . For example the value is   Opportunity-Type-Existing Business.  The voter looks for Opportunity trait which are all the opportunities related to logged in account. Then searches for type of all opportunities and returns true if there is at least one opportunity with the type  Existing Business.

public class SalesForceVoter extends AbstractJsonTraitVoter {
    public SalesForceVoter() {
        super(SalesForceTraits.class);
    }
}

Preview parameter converter

Parameter converter is needed for Personalization#Personalization-Preview. It Converts String to a corresponding trait class holding a json and vice versa. There a no special logic in the default

SalesForceParameterConverter. It expect a property value in the format traitName-propertyPath-expectedValueRegexp. For example we want to check if there is an Opportunity with the Type Existing Business, we set the value Opportunity-Type-Existing Business via choose audience dialog to a page variant. 

   
public class SalesForceParameterConverter extends AbstractJsonTraitParameterConverter {
    public SalesForceParameterConverter() {
        super(SalesForceTraits.class);
    }
}

Sample traits example

Read more