Monday 10 June 2013

mscrm_facebook integration : Display Contact picture from Facebook in mscrm


http://blogs.msdn.com/b/crm/archive/2011/09/28/displaying-a-contact-s-facebook-picture-in-microsoft-dynamics-crm-2011.aspx

This Entire Integration is based on 0nly one URL and that is,
As you may Know, Each and Every User in Facebook has an Unique ID, Some change them into Alphabets called
“your Facebook URL” you can do this in Facebook Setting, and some leave as Numbers.
This User’s Facebook URL can be Generally fall in Users First and Last name, as follows
So, Most of the Organizations Collect First and Last name while creating a contact.
If you use
http://graph.facebook.com/userid/picture?type=large  //Large size picture
http://graph.facebook.com/userid/picture?type=small // Small size picture
http://graph.facebook.com/userid/picture?type=normal // Normal size Picture
the above url Displays users Profile Picture separately without any other user Information.
Now. we come to CRM,
Create a new CRM webresource javascript type and paste the following code.
function pp()
{
var profilepicture = Xrm.Page.getControl(“WebResource_profile”);
// ”WebResource_profile” Name of the other web resource which you place in the form to display the Picture. 
if (!profilepicture)
{
return;
}
//Get the first and lat name of the Contact
var fn = Xrm.Page.data.entity.attributes.get(“firstname”).getValue();
var ln = Xrm.Page.data.entity.attributes.get(“lastname”).getValue();
var fin = fn+ln; // Concatenate the First and last name without space.
var furl = ”http://graph.facebook.com/” + fn + “/picture?type=large”;
//Then set the finalized URL as the Source for the web-resource placed in the Form.
profilepicture.setSrc(furl);
}
The Above Code downloads the Large picture from contact’s Facebook account.
Now, Customize the Entity Form by adding a new webresource, with some common profile picture as default.
add the JavaScript webresource with any message you want, onload, OnSave or Onchange of the Form method.
you can also further redesign the code by inserting a new field for facebookID and pass the data directly in to URL, in this case the CRM user must know the contacts FacebookID to Display the Picture.
I do know that the resultant picture is not 100% accurate and not reliable.
But I hope this code can be further developed which might enable the CRM users to search the Contacts in facebook and Save the Desired Picture from the result.

Friday 7 June 2013

Twitter interface integration with mscrm 2011

In the sample below I will show you how to integrate Microsoft Dynamics CRM and Twitter on Account form. Below are the detailed steps:

* Save the below html code to an html file (Copy and paste into Notepad and then do a Save As)

<HTML><HEAD>
<META charset=utf-8></HEAD>
<BODY contentEditable=true>
<SCRIPT src="http://widgets.twimg.com/j/2/widget.js"></SCRIPT>

<SCRIPT>
var search = parent.document.forms[0].all.name.DataValue;
new TWTR.Widget({version: 2,type: 'profile',rpp: 10,interval: 2000,width: 630,height: 300,theme: { shell: { background: 'transparent', color: '#333' },tweets: { background: 'transparent', color: '#333', links: '#c10000' }
},
features: { scrollbar: false, loop: true, live: false, hashtags: true, timestamp: true, avatars: true, toptweets: true, behavior: 'default' }
}).render().setUser(search).start();
    </SCRIPT>

</BODY></HTML>

*Go to CRM, Settings, Customizations, Customize The System, Web Resources and Click the New button.
* Give the Web Resource a name and specify the type as a Web Page. Browse to the location where you saved your html file, select it and then press the save button.
* Customize the Account entity by going to Settings, Customizations, Customize the Solution, Entities, Leads, Form and add the Web Resource to the Main Form. Open up the Main Form, click the Insert tab and select the Web Resource that you just created.
* Save and Publish

You will now see a windows on the Account  form for the Twitter  interface. When you Can find top 10 Twits for this account 

Linkedin interface integration with mscrm 2011

In the sample below I will show you how to integrate Microsoft Dynamics CRM and LinkedIn. I found a post from Leon Tribe (an MVP for Microsoft Dynamics CRM) that explains it clearly for Microsoft Dynamics CRM 2011. Below are the detailed steps:

* Save the below html code to an html file (Copy and paste into Notepad and then do a Save As)

