Cross Organization Contact Synchronization Plug-In Sample
Hi all
My colleague Fouad Rachkidi (CRM Escalation Engineer) who already posted another sample on this blog, created today a Pug-In which can allow you to create/update Contact across multiple Organization.
Ex: You created Contact1 in Org1, it gets automatically created in Org2.
It does also work on Updates of course, here are all the details and code.
Plugin Registration Information:
Plugin Registration XML:
<Register LogFile="Plug-in Registration Log.txt" Server="https://sqlcrmsrv:5555" Org="Org1" Domain="frachkid" UserName="crmadmin">
<Solution SourceType="1" Assembly="IntegrationPlugin.dll" Id="3290a2ae-b3c0-4e13-a89d-605e9c58a5fd">
<PluginTypes>
<Plugin TypeName="IntegrationPlugin.IntegrationClass" FriendlyName="7a38185e-afd4-400a-b651-135783c44505" Id="48d50154-3ee5-4441-aca5-e52af2a5da82">
<Steps>
<Step PluginTypeName="IntegrationPlugin.IntegrationClass" PluginTypeFriendlyName="7a38185e-afd4-400a-b651-135783c44505" CustomConfiguration="" SecureConfiguration="" Description="Update of contact in Parent Pipeline" FilteringAttributes="" ImpersonatingUserId="" InvocationSource="0" MessageName="Update" Mode="1" PrimaryEntityName="contact" SecondaryEntityName="none" Stage="50" SupportedDeployment="0" Rank="1" Id="e47a6698-c7c2-de11-895a-00155dcd1a24">
<Images>
<Image EntityAlias="preEnityImageXml" ImageType="0" MessagePropertyName="Target" Attributes="" Id="41b818ab-c7c2-de11-895a-00155dcd1a24" />
<Image EntityAlias="postEnityImageXml" ImageType="1" MessagePropertyName="Target" Attributes="" Id="157ae5b4-c7c2-de11-895a-00155dcd1a24" />
</Images>
</Step>
<Step PluginTypeName="IntegrationPlugin.IntegrationClass" PluginTypeFriendlyName="7a38185e-afd4-400a-b651-135783c44505" CustomConfiguration="" SecureConfiguration="" Description="Create of contact in Parent Pipeline" FilteringAttributes="" ImpersonatingUserId="" InvocationSource="0" MessageName="Create" Mode="1" PrimaryEntityName="contact" SecondaryEntityName="none" Stage="50" SupportedDeployment="0" Rank="1" Id="a9cfab49-cac2-de11-895a-00155dcd1a24">
<Images />
</Step>
</Steps>
</Plugin>
</PluginTypes>
</Solution>
</Register>
Creating a new Contact in Org1….
Contact created successfully in Org1…
Same contact created in Org2 by the integration plugin.
Now updating contact in Org1…
Same contact in Org2 updated by the plugin.
Plug-In Source Code :
using System;
using System.Collections.Generic;
using System.Text;
using IntegrationPlugin.Org1CrmSdk; //Web proxy for Org1 CrmService
using IntegrationPlugin.Org2CrmSdk; //Web proxy for Org2 CrmService
using Microsoft.Crm.Sdk;
using Microsoft.Crm.SdkTypeProxy;
//This sample code provide integration between 2 organizations hosted on the same CRM server
//Org1 and Org2
//Creating a contact in Org1 will fire the IntegrationPlugin and the same contact is created in Org2
//Updating a contact in Org1 will fire the IntegrationPlugin and the same contact is updated in Org2
//This is only for demostation purposes of course the sample code can be extended further to add further integration requirements
//Also other entities can implement the same plug-in concept
namespace IntegrationPlugin
{
public class IntegrationClass : IPlugin
{
public void Execute(IPluginExecutionContext context)
{
try
{
// Message: Create
// Primary Entity: contact
// Sate: Post Stage
// Mode: Asynchronous
// Pipeline: Parent
// Deployment: Server
if (context.InputParameters.Properties.Contains(ParameterName.Target)
&& context.InputParameters.Properties[ParameterName.Target] is Microsoft.Crm.Sdk.DynamicEntity
&& context.MessageName.Equals("Create"))
{
Microsoft.Crm.Sdk.DynamicEntity entity = null;
entity = (Microsoft.Crm.Sdk.DynamicEntity)
context.InputParameters.Properties[ParameterName.Target];
if (entity.Name == Microsoft.Crm.SdkTypeProxy.EntityName.contact.ToString())
{
if (context.OutputParameters.Properties.Contains(ParameterName.Id))
{
//Retrieving the contactId of the contact created in Org1
Guid org1ContactId =
new Guid(context.OutputParameters.Properties[ParameterName.Id].ToString());
//Creating a Token for Org1
Org1CrmSdk.CrmAuthenticationToken org1Token = new Org1CrmSdk.CrmAuthenticationToken();
org1Token.AuthenticationType = 0;
org1Token.OrganizationName = "Org1";
//Creating an instance of the CrmService for Org1
Org1CrmSdk.CrmService org1CrmService = new Org1CrmSdk.CrmService();
org1CrmService.CrmAuthenticationTokenValue = org1Token;
org1CrmService.Credentials = System.Net.CredentialCache.DefaultCredentials;
//Retriving the contact details from Org1
Org1CrmSdk.contact org1Contact = (Org1CrmSdk.contact)
org1CrmService.Retrieve(Org1CrmSdk.EntityName.contact.ToString(), org1ContactId, new Org1CrmSdk.AllColumns());
//Creating a Token for Org2
Org2CrmSdk.CrmAuthenticationToken org2Token = new Org2CrmSdk.CrmAuthenticationToken();
org2Token.AuthenticationType = 0;
org2Token.OrganizationName = "Org2";
//Creating an instance of the CrmService for Org2
Org2CrmSdk.CrmService org2CrmService = new Org2CrmSdk.CrmService();
org2CrmService.CrmAuthenticationTokenValue = org2Token;
org2CrmService.Credentials = System.Net.CredentialCache.DefaultCredentials;
//Setting the details for the contact in Org2 based on the details of Org1 contact
Org2CrmSdk.contact org2Contact = new Org2CrmSdk.contact();
org2Contact.firstname = org1Contact.firstname;
org2Contact.lastname = org1Contact.lastname;
//Creating the contact in Org2
Guid org2ConactId = org2CrmService.Create(org2Contact);
//Update contact in Org1 with the GUID of contact created in Org2
//Synch concept between the 2 contacts.
//We have a custom attribute so store the GUID
org1Contact.new_org2contactid = org2ConactId.ToString();
org1CrmService.Update(org1Contact);
}
}
}
// Message: Update
// Primary Entity: contact
// Sate: Post Stage
// Mode: Asynchronous
// Pipeline: Parent
// Deployment: Server
else if (context.InputParameters.Properties.Contains(ParameterName.Target)
&& context.InputParameters.Properties[ParameterName.Target] is Microsoft.Crm.Sdk.DynamicEntity
&& context.MessageName.Equals("Update"))
{
//Preupdate image of the firstname and lastname
Microsoft.Crm.Sdk.DynamicEntity preEntityImage = null;
preEntityImage = (Microsoft.Crm.Sdk.DynamicEntity)context.PreEntityImages.Properties["preEnityImageXml"];
string preFirstName = (string)preEntityImage.Properties["firstname"];
string preLastName = (string)preEntityImage.Properties["lastname"];
//Postupdate image of the firstname and lastname
Microsoft.Crm.Sdk.DynamicEntity postEntityImage = null;
postEntityImage = (Microsoft.Crm.Sdk.DynamicEntity)context.PostEntityImages.Properties["postEnityImageXml"];
string postFirstName = (string)postEntityImage.Properties["firstname"];
string postLastName = (string)postEntityImage.Properties["lastname"];
string org2ContactId = (string)postEntityImage.Properties["new_org2contactid"];
//Creating a Token for Org2
Org2CrmSdk.CrmAuthenticationToken org2Token = new Org2CrmSdk.CrmAuthenticationToken();
org2Token.AuthenticationType = 0;
org2Token.OrganizationName = "Org2";
//Creating an instance of the CrmService for Org2
Org2CrmSdk.CrmService org2CrmService = new Org2CrmSdk.CrmService();
org2CrmService.CrmAuthenticationTokenValue = org2Token;
org2CrmService.Credentials = System.Net.CredentialCache.DefaultCredentials;
//Setting the details for the contact in Org2
Org2CrmSdk.contact org2Contact = new Org2CrmSdk.contact();
org2Contact.contactid = new IntegrationPlugin.Org2CrmSdk.Key();
org2Contact.contactid.Value = new Guid(org2ContactId);
if (!postFirstName.Equals(preFirstName))
org2Contact.firstname = postFirstName;
if (!postLastName.Equals(preLastName))
org2Contact.lastname = postLastName;
//Update contact in Org2
org2CrmService.Update(org2Contact);
}
}
catch (System.Web.Services.Protocols.SoapException soapex)
{
throw new InvalidPluginExecutionException("An error occurred in IntegrationPlugin", soapex);
}
}
}
}
Hope this helps
Benjamin LECOQ (Code & Idea by Fouad Rachkidi)