Home > CRM 2011, Plug-Ins > Sending an Email using CRM 2011 Plug In

Sending an Email using CRM 2011 Plug In

Hi,

In one of my recent requirements, I had to send an Email using Plug-in (Late Binding). Below is the code snippet.

private void SendEmail(IOrganizationService service, Guid recieverUserId, Guid senderUserId, Guid regardingObjectId, string emailBody, string emailSubject)

{

Entity email = new Entity();
email.LogicalName = “email”;

//Set regarding object property (i.e. The entity record, which u want this email associated with)

EntityReference regardingObject = new EntityReference(“{entity_name}”, regardingObjectId);
email.Attributes.Add(“regardingobjectid”,regardingObject);

//Defining Activity Parties (starts)

EntityReference from = new EntityReference(“systemuser”, senderUserId);

EntityReference to = new EntityReference(“systemuser”,recieverUserId);

//Derive from party

Entity fromParty = new Entity(“activityparty”);
fromParty.Attributes.Add(“partyid”,from);

//Derive to party

Entity toParty = new Entity(“activityparty”);
toParty.Attributes.Add(“partyid”, to);

EntityCollection collFromParty = new EntityCollection();
collFromParty.EntityName = “systemuser”;
collFromParty.Entities.Add(fromParty);

EntityCollection collToParty = new EntityCollection();
collToParty.EntityName = “systemuser”;
collToParty.Entities.Add(toParty);

email.Attributes.Add(“from”,collFromParty);
email.Attributes.Add(“to”, collToParty);

//Defining Activity Parties (ends)

//Set subject & body properties
email.Attributes.Add(“subject”,emailSubject);
email.Attributes.Add(“description”, emailBody);

//Create email activity

Guid emailID = service.Create(email);

//Sending email

SendEmailRequest reqSendEmail = new SendEmailRequest();
reqSendEmail.EmailId = emailID;//ID of created mail
reqSendEmail.TrackingToken = “”;
reqSendEmail.IssueSend = true;

SendEmailResponse res = (SendEmailResponse)service.Execute(reqSendEmail);

}