<html>
<head>
<script src="http://www.linkedin.com/companyInsider?script&useBorder=no" type="text/javascript"> </script>
</head>
<body>
<center>
<span id="getlinkedin"> </span>
</center>
<script type="text/javascript">
var parentForm = parent.frames.document.crmForm;
new LinkedIn.CompanyInsiderBox("getlinkedin",parentForm.all.companyname.DataValue);
</script>
</body>


*Go to CRM, Settings, Customizations, Customize The System, Web Resources and Click the New button.
* Give the Web Resource a name and specify the type as a Web Page. Browse to the location where you saved your html file, select it and then press the save button.
* Customize the lead entity by going to Settings, Customizations, Customize the Solution, Entities, Leads, Form and add the Web Resource to the Main Form. Open up the Main Form, click the Insert tab and select the Web Resource that you just created.
* Save and Publish

You will now see a windows on the Lead form for the LinkedIn interface. When you change the Lead record’s Company, the LinkedIn window is adjusted to show you who you know that works there and a link to show everyone else that works there that you may have access to.

Friday 31 May 2013

Publishing CRM entities in SharePoint

Thought Process:
1) CRM 2011 provides SDK and I can always develop custom solutions. If I choose to refer to “Walkthrough: Build a Web Application That Connects to Microsoft Dynamics CRM 2011 Using Developer Extensions” I can easily display CRM 2011 entity information in a Web Application.
2) That means I can easily transform those custom solutions (like a Web Application) into a SharePoint 2010 web part, and bingo! We are all set!
Catch:
1) CRM 2011 is based on .Net framework 4.0 and SP 2010 is on .Net 3.5. So if you try to implement the step 2 you can’t even build your SharePoint Web Part forget about deploying it.
Resolution [Important Steps]:
image_thumb25
1) Publish an intermediary WCF service with relevant methods to expose information from CRM 2011.
2) Create a SharePoint Web Part and make appropriate calls to the WCF service and then transform the result set as per your needs for the end user.

The Steps in detail:

1) We need to create and publish a WCF service to call in CRM 2011. This service can have multiple facets based on your needs; may be you intend to perform add/edit/delete apart from just “display” so create the WCF methods judiciously. For now I will stick to the display part.
IMP: The code blocks below doesn’t confirm to the coding best practices but does work, and I am sure you guys can transform it accordingly. I have ripped the pieces from from all over the web
a) Generate Early Bound Types:
Run the CrmSvcUtil.exe tool, with the Microsoft.Xrm.Client.CodeGeneration extension, to generate your entity classes and service contexts.
The following example command creates a file called “Xrm.cs” that points at an instance of Microsoft Dynamics CRM. Note that the Microsoft.Xrm.Client.CodeGeneration.dll file must be in the same directory as the CrmSvcUtil.exe file, or in the system GAC, when you run this command.
crmsvcutil.exe /codeCustomization:"Microsoft.Xrm.Client.CodeGeneration.CodeCustomization, Microsoft.Xrm.Client.CodeGeneration"
/out:Xrm\Xrm.cs /url:
http://dpm2012/fabrikam/XRMServices/2011/Organization.svc /domain:CONTOSO /username:spfarm
/password:Welcome@123 /namespace:Xrm /serviceContextName:XrmServiceContext

b) Use Visual Studio 2010 to create a WCF Service Application (ensure .NET Framework 4).
Img1_thumb3
c) Right-click the project in Visual Studio, click Add, and then click Existing Item. Select the “xrm.cs” file that you created when you generated the early bound types.
d) Right-click the project in Visual Studio, click Add, add a new class to the project. The Add New Item dialog box appears. Rename the class as Entities.cs. Similarly add one more class and name it as Views.cs
e) Add couple of properties in both these classes (please name it appropriately)
public string MyProperty { get; set; }
public string MyProperty1 { get; set; }
 
f) Add the references as shown below (for the CRM dll the Source will be SDK\bin, don’t search for C:\Shariq Smile)
 
image_thumb7
g) Now your Solution should look more like below (few more references might have been inadvertently added)
 
image_thumb3
 
h) Right-click the project in Visual Studio and add the Service Reference for the Organization.svc
 
 
i) Open the interface IService1.cs and replace the ServiceContract with the code below:
 
