Microsoft Dynamics 365
Learn how to integrate your Microsoft Dynamics instance with Strivacity, allowing Strivacity to add, update and maintain customer information and use it as a source of entitlement.
Integrating Strivacity with Microsoft Dynamics provides the following benefits:
- Use Microsoft Dynamics customer information as a source of entitlement during customer registration, login, or any step within the customer account lifecycle
- Create new customer records, and synchronize/update those customer records with the latest customer account information (from Strivacity)
- If required, migrate customer information from Microsoft Dynamics to Strivacity upon account registration
They're two steps to setting up Strivacity with Microsoft Dynamics 365:
- Setup Microsoft Power Platform to register Strivacity as an Application and define API permissions for the application, and enable public client access
- Setup a pre-registration hook within Strivacity
1) Setup Microsoft Power Platform to register Strivacity as an Application
- From within the Azure Active Directory Dashboard, click on App registrations, and click + New registration
- Define a name for your new application
- Choose Accounts in any organizational directory (Any Azure AD directory - Multi-tenant)
- Click the Register button. Your newly created application should be registered as shown in the screenshot below.
Make a record of the ClientID so that you can use it at a later stage of the integration.
- Next, click on Certificates and Secrets
- Click on New client secret and copy it to a safe location for use later in this integration. Note you will not be able to copy the secret again later
- Next, click on API permissions, and then Add a permission
- Select Dynamics CRM as shown below:
- Next, search for “user_impersonation”, and then click add permissions as shown below:
- Now click on Manifest, and set allowPublicClient to true, as shown highlighted below:
This completes the initial configuration within Microsoft Dynamics 365 for use with Strivacity.
Create a 'Before registration' hook from the Microsoft Dynamics 365 plugin
Our plugin library contains an off-the-shelf Microsoft Dynamics 365 event hook template that jumpstarts your integration process and allows you to customize it to your needs.
- In the Admin Console, go to Lifecycle Event Hooks.
- Click ' Add plugin'. You will be redirected to the plugin library.
- Click on the Microsoft Dynamics 365 logo. You can find it in the CRM section.
- There will be a pre-select for the event hook, so you only need to click 'Add'.
- Wait for the Microsoft Dynamics 365 hook template to be added.
If the Admin Console doesn't want to add the hook, it's most likely that the name of the hook is already taken. Click 'Edit' and you can modify the name of the event hook. Then continue with 'Try again'.
- If the hook has been successfully added, you can return to the list view with 'Back to plugin library', then 'Back to event hooks'.
You can add the following to the event hook plugin:
- Define
DYNAMICS_AUTHORITY_URL
,DYNAMICS_RESOURCE
,DYNAMICS_CLIENT_ID
, andDYNAMICS_CLIENT_SECRET
you noted from step 1 above.
This will search Microsoft Dynamics 365 for a contact matching the primary email address
Now add any additional logic as you see fit!
var dynamics = require('dynamics-web-api');
var AuthenticationContext = require('adal-node').AuthenticationContext;
// dynamics config
var DYNAMICS_AUTHORITY_URL = 'https://login.microsoftonline.com/<YOUR TENANT>/oauth2/token';
var DYNAMICS_RESOURCE = 'https://<YOUR DYNAMICS INSTANCE>.crm.dynamics.com/';
var DYNAMICS_CLIENT_ID = '<CLIENT ID>';
var DYNAMICS_CLIENT_SECRET = '<CLIENT SECRET>'
// get an adal context for use in auth
var adalContext = new AuthenticationContext(DYNAMICS_AUTHORITY_URL);
/** This function will be called from the Pre registration hook in a blocking manner.
*
* @param {Object} args Input arguments
* @param {Object} args.application Application related information
* @param {string} args.application.name Name
* @param {string} args.application.client_id OAuth client ID
*
* @param {Object} args.oidc_context Information about the originating OpenID Connect request
* @param {string[]} args.oidc_context.acr_values ACR values
* @param {string[]} args.oidc_context.ui_locales UI locales
*
* @param {Object} args.customer Customer related information
* @param {string} args.customer.ip_address HTTP client IP coming from the X-Forwarded-For header
* @param {string} args.customer.store Userstore
* @param {Object} args.customer.attributes User attributes provided during the registration
* @param {Object} args.customer.identifiers User identifiers provided during the registration
* @param {Object[]} args.customer.consents User consents accepted during the registration
* @param {string} args.customer.location.city City of the customer
* @param {string} args.customer.location.state State of the customer
* @param {string} args.customer.location.country Country of the customer
* @param {string} args.customer.location.country_code Country code of the customer
* @param {string} args.customer.location.coordinates.latitude Latitude coordinate of the customer
* @param {string} args.customer.location.coordinates.longitude Longitude coordinate of the customer
*
* @param {Object} args.session Session store
* @param {Object} args.continue_context Continue context
*
* @param {Object} args.continue_request_parameters Continue request parameters
* @param {string} args.continue_request_parameters.callback_url Callback url to use after a continue call
* @param {string} args.continue_request_parameters.state State parameter to use after a continue call
* @param {preRegistrationCallback} callback
* @param {denyRequestCallback} error
*/
module.exports = async function ({ application, oidc_context, customer, session, continue_context, continue_request_parameters }, callback, error) {
console.log(customer)
var client = new dynamics({
webApiUrl: DYNAMICS_RESOURCE + 'api/data/v9.1/',
onTokenRefresh: acquireToken
});
var records = await client.retrieveMultiple("contacts", ["fullname"], `emailaddress1 eq '${customer.attributes.emails.primaryEmail}'`)
console.log(records)
// the following function call does not modify the registering user
callback(new RegistrationData(customer.attributes, [], session));
};
/**
* Callback for acquiring a token via ADAL
*/
function acquireToken(callback) {
function adalcb(error, token) {
if (!error) {
callback(token);
} else {
throw new Error(error)
}
}
// get the token
adalContext.acquireTokenWithClientCredentials(DYNAMICS_RESOURCE, DYNAMICS_CLIENT_ID, DYNAMICS_CLIENT_SECRET, adalcb);
}
/** Allow registration
*
* @callback preRegistrationCallback
* @param {RegistrationData|RedirectRequest|ShowErrorMessage} token
*/
/** Deny registration
*
* @callback denyRequestCallback
* @param {ErrorDenyRequest} error
*/
/** RegistrationData */
class RegistrationData {
attributes = {}
additionalAuthenticators = []
session = {}
/**
* @constructor
* @param {Object} attributes
* @param {AdditionalAuthenticator[]} additionalAuthenticators
* @param {Object} session
*/
constructor(attributes, additionalAuthenticators, session) {
this.attributes = attributes;
this.additionalAuthenticators = additionalAuthenticators;
this.session = session;
}
}
/** AdditionalAuthenticator */
class AdditionalAuthenticator {
type = null;
target = null;
/**
* @constructor
* @param {"email"|"phone"} type
* @param {string} target
*/
constructor(type, target) {
this.type = type;
this.target = target;
}
}
/** RedirectRequest is a global object
* @constructor
* @param {string} redirect_url
* @param {Object} session
*/
/** ShowErrorMessage is a global object
* @constructor
* @param {string} error_message
* @param {Object} session
*/
/** ErrorDenyRequest is a global object
* @constructor
* @param {string} description
* @param {string} hint
*/
Updated 5 months ago