Sunday, September 18, 2011

How to create an email activity using REST Endpoints in CRM2011


How tough it can be to create an activity using code? It sounds very easy but there are few issues, if you are using REST Endpoints.

REST Endpoints do not support all the CRM data types. One of those data type is PartyList. PartyList is very important to create most of the activity like emails, appointments, phone calls etc.

To set the value of the PartyList field you need an array of PartyLists as you can have more than value for those fields. For e.g you can have more than one recipient for an email or you can have more than resource for an appointment.

As I mentioned earlier, REST Endpoints do not support PartyList, So its is impossible to assign value to these fields. If you look at DataSet returned by the Rest Endpoints, It looks like they are treating PartyList fields like string fields.

image

These values does not even return the guid or name of the PartyList entity. if you look at sender field in the screen shot above, it does not have guid or the name of the system user who sent this email.
I tried the same using following code:

email.Sender="crm2011@emailops.com.au";
var partlistcollection = new Array(); //tried to create an array of PartyLists

partlistcollection[0] = {Id: "8384E684-7686-E011-8AF0-00155D32042E",LogicalName: "contact",Name: "Amreek Singh"};
email.ToRecipients=JSON.stringify(partlistcollection);

But it did not work, if you pass a string value to the PartyList fields, You won’t get any error message but you won’t see any value in those fields on a created entity. 

Now here is the solution. You need to create an activity (in this case it’s  an email) first and then create a PartyList entity and link it back to the created activity.

function CreateEmail() {
alert("CreateEmail Begin");

var email = new Object();
email.Subject = "Sample Email Using REST";
SDK.JScriptRESTDataOperations.Create(email, "Email", EmailCallBack, function (error) { alert(error.message); });
}

// Email Call Back function
function EmailCallBack(result)
{
var activityParty=new Object();
// Set the "party" of the ActivityParty // EntityReference of an entity this activityparty relatated to. 
activityParty.PartyId = {
  Id: "8384E684-7686-E011-8AF0-00155D32042E",//replace this with the contactid from your system.
  LogicalName: "contact"
};
// Set the "activity" of the ActivityParty
// EntityReference.
activityParty.ActivityId = {
  Id: result.ActivityId, 
  LogicalName: "email"
};
// Set the participation type (what role the party has on the activity).
activityParty.ParticipationTypeMask = { Value: 2 }; // 2 mean ToRecipients
SDK.JScriptRESTDataOperations.Create(activityParty, "ActivityParty",ActivityPartyCallBack , function (error) { alert(error.message); });
}

function ActivityPartyCallBack(reuslt)
{
alert("Process Completed");
}

activityParty.ParticipationTypeMask = { Value: 2 }; is very important as it will specify if this PartList is sender/recipient/resource etc  of the activity.

Here is the link to complete list of activityParty.ParticipationTypeMask click here.
For this sample, I have used the generic REST CRUD data operations library created by Jim Daly.
Add references to following Java Script  web resources to try the solution.
  • SDK.JScriptRESTDataOperations
  • JSON2
Here is the link to unmanaged solution RESTEmailSolution_1_0
  • I hope this helps.

9 comments:

  1. Thanx! Works great!
    Too bad Microsoft didn't make it available in one shot.

    ReplyDelete
  2. Hi,
    If i create 2 multiple activity parties for "Appointment" the 2nd one overriding first one.
    Any help really appriciated.

    My code here (I am calling below code twice to create 2 activity parties)

    var activityParty = new Object();
    activityParty.PartyId = {
    Id: userGuid,
    LogicalName: "systemuser"
    };

    activityParty.ActivityId = {
    Id: activityId,
    LogicalName: "appointment"
    };
    activityParty.ParticipationTypeMask = { Value: 5 }; //5 = Required Attendees

    createRecord(activityParty, "ActivityPartySet", "createAPCompleted", null);


    Thanks,
    Jyothi

    ReplyDelete
    Replies
    1. Use email.email_activity_parties property of the email entity. if you do a createrecord(email,"EmailPartySet") on an email where you have set the email_activity_parties property, the create will create both the email and the parties together.

      Simple example as follows ...

      This took me ages to work out. By the way Jaime's XRMServiceToolkit is very cool, I am using it. If you want to do this via REST, you need to use the email.email_activity_parties property, which accepts a collection of activity parties. Something like this will work. Obviously not the cleanest code to do this but you should get the idea from this how the email_activity_parties property works.


      var email = new Object();

      email.Subject = "my email";
      email.Description = "my email description";

      var activityParties = new Array();

      var partyObj0 = new Object();
      partyObj0.PartyId = { Id: userid, LogicalName: "systemuser" };
      partyObj0.ParticipationTypeMask = { Value: 1 };
      activityParties[0] = partyObj0;

      var partyObj1 = new Object();
      partyObj1.PartyId = { Id: contactid1, LogicalName: "contact" };
      partyObj1.ParticipationTypeMask = { Value: 2 };
      activityParties[1] = partyObj1;

      var partyObj2 = new Object();
      partyObj2.PartyId = { Id: contactid2, LogicalName: "contact" };
      partyObj2.ParticipationTypeMask = { Value: 2 };
      activityParties[2] = partyObj2;

      //then pass email into createrecord function
      createRecord(email, "EmailSet", "createEmailCompleted", null);







      Delete
  3. Microsoft Dynamics CRM training will help you manage and prioritize your business goals, customize.we teach MS Dynamics CRM training and class available at Hyderabad.

    ReplyDelete
  4. Thanks alot for your article, this helped a lot understanding the workflow of creating an email activity and linking the contact and systemuser entity back to the email activity entity.

    I only have one problem left: Is there a possibility to change the email activity status from "draft" to "completed"? When I create an email from the web-interface of Dynamics CRM 2011, I'm able to send this email via configured email router which uses a SMTP server.

    Now the idea is want to create an email via REST which is sent immediately after creation and association with the systemuser and contact entities. I tried to set StateCode and StatusCode via HTTP MERGE to the email entity, but unfortunately the CRM returns a formal correct HTTP 204, but the status remains "draft".

    Thanks in advance,
    Ryad

    ReplyDelete
    Replies
    1. Rest is sub set of SOAP services. It does not have method to send the email out. REST is just to create and update etc. You may need to use soap service or create a workflow. On create or update send the email out automatically.

      I hope this helps.

      Delete
    2. Thanks Amreek Singh for your answer. As I searched for more information on this topic, I already expected such an issue. I will try to extend my project with a SOAP interface to call Execute-Methods on the CRM side.

      The workflow solution also seems to be interesting, I'm going to check this out.

      Thanks!

      Delete