[ServiceContract]
    public interface IService1
    {
 
        [OperationContract]
        string GetMessage();
 
        [OperationContract]
        List<Entities> GetEntityData();
 
 
        [OperationContract]
        List<Views> GetViewData(int SelectedEntity);
 
        [OperationContract]
        DataSet GetCompleteData(string _SavedQueryId);
 
    }
j) Now we need to implement the Service1.svc, copy the below code (make appropriate changes for your OrganizationUri i.e. Organization.svc )
    public class Service1 : IService1
    {
        public List<Entities> GetEntityData()
        {
        ClientCredentials Credentials = new ClientCredentials();

        Credentials.Windows.ClientCredential = CredentialCache.DefaultNetworkCredentials;

        //This URL needs to be updated to match the servername and Organization for the environment. 

        Uri OrganizationUri = new Uri("http://DPM2012/TailspinToysDB/XRMServices/2011/Organization.svc");
        List<Entities> EntityList = new List<Entities>();
        Uri HomeRealmUri = null;
        using (OrganizationServiceProxy serviceProxy = new OrganizationServiceProxy(OrganizationUri, HomeRealmUri, 
        Credentials, null))
        {

            Microsoft.Xrm.Sdk.IOrganizationService service = serviceProxy as Microsoft.Xrm.Sdk.IOrganizationService;

            RetrieveAllEntitiesRequest request = new RetrieveAllEntitiesRequest()
            {
                EntityFilters = EntityFilters.Attributes,
                RetrieveAsIfPublished = true
            };

            // Retrieve the MetaData.
            RetrieveAllEntitiesResponse response = (RetrieveAllEntitiesResponse)serviceProxy.Execute(request);

            foreach (EntityMetadata currentEntity in response.EntityMetadata)
            {
                if (currentEntity.IsCustomizable.Value == true)
                {
                    foreach (AttributeMetadata currentAttribute in currentEntity.Attributes)
                    {

                        Entities e = new Entities();
                        e.MyProperty = currentEntity.LogicalName;
                        e.MyProperty1 = currentEntity.ObjectTypeCode.Value.ToString();

                        if (EntityList.Where(en => en.MyProperty.Equals(e.MyProperty) && 
                        en.MyProperty1.Equals(e.MyProperty1)).Count() == 0)
                        {
                            EntityList.Add(e);
                        }
                    }
                }
            }

        }
        return EntityList;
        }

        public List<Views> GetViewData(int paramSelectedEntity)
        {
        ClientCredentials Credentials = new ClientCredentials();

        Credentials.Windows.ClientCredential = CredentialCache.DefaultNetworkCredentials;

        //This URL needs to be updated to match the servername and Organization for the environment. 

        Uri OrganizationUri = new Uri("http://dpm2012/TailspinToysDB/XRMServices/2011/Organization.svc");

        Uri HomeRealmUri = null;
        List<Views> ViewsList = new List<Views>();

        using (OrganizationServiceProxy serviceProxy = new OrganizationServiceProxy(OrganizationUri, HomeRealmUri, 
        Credentials, null))
        {
            serviceProxy.EnableProxyTypes();

            Microsoft.Xrm.Sdk.IOrganizationService service = (Microsoft.Xrm.Sdk.IOrganizationService)serviceProxy;

            // Retrieve Views
            QueryExpression mySavedQuery = new QueryExpression
            {
                ColumnSet = new ColumnSet("savedqueryid", "name", "querytype", "isdefault", "returnedtypecode", 
                "isquickfindquery"),
                EntityName = SavedQuery.EntityLogicalName,
                Criteria = new FilterExpression
                {
                    Conditions =
        {
                
            new ConditionExpression
            {
                AttributeName = "returnedtypecode",
                Operator = ConditionOperator.Equal,
                Values = {paramSelectedEntity}
            }
        }
                }
            };
            RetrieveMultipleRequest retrieveSavedQueriesRequest = new RetrieveMultipleRequest { Query = mySavedQuery };

            RetrieveMultipleResponse retrieveSavedQueriesResponse = 
            (RetrieveMultipleResponse)serviceProxy.Execute(retrieveSavedQueriesRequest);

            DataCollection<Entity> savedQueries = retrieveSavedQueriesResponse.EntityCollection.Entities;
                
            foreach (Entity ent in savedQueries)
            {
                SavedQuery rsq = (SavedQuery)ent;
                if (rsq.IsDefault == true)
                {
                    Views e = new Views();
                    e.MyProperty = rsq.Name.ToString();
                    e.MyProperty1 = rsq.Id.ToString();
                    ViewsList.Add(e);
                }
            }
        }

        return ViewsList;           

        }

        public DataTable convertEntityCollectionToDataTable(EntityCollection BEC)
        {
            DataTable dt = new DataTable();
            int total = BEC.Entities.Count;
            for (int i = 0; i < total; i++)
            {
                DataRow row = dt.NewRow();
                Entity myEntity = (Entity)BEC.Entities[i];
                var keys = myEntity.Attributes.Keys;
                foreach (var item in keys)
                {
                    string columnName = item;
                    string value = getValuefromAttribute(myEntity.Attributes[item]);
                    if (dt.Columns.IndexOf(columnName) == -1)
                    {
                        dt.Columns.Add(item, Type.GetType("System.String"));
                    }
                    row[columnName] = value;
                }
                dt.Rows.Add(row);
            }
            return dt;
        }

        private string getValuefromAttribute(object p)
        {
            if (p.ToString() == "Microsoft.Xrm.Sdk.EntityReference")
            {
                return ((EntityReference)p).Name;
            }
            if (p.ToString() == "Microsoft.Xrm.Sdk.OptionSetValue")
            {
                return ((OptionSetValue)p).Value.ToString();
            }
            if (p.ToString() == "Microsoft.Xrm.Sdk.Money")
            {
                return ((Money)p).Value.ToString();
            }
            if (p.ToString() == "Microsoft.Xrm.Sdk.AliasedValue")
            {
                return ((Microsoft.Xrm.Sdk.AliasedValue)p).Value.ToString();
            }
            else
            {
                return p.ToString();
            }
        }

        public DataSet GetCompleteData(string _strSavedQueryId)
        {
        DataSet ds = new DataSet();

        Guid _SavedQueryId = new Guid(_strSavedQueryId);

        ClientCredentials Credentials = new ClientCredentials();

        Credentials.Windows.ClientCredential = CredentialCache.DefaultNetworkCredentials;

        //This URL needs to be updated to match the servername and Organization for the environment. 

        Uri OrganizationUri = new Uri("http://dpm2012/TailspinToysDB/XRMServices/2011/Organization.svc");

        Uri HomeRealmUri = null;


        using (OrganizationServiceProxy serviceProxy = new OrganizationServiceProxy(OrganizationUri, HomeRealmUri, 
        Credentials, null))
        {
            serviceProxy.EnableProxyTypes();

            Microsoft.Xrm.Sdk.IOrganizationService service = (Microsoft.Xrm.Sdk.IOrganizationService)serviceProxy;

            ColumnSet cSet = new ColumnSet("savedqueryid", "fetchxml");

            SavedQuery rsq = (SavedQuery)service.Retrieve(SavedQuery.EntityLogicalName, _SavedQueryId, cSet);

            RetrieveMultipleRequest req = new RetrieveMultipleRequest();
            FetchExpression fetch = new FetchExpression(rsq.FetchXml);
            req.Query = fetch;
            RetrieveMultipleResponse resp = (RetrieveMultipleResponse)service.Execute(req);
            DataTable ObjDT = convertEntityCollectionToDataTable(resp.EntityCollection);
            ds.Tables.Add(ObjDT);

        }
        return ds;
        }
    }