This is tested code and you can use as it is. Hope it Helps 🙂

  1. bigdiddy
    November 29, 2011 at 7:20 PM

    hey, looks good, but i have an error by calling the service.create(email).
    recieverUserId = systemuserID1
    senderUserId = systemuserID2
    regardingObjectId = systemuserID1.
    im getting an exception because the parent of the email entty is invalid, why ???
    By creating emails manually in the crm there are no problem by regarding the email
    to an user.
    Have you ever get this problem?

  2. November 30, 2011 at 1:43 PM

    Try to run the code without setting the “regardingObject” property.
    If it works, Please double check the entity name of parent (i.e., regarding object) you provided.

    For further investigation could you please provide me the exception details.

  3. Vidhyut
    February 29, 2012 at 2:33 PM

    Hi, I tried this code, it executed without any error. But didnt send any email. How?

    • February 29, 2012 at 3:34 PM

      Hi,
      Go to the record’s “Activities” section and check whether the email activity has created or not.
      If yes check the email id’s are valid for recepients.
      And verify the recepient has subscribed for “Do not send mail” and finally Email router.

  4. SDev
    September 4, 2013 at 4:52 PM

    I am having the same issue faced by Vidhyut. (“Hi, I tried this code, it executed without any error. But didnt send any email. How?”)

    I checked, activities are created and Email is already created but not sent.

    Configured E-mail Access Configuration set to Email Router. But not working. How to enable a user to send email. Please give me preferred settings I’m using CRM 2011 Online.

    • September 5, 2013 at 4:08 PM

      Whom are the recipients in your email?
      If recipient has a ‘Contact’, check if the option “Do not send email” is selected in “Contact –> Contact Methods” section.
      User in CRM does not have option to enable\disable sending emails.

  5. Yasin
    January 17, 2014 at 9:45 PM

    What should be the message name and primary entity name to register this plugin?

  6. Ganesh
    September 1, 2014 at 8:32 PM

    I have created a plugin for sending an email but I would like to call this plugin from WCF Service upon a record creation. I am really stuck on how to consume WCF service from plugin to trigger this email activity. Any help is really appreciated.

  7. Ganesh
    September 2, 2014 at 4:02 PM

    Thanks for your prompt response Rajeev. i read this article and followed the same way but I am getting an exception “Microsoft.Crm.Extensibility.InprocessServiceProxy’ cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. If the type is a collection, consider marking it with the CollectionDataContractAttribute. See the Microsoft .NET Framework documentation for other supported types.”

    The code which you have shown above is in Plugin..I just written the same code in my WCF Service..But I am unable to call the WCF service.

    • September 2, 2014 at 6:31 PM

      Hi Ganesh,
      is your WCF service expecting or returning Class object; If yes, make sure to keep [DataContract] tag for Class and [DataMember] for each Class attribute.

      • Ganesh
        September 2, 2014 at 8:46 PM

        No. My service method is a void Method as i mentioned in my previous post it.From my plugin my service should be invoked when i create a record in CRM. Let me share my requirement if you dont mind so that it will be very easy for you to understand. Actually am very new to this CRM..so I am not sure how this works from plugin to CRM.

  8. Ganesh
    September 3, 2014 at 12:55 AM

    I tried running this code as it is in my plugin. But it gives me error “The e-mail must have at least one recipient before it can be sent”. I am not sure is there any thing else that I need to change in the above code.

    • September 3, 2014 at 10:39 AM

      Hi Ganesh,
      Make sure in below statement from code, “recieverUserId” is a valid User GUID in your system.
      EntityReference to = new EntityReference(“systemuser”,recieverUserId);

      Also the User must have “Primary Email” field populated.

      • Ganesh
        September 3, 2014 at 2:41 PM

        In my vehicle entity(vt_vehicle) and I have these fields
        1. vt_name
        2. vt_make
        3. vt_model
        4. vt_year
        5. vt_vehicleowner
        6. emailaddress——this one is autogenerated when i check email option while creating entity.

        Now once i create this record and save and email should be created to the vt_vehicleowner. here is my code

        public class PostVehicleCreate: Plugin
        {
        public Guid recieverUserId;
        public Guid senderUserId;
        public Guid regardingObjectId;
        public string emailBody = string.Empty;
        public string emailSubject = string.Empty;
        public PostVehicleCreate()
        : base(typeof(PostVehicleCreate))
        {
        base.RegisteredEvents.Add(new Tuple<int, string, string, Action>(40, “Create”, “vt_vehicle”, new Action(ExecutePostVehicleCreate)));

        }

        protected void ExecutePostVehicleCreate(LocalPluginContext localContext)
        {
        IPluginExecutionContext context = (IPluginExecutionContext)localContext.PluginExecutionContext;

        if (context.InputParameters.Contains(“Target”) && (context.InputParameters[“Target”] is Entity))
        {
        IOrganizationService service = (IOrganizationService)localContext.OrganizationService;
        Entity entity = (Entity)context.InputParameters[“Target”];
        SendEmail(service, recieverUserId, senderUserId, regardingObjectId, emailBody, emailSubject);

        }

        }

        private void SendEmail(IOrganizationService service, Guid recieverUserId, Guid senderUserId, Guid regardingObjectId, string emailBody, string emailSubject)
        {

        try
        {
        Entity email=new Entity();
        email.LogicalName = “email”;

        //set the regarding object property
        //EntityReference regardingObject = new EntityReference(“vt_vehicle”, regardingObjectId);
        //email.Attributes.Add(“regardingobjectid”, regardingObject);

        //Defining From Attributes
        EntityReference from = new EntityReference(“systemuser”, senderUserId);

        EntityReference to = new EntityReference(“vt_vehicleowner”, recieverUserId);

        Entity fromParty = new Entity(“activityparty”);
        fromParty.Attributes.Add(“partyid”, from);

        Entity toParty = new Entity(“activityparty”);
        toParty.Attributes.Add(“partyid”, to);

        EntityCollection ec_from=new EntityCollection();
        ec_from.EntityName = “systemuser”;
        ec_from.Entities.Add(fromParty);

        EntityCollection ec_to = new EntityCollection();
        ec_to.EntityName = “vt_vehicle”;
        ec_to.Entities.Add(toParty);

        email.Attributes.Add(“from”, fromParty);
        email.Attributes.Add(“to”, toParty);

        //set subject and body properties
        email.Attributes.Add(“subject”, emailSubject);
        email.Attributes.Add(“description”, emailBody);

        //create email activity

        Guid emailId = service.Create(email);

        //sending email

        SendEmailRequest emailRequest=new SendEmailRequest();
        emailRequest.EmailId = emailId;
        emailRequest.TrackingToken = “”;
        emailRequest.IssueSend = true;

        SendEmailResponse res = (SendEmailResponse) service.Execute(emailRequest);

        }
        catch (NullReferenceException ex)
        {
        throw new NullReferenceException(“Processor Usage” + ex.Message);
        }
        }
        }

      • September 3, 2014 at 3:21 PM

        Hi Ganesh,
        I see you just declared “senderUserId” variable but not providing any value.
        Set “senderUserId” variable with valid User GUID.

  9. Ganesh
    September 3, 2014 at 2:50 PM

    After i run this code i get this error “The e-mail must have at least one recipient before it can be sent”

  10. Ganesh
    September 3, 2014 at 3:32 PM

    But GUID is something autogenerated. How will i set that..is it something like this GUID senderUserId = new GUID; or can you help me how should i set that?

    • September 6, 2014 at 12:44 PM

      In CRM, every entity has a PrimaryField of type UniqueIdentifier (i.e.,GUID). So when you create Users, every User gets a ‘SystemUserId’ field auto generated.
      You can read the ‘SystemUserId’ GUID field and set as ‘To’ Recepient.

  11. Ganesh
    September 11, 2014 at 12:13 AM

    I have this in my service1.svc.cs

    void IService1.CreateEmailOnVehicleEntity(EmailActivity emailActivity)
    {

    try
    {

    CreateRequest reqCreate = new CreateRequest();
    Entity emailCreate = new Entity(“email”);
    emailCreate[“subject”] = “test subject”;
    emailCreate[“description”] = ” test description”;

    //emailCreate[“ownerid”] = new EntityReference(“systemuser”, new Guid(OwnerId));
    Entity entity = new Entity(“vt_vehicle”);

    Entity ap = new Entity();
    ap = new Entity(“activityparty”);

    Guid ownerGuid = Guid.Empty;
    ownerGuid = entity.GetAttributeValue(“vt_owner”).Id;
    Entity contact = emailActivity.service.Retrieve(“contact”, ownerGuid, new ColumnSet(new string[] { “fullname” }));
    ap[“addressused”] = contact.Attributes[“fullname”];
    Entity[] aryTo = { ap };
    emailCreate[“to”] = aryTo;

    //assigning a systemuser entity to the From attribute for the email acitivity
    Entity ap2 = new Entity();
    ap2 = new Entity(“activityparty”);

    ap2[“partyid”] = new EntityReference(“systemuser”, emailActivity.context.UserId);
    Entity[] aryFrom = { ap2 };
    emailCreate[“from”] = aryFrom;

    // assign a regarding object
    // Guid regardingGuid = entity.Id;
    //EntityReference regardingObject=new EntityReference(“vt_vehicle”,regardingGuid);
    emailCreate[“regardingobjectid”] = entity.ToEntityReference(); //new EntityReference(“vt_vehicle”, regardingGuid);

    reqCreate.Target = emailCreate;
    CreateResponse resp = (CreateResponse)emailActivity.service.Execute(reqCreate);

    }
    catch (NullReferenceException ex)
    {
    throw new NullReferenceException(“Processor Usage” + ex.Message);
    }
    }

    And this one in my Plugin

    protected void ExecutePostVehicleCreate(LocalPluginContext localContext)
    {
    IPluginExecutionContext context = (IPluginExecutionContext)localContext.PluginExecutionContext;

    if (context.InputParameters.Contains(“Target”) && (context.InputParameters[“Target”] is Entity))
    {
    IOrganizationService service = (IOrganizationService)localContext.OrganizationService;
    Entity entity = (Entity)context.InputParameters[“Target”];

    try
    {
    BasicHttpBinding myBinding = new BasicHttpBinding();
    myBinding.Name = “BasicHttpBinding_IService1”;
    myBinding.Security.Mode = BasicHttpSecurityMode.None;
    myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
    myBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
    myBinding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;

    EndpointAddress endPointAddress = new EndpointAddress(“http://localhost:4353/Service1.svc”);
    ChannelFactory factory = new ChannelFactory(myBinding, endPointAddress);
    IService1 channel = factory.CreateChannel();
    channel.CreateEmailOnVehicleEntity(service, context);
    factory.Close();
    }
    catch (NullReferenceException ex)
    {

    throw new NullReferenceException(“Processor Usage” + ex.Message);
    }

    }
    }

    Now my plugin works fine without error. But when i call the service from my plugin. I get this error.

    Unhandled Exception: System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: Type ‘Microsoft.Crm.Extensibility.InprocessServiceProxy’ cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. If the type is a collection, consider marking it with the CollectionDataContractAttribute. See the Microsoft .NET Framework documentation for other supported types.Detail:

    -2147220891

    OperationStatus
    0

    SubErrorCode
    -2146233088

    Type ‘Microsoft.Crm.Extensibility.InprocessServiceProxy’ cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. If the type is a collection, consider marking it with the CollectionDataContractAttribute. See the Microsoft .NET Framework documentation for other supported types.
    2014-09-10T18:42:10.6048979Z

    [CrmVSSolution_Email.Plugins: CrmVSSolution_Email.Plugins.PostVehicleCreate]
    [85ad8342-9c32-e411-9455-0800271b3708: PostVehicleCreate]
    Entered CrmVSSolution_Email.Plugins.PostVehicleCreate.Execute(), Correlation Id: 08727641-8866-4746-87ea-79bc23db6c93, Initiating User: afcad25d-bf2c-e411-a5f5-0800271b3708
    CrmVSSolution_Email.Plugins.PostVehicleCreate is firing for Entity: vt_vehicle, Message: Create, Correlation Id: 08727641-8866-4746-87ea-79bc23db6c93, Initiating User: afcad25d-bf2c-e411-a5f5-0800271b3708
    Exiting CrmVSSolution_Email.Plugins.PostVehicleCreate.Execute(), Correlation Id: 08727641-8866-4746-87ea-79bc23db6c93, Initiating User: afcad25d-bf2c-e411-a5f5-0800271b3708

  12. Ganesh
    September 15, 2014 at 11:47 AM

    Hi Rajeev,

    I get NullReferenceException Object reference not set to an instance of an object. inside WCF. Could you please suggest me how to fix this.

    • September 15, 2014 at 1:02 PM

      First create a client (i.e., Console App or Web App) to your WCF service and unit test the code flow.
      Its easy to test standalone WCF service than from your Plug-in. Also in your WCF service Trace the exceptions to event viewer to troubleshoot quickly.

  13. Ganesh
    September 15, 2014 at 2:49 PM

    Now there is no issue in the plugin. It is throwing NullReferenceException in WCF. this is the service interface i have

    [ServiceContract]
    [ServiceKnownType(typeof(EmailActivity))]
    public interface IService1
    {

    [OperationContract]
    void CreateEmailOnVehicleEntity(EmailActivity emailActivity);

    // TODO: Add your service operations here
    }

    [DataContract]
    public class EmailActivity
    {
    public IOrganizationService _service;
    public IPluginExecutionContext _context;

    [DataMember]
    public IOrganizationService service
    {
    get
    {
    return _service;
    }
    set
    {
    _service = value;
    }
    }

    [DataMember]
    public IPluginExecutionContext context
    {
    get
    {
    return _context;
    }
    set
    {
    _context = value;
    }
    }
    }

    Could you please check this code and the last code and let me know where to enable the tracing and how to troubleshoot this.

  14. Ganesh
    September 18, 2014 at 9:37 AM

    I am passing the parameter in the Service1 as CreateEmailonVehicleEntity(IOrganization service)

    and in my plugin i am calling channel.CreateEmailonVehicleEntity(service).

    But i get an exception Type ‘Microsoft.Crm.Extensibility.InprocessServiceProxy’ cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. If the type is a collection, consider marking it with the CollectionDataContractAttribute. See the Microsoft .NET Framework documentation for other supported types.
    2014-09-10T18:42:10.6048979Z

    How do i serialize the IOrganization service. I have already tried using data contract and datamember. But gives the same error.

  15. Ganesh
    September 22, 2014 at 2:28 PM

    I have successfully completed this task.

    Now I have another task to create custom workflow on creation of record.

    I need to check whether the contact in my record has account or not. If not then I have to create one.

    I have to create an Entity name bank with one field and link the owner to bank entity.

    create a case and link to customer/contact and attach notes with some details like vehicle name , make model etc.

    Drop the case in Bank Queue.

    Can you sugggest me how should i proceed.

  16. Vsubbareddy
    May 7, 2018 at 8:33 AM

    Nice explain

  1. September 9, 2011 at 10:09 PM

Leave a comment