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:

clip_image002

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….

clip_image002[5]

Contact created successfully in Org1…

clip_image002[7]

Same contact created in Org2 by the integration plugin.

clip_image002[9]

Now updating contact in Org1…

clip_image002[11]

Same contact in Org2 updated by the plugin.

clip_image002[13]

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)