k) Now the CRM WCF Service is ready and we can publish it at IIS. The steps to publish any WCF service can be found easily over web. Starters can refer to http://debugmode.net/2010/09/07/walkthrough-on-creating-wcf-4-0-service-and-hosting-in-iis-7-5/. Skip the Service creation steps from this blog just refer to Publishing steps and also ensure to test it locally using a local Client.
If you have reached here successfully, the battle is almost won Smile
2) Now we just need to create a simple SharePoint 2010 Visual Web Part to consume this service as per need.
a) Use Visual Studio 2010 to create a new Visual Web Part project.
b) Right Click the project and Add the Service Reference for our CRM Service published in Step 1.
image_thumb13
c) Add the following code to VisualWebPart1UserControl.ascx :
<asp:DropDownList ID="ddlEntityList" runat="server" AutoPostBack="True" 
OnSelectedIndexChanged="ddlEntityList_SelectedIndexChanged"></asp:DropDownList>
<asp:DropDownList ID="ddlViewsList" runat="server" AutoPostBack="True" 
OnSelectedIndexChanged="ddlViewsList_SelectedIndexChanged"></asp:DropDownList>
<asp:GridView ID="gdEntity" ViewStateMode="Disabled" runat="server" />
d) Add the following code to VisualWebPart1UserControl.ascx.cs:
       protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                Service1Client proxy = new Service1Client();

                ddlEntityList.DataSource = proxy.GetEntityData();
                ddlEntityList.DataTextField = "MyProperty";
                ddlEntityList.DataValueField = "MyProperty1";
                ddlEntityList.DataBind();
            }
        }

        protected void ddlEntityList_SelectedIndexChanged(object sender, EventArgs e)
        {
            ddlViewsList.Items.Clear();
            int index = Convert.ToInt32(ddlEntityList.SelectedValue);
            Service1Client proxy = new Service1Client();

            ddlViewsList.DataSource = proxy.GetViewData(index);
            ddlViewsList.DataTextField = "MyProperty";
            ddlViewsList.DataValueField = "MyProperty1";
            ddlViewsList.DataBind();


        }

        protected void ddlViewsList_SelectedIndexChanged(object sender, EventArgs e)
        {            
            string str = ddlViewsList.SelectedValue;
            Service1Client proxy = new Service1Client();
            gdEntity.DataSource = proxy.GetCompleteData(str);
            gdEntity.DataBind();
        }
