CRM 4.0 How to handle when user click "Track in CRM" on an email that doesn't exist on a contact

Unanswered CRM 4.0 How to handle when user click "Track in CRM" on an email that doesn't exist on a contact

  • Tuesday, December 09, 2008 9:54 AM
     
     

    I have been asked to write some code to handle the following problem:

     

    If a user in Outlook clicks "Track in CRM" on a mail with an email address that does not exist in CRM on any contact the email is put in the database with no relationship to any record so it is kind of "Lost".

     

    So instead they (the CRM guys) want me to write some code that when a user clicks "Track in CRM" the code searches on all contacts to see if that email exists and if not I should give a warning that this contact email does not exist and a question if they would like to create the contact. If they click yes to create contact I should bring up the "New contact" window in CRM. And when the contacts is created then the Tracking can be applied.

     

    I have never programmed towards CRM before so please treat me as a novice in CRM. I am greatful for all help I can get.

     

    What I know so far is that the event that fires when user clicks "Track in CRM" is called CreateNewEmail activity.  However I do not know if this should be solved by writing a Workflow or if it is a JScript solution.

     

     

All Replies

  • Tuesday, December 09, 2008 1:54 PM
     
     
    You can not do this in JavaScript because the button is an "MS CRM Outlook Client Add-On". 
    You can not do it in Workflow because workflows get executed serverside and do not have a user interface element.

    If you really want to implement this functionality you will need to write an Outlook "Add-On" in c#.

    The new email activity is created when the email is sent so it is not really useful in your case as you want your function to search the MS CRM database and provide user with custom optoin to create new if it does not exist.


    Simple Solution: 

    Why dont you ask users to type the name of the person they want to send the email to in the "To" field and then click "Check Names" function of outlook. If nothing is returned then they can go in and create the contact.

    You can read more about this at the URL below:



    Hassan.
  • Tuesday, December 09, 2008 2:36 PM
     
     

    Thanks for the reply. That saves my a lot of trouble of trying and failing. However your solution does not solve the problem.

     

    The problem is that the users say get an email from someone and then they decide that they want this email tracked in CRM. So they click the track in CRM button. But if for some reason this persons email was not already in CRM as one of the contacts emails then the tracking just lays "hidden" in the database with a no connection to any contact. Hence you cannot find it later in CRM (withouth going into the databasetable). yet for the user it looks like it is being tracked as the icon changes on the email in the Outlook client. For the users this seems like a big bug as it does not ive a warning saying you cannot track this in CRM as this contact does not exist.

     

    So this is not nessecary when sending an email, it most often is when received an email.

     

    Any other ideas to how I can solve this?

     

    Lisa-Marie

  • Tuesday, December 09, 2008 2:44 PM
     
     
    Yes. 
    All emails not associated with any contact are visible in MS CRM with a RED Exclamation mark. You do not need to look in the database for those emails.

    To view such emails go to My Workplace -> Activities -> Filter by Email ->Recieved Emails. 
    You will see emails that were tracked by MS CRM becasue the user clicked on the "Track in MS CRM" button but MS CRM could not find a contact to associate the email with.

    When you click on the Red Exclamation mark the system will let you assocaited the email with an existing contact OR let you create a new contact. 

    Let your system know how to do this and make this a part of your SOP  (Standard Operating Prcedure).  This should solve your problem.

    Hassan.
  • Tuesday, December 09, 2008 10:05 PM
     
     

     

    Hi,

     

    Ok sounds reasonable. Thank you!

     

    Do you mean System Administrator and that person should be responsible to resolve missing contacts as a SOP?

     

    Also.. did you possibly mean a RED Questionmark? As that seem to be the only thing I see when I follow your instrucitons. And also I do not have a filter for received emails.... just My received emails so I guess Administrator need to use the filter All Emails and go through all of those with a RED Questionmark and resolve the missing contact??

     

    Lisa-Marie

     

     

  • Wednesday, December 10, 2008 12:03 PM
     
     

    Hi again.

     

    I presented your solution to the system administrator who is also a user of CRM, and she was not pleased with this solution. She thinks it is not very user friendly. Also she will not always know the contact details for contacts, and therefore can't create the missing contacts. And if she is the one creating the contact then she is the owner of the contact and that, according to her, is not correct.

     

    We discussed some options and found another approach to do this problem. This is the solutions:

    "Create a workflow that starts when a new email is tracked in CRM. This workflow need to check if there are any conflicts with the TO and FROM contacts in the email and if there is it should send an email to the creator of the tracking that there is an unresolved contact in this email tracking, and include a link that will open up the tracked email in CRM and let the user fix it themselves from there."

     

    So question now is... how can I implement this Workflow. Keep in mind I am still a novice in CRM. However I have programmed workflows in SharePoint before so I assume there are some simularities.

     

    All help is appriciated!

     

    Lisa-Marie

  • Wednesday, December 10, 2008 3:22 PM
     
     
    Hi Lisa,
        
    If you want to do this using workflow you will need to create a workflow assembly. 
    Download the SDK. You will find sample code to do what you are trying to do.
    You can download the SDK from the URL below:

    regards,
    Hassan.
  • Wednesday, December 10, 2008 3:51 PM
     
     

    Great thanks.

     

    I was trying to create a simple workflow in the GUI, but I don't think I have the tools to check if the email has a "recipient not resolved to a record" error on it and there for I cannot do this.

     

    I will take use of the SDK and see if I can find more there.

     

    I need help to find the property names for the error mesage "At least one recipient could not be resolved to a record in the system". And also what is the property name to get the direct link to open the spesific email in CRM.

     

    I want to create a task on the user that started the Tracking of the email that he must add a contact, and in the task have the link directly to the email.

     

    Regards,

    Lisa-Marie

  • Wednesday, December 10, 2008 4:12 PM
     
     
    Lisa
         All records in MS CRM have a GUID. 

    You need to create a workflow that runs when an email activity is created. You need to pass the GUID of the new email to your custom code.

    You could will then check if it is an incomig email or outgoing email.

    If incoming you will need to use "CheckIncomingEmailResponse.ReasonCode". Check SDK for details.

    Hassan.
  • Thursday, December 11, 2008 11:00 AM
     
     

     

    Hassan,

     

    What do I do with the GUID? Do I need to use the CrmService to get the Email based on the GUID?

     

    How do I check if the email in incomming or outgoing?

     

    So if I have understood you correctly I should create a custom activity that checks an email if it has a ReasonCode equeal to Unresolved contact. And have the activity return true or false.

     

    Then I Create a Workflow in CRM and make use of this custom activity. The rest of the workflow steps I can create through teh CRM GUI?

     

    Thanks for all help.

    Lisa-Marie

  • Thursday, December 11, 2008 11:18 AM
     
     
    Hi Lisa,

    >>Do I need to use the CrmService to get the Email based on the GUID?
    Yes.

    >>How do I check if the email in incomming or outgoing?
    You use the "directioncode" attribute of the email entity.

    >>So if I have understood you correctly I should create a custom activity that checks an email if it has a ReasonCode equeal to Unresolved contact. And have the activity return true or false.
    NO. You dont need to create any custom entities. the Email Entity you retreive by using the GUID will give you the ReasonCode you will need to use.

    >>Then I Create a Workflow in CRM and make use of this custom activity. The rest of the workflow steps I can create through teh CRM GUI?
    No. You create a workflow to capture the "New Email activity created" event. Your workflow fires off when a new email activity is created in the system. Your workflow will pass the GUID of the new email to your assembly.


    Hassan.
  • Thursday, December 11, 2008 12:00 PM
     
     

    Hassan,

     

    What I tried to say is that I need to create a Custom Workflow Activity that I can use in a CRM workflow? And that I don't have to write the entire workflow in code but can create most of the workflow in CRM and in that make use of the custome workflow activity that I have created in code.

     

    I looked at the ReasonCode but I don't understand how I can use that to tell if contacts in TO or FROM field is missing a record in CRM. Also I do not really care if the email in incomming or outgoing as I need to check both types of emails.

    In the TO/ FROM field of an email there could be more than 1 contact and also there could be 1 of 5 contacts that is missing a record whilst the other 4 is fine.

     

    I found this code; http://forums.microsoft.com/Dynamics/ShowPost.aspx?PostID=3687873&SiteID=27 and have made use of a lot from here. I believe I am on the right way finally.

  • Thursday, December 18, 2008 8:58 AM
     
     

    Hi Hassan,

     

    Did you or anyone else have an answer to my last post?

     

    Regards,

    Lisa-Marie

     

     

     

  • Thursday, December 18, 2008 1:53 PM
     
     
    Hi Lisa,
        No replies yet. How are you getting on? Found a solution yet?

    Hassan.
  • Thursday, January 08, 2009 2:12 PM
     
     

    It has been on hold over Christmas so I needed to get back into it again. No unfortunatly I have not found a solution. So far this is the code I have written for the custom activity:

     

    Code Snippet

    namespace CreateResolveContactProblemTask

    {

    [PersistOnClose]

    [CrmWorkflowActivity("Check For Unresolved Contacts", "Custom Activities Library")]

    public sealed partial class CheckForUnresolvedContacts : SequentialWorkflowActivity

    {

    /// <summary>

    /// Guid to the email that is to be inspected for any unresolved contactsw

    /// </summary>

    [CrmInput("Current EmailID")]

    [CrmReferenceTarget("email")]

    public Lookup CurrentEmailId

    {

    get { return (Lookup)GetValue(CurrentEmailIdProperty); }

    set { SetValue(CurrentEmailIdProperty, value); }

    }

     

    #region Dependency Properties

    /// <summary>

    /// Using a DependencyProperty as the backing store for EmailGuid. This enables animation, styling, binding, etc...

    /// </summary>

    public static readonly DependencyProperty CurrentEmailIdProperty =

    DependencyProperty.Register("CurrentEmailId", typeof(Lookup), typeof(CheckForUnresolvedContacts));

     

    /// <summary>

    /// Returns true or false if this email had a unresolved contact

    /// </summary>

    [CrmOutput("Has Unresolved Contacts")]

    public bool HasUnresolvedContacts

    {

    get { return (bool)GetValue(HasUnresolvedContactsProperty); }

    set { SetValue(HasUnresolvedContactsProperty, value); }

    }

     

    // Using a DependencyProperty as the backing store for HasUnresolvedContact. This enables animation, styling, binding, etc...

    public static readonly DependencyProperty HasUnresolvedContactsProperty =

    DependencyProperty.Register("HasUnresolvedContacts", typeof(bool), typeof(CheckForUnresolvedContacts));

     

    #endregion

     

    public CheckForUnresolvedContacts()

    {

    InitializeComponent();

    }

     

    protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)

    {

    //Get the context service

    IContextService contextService = (IContextService)executionContext.GetService(typeof(IContextService));

    IWorkflowContext context = contextService.Context;

     

    //Use the context service to create an instance of CrmService

    ICrmService crmService = context.CreateCrmService();

    Guid newEmailId = CurrentEmailId.Value;

     

    try

    {

    //Get email from CrmService based on GUID

    email crmEmail = (email)crmService.Retrieve(EntityName.email.ToString(), newEmailId, new AllColumns());

     

    if (crmEmail != null)

    {

    // Directioncode = true if email is outgoing

    if (crmEmail.directioncode.Value)

    {

     

    }

    }

    }

    catch (System.Web.Services.Protocols.SoapException se)

    {

    TextWriter w = new StreamWriter(@"C:\Downloads\SeCrmerror.txt");

    w.WriteLine(se.Message + " " + se.InnerException.Message);

    w.Close();

    return ActivityExecutionStatus.Faulting;

    }

    catch (Exception ex)

    {

    TextWriter w = new StreamWriter(@"C:\Downloads\ExCrmerror.txt");

    w.WriteLine(ex.Message + " " + ex.InnerException.Message);

    w.Close();

    return ActivityExecutionStatus.Faulting;

    }

    return base.Execute(executionContext);

    }

    }

    }

     

     

     

    I need to figure out how to debug so that I can find the answer to how to check for the error.

  • Monday, January 26, 2009 10:06 PM
     
     

    Debugging a Plug-in

    The following steps describe how to debug a plug-in.

    1. Deploy the plug-in assembly.

      Copy the assembly to the standard plug-in folder on the server: <crm-root>\Server\bin\assembly. If there is another copy of the assembly at the same location and you cannot overwrite that copy because it is locked by Microsoft Dynamics CRM, run the iisreset program in a command window to free the assembly.

    2. Register the plug-in on the desired stage of the event execution pipeline. Register the plug-in assembly on the server using on-disk deployment.

      Tip It is possible to debug a database deployed plug-in. The compiled plug-in assembly's .pdb file must be copied to the server's <crm-root>\Server\bin\assembly folder and IIS must then be restarted. After debugging has been completed, you must remove the .pdb file and reset IIS to prevent the w3wp.exe process from consuming additional memory.

      Generally, you do not want to register your plug-in in the event execution pipeline until the plug-in assembly is available on the Microsoft Dynamics CRM server. If someone else is using Microsoft Dynamics CRM on the server, and you have registered the plug-in in but have not yet deployed the assembly, the person running Microsoft Dynamics CRM receives an error if the system tries to execute the missing plug-in.

    3. Configure the debugger.

      Set a breakpoint in your plug-in code. For an online plug-in, attach the debugger to the w3wp.exe process on the Microsoft Dynamics CRM server. For an offline plug-in, attach the debugger to the Microsoft.Crm.Application.Hoster.exe process. For asynchronous registered plug-ins (or workflow assemblies) attach to the CrmAsyncService.exe process. If there are multiple processes running for the same executable you may not know which process to attach to. You can do an IIS reset to terminate those processes. Next, open or refresh the Microsoft Dynamics CRM Web application to start the process again.

    4. Test the plug-in.

      Run the Microsoft Dynamics CRM Web application, or other custom application that uses the SDK, and perform whatever action is required to cause the plug-in to execute. For example, if a plug-in is registered for an account creation event, create a new account.

    5. Debug your plug-in code.

      Make any needed changes to your code so that it performs as you want. If the code is changed, compile the code into an assembly and repeat step numbers 1, 3, and 4 in this procedure as necessary. However, if you change the plug-in assembly version number, you must unregister the earlier version of the assembly and register the new version.

    6. Register the plug-in in the database.

      After the edit/compile/deploy/test/debug cycle for your plug-in has been completed, unregister the (on-disk) plug-in assembly and then reregister the plug-in in the Microsoft Dynamics CRM database.

  • Wednesday, July 21, 2010 9:30 AM
     
     

    Hi Asiliram


    Did you ever get this working as I would like to do the same for my users?

     

    Thanks

     

    Andy


    asatchwell