e) Right click the Project and deploy to the SharePoint Site.
f) Go to the SharePoint 2010 Site and add the Visual Web Part to a page where you want to display the Web Part. And ‘Bingo’. You should see the something like this:
image_thumb29
This SharePoint Web Part code above is pretty basic in nature for now, but I am sure you can improve upon this sample code – you know, things like:
  • When not to show the ‘View’ Drop Down when the Entity is refreshed.
  • Or when there is no result set we must show appropriate result rather than the Yellow screen of death.
  • Or you want to filter the Grid by removing certain columns from the dataset or renaming the column Header etc.
I leave all it all up to you, as the sample is attached. Use it/Break it and Enjoy !!!

Food for thought

1) In principle this should work for MOSS 2007, for those who are still on it Smile
2) In SharePoint 2013, we can merge the WCF code implementation within the SharePoint web part itself.
You can download the complete sample from here.

Code References

Hope this helps a needy soul!

Share point -MSCRM integration

Part 1 CRM 2011
Within CRM go to Settings \ Document Management
Click on Document Management under Settings Tab from the left Navigation Page
Click on List Components and then Download the list component file from Microsoft Download Center CRM2011-SharePointList-ENU-amd64.exe and extract them
Three files are extracted, AllowHtcExtn.ps1, crmlistcomponent.wsp and mscrmsharepointeula.txt.
Only the crmlistcomponent.wsp will be used in the integration.
Part 2 SharePoint
Open your team site
or SharePoint 2013
Click on Site Action from the Top Link Bar and from the drop down select Site Settings NOTE: these steps may vary slightly for SharePoint online, the final link is the destination but the navigation can be different.
or SharePoint 2013
Click on Solutions under Galleries
or SharePoint 2013
Click on Solution from the top link bar and then click Upload Solution
Browse to the saved file crmlistcomponent.wsp and upload
Activate the wsp file just uploaded. Note: At times this can fail, keep trying and it should activate.
Part 3 back to CRM 2011
Under the Document Management Click on Document Management Settings. Select the entities you want to integrate with SharePoint You will need to specify the URL for your SharePoint Team Site. The url can be a sub site that you have created into you main team site.
Now click next and then Select the base entity
Click on next and it will give you a popup for creating libraries into Sharepoint Online. Just Click OK
CRM will create the folders and give the status as Succeed
Click on finish
Validate everything is working, open an account and click on Documents from the left Navigation Pane, it will give you a popup regarding creating folders in SharePoint, click OK. You can now attach any document or create any document from CRM 2011 online.