Sunday, August 16, 2009

Using Unresolved Email Recipients in CRM 4.0

Unresolved emails are useful in that you can send an email to someone without having them setup as a system record (contact, account, lead, queue, user, ect).  Unresolved email addresses are turned off by default.  They should be used with caution.  If you send an email to an unresolved address it will not track the email to that lead/contact since one does not exist.  It also does not leverage the email "Do not allow" flags to allow people to opt out of emails.  With those considerations, there are still cases where it is very useful to send an email to someone without having to create a contact record.



I will show two example of sending emails to unresolved recipients.  The first will be sent from the email form using JavaScript.  The second will be done in a plugin.  We will add two unresolved email addresses as CC addresses on emails sent from a contact record.


Before we begin.  You must flip the setting to allow unresolved recipients.  Go to Settings --> Administration --> System Settings --> Email Tab.  Set Allow messages with unresolved e-mail recipients to be sent to yes.




 Second, we will add a couple of fields to the contact for secondary contacts email addresses.  These fields will contain our unresolved email addresses.




JavaScript Implementation
When the user clicks "Send Email" from the contact form we want the CC field to default with the two unresolved email addresses.  To do this we add the following Jscript to the onload of the email form.  The code will check to see if the regarding object is of type contact since this form is used for all emails.  Then it adds each email address to an email object that follows the activityparty schema for unresolved email addresses.  It has a type of 9206 and the email is set in the data property.

if (crmForm.FormType == 1 &&
    crmForm.all.regardingobjectid.DataValue != null &&
    crmForm.all.regardingobjectid.DataValue[0].typename == "contact" &&
    window.opener != null &&
    window.opener.document != null) {



    var ar = new Array();
    var emailObj = new Object();


    if (window.opener.document.crmForm.all.new_secondarycontactemail1 != null &&
            window.opener.document.crmForm.all.new_secondarycontactemail1.DataValue != null) {
        emailObj = new Object();
        emailObj['type'] = '9206';
        emailObj['category'] = '3';
        emailObj['data'] = window.opener.document.crmForm.all.new_secondarycontactemail1.DataValue;
        emailObj['name'] = window.opener.document.crmForm.all.new_secondarycontactemail1.DataValue;
        ar.push(emailObj);
    }



    if (window.opener.document.crmForm.all.new_secondarycontactemail2 != null &&
            window.opener.document.crmForm.all.new_secondarycontactemail2.DataValue != null) {
        emailObj = new Object();
        emailObj['type'] = '9206';
        emailObj['category'] = '3';
        emailObj['data'] = window.opener.document.crmForm.all.new_secondarycontactemail2.DataValue;
        emailObj['name'] = window.opener.document.crmForm.all.new_secondarycontactemail2.DataValue;
        ar.push(emailObj);
    }



    crmForm.all.cc.DataValue = ar;


}


Lastly, publish the customization.  When you click "Send Email" from the contact form your addresses will be added to the CC. 


 


 


Plugin Implementation


The same functionality can be added using a plugin.  The benefits of using a plugin versus a client side implementation is that you can implement consistent functionality regardless of whether the email send is triggered from a client portal, another plugin, or through the CRM UI.  The JavaScript implemenation is useful in that the user can see who the email is being sent to before they click Send. 



Install the plugin using the registration tool as a pre-create step for email save.  This will add the CC on the initial save of the email.  It is triggered regardless of whether the user clicks save or send from the email form.  The code also includes duplicate checking logic. So, if the user adds the email address to the CC from the form it will not duplicate the same address in the plugin.


using System.Web;
using System.Net;


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Crm.Sdk;
using Microsoft.Crm.SdkTypeProxy;
using Microsoft.Crm.Sdk.Query;
using System.Reflection;
using System.Web.Services.Protocols;
using Microsoft.Crm.SdkTypeProxy.Metadata;
using Microsoft.Crm.Sdk.Metadata;
using Inetium.CrmPlugins;
using System.Collections;



namespace Inetium.CrmPlugins.Plugins
{
    public class CaseUnresolvedEmailPlugin : IPlugin
    {
        public void Execute(IPluginExecutionContext context)
        {
            ICrmService service = null;
            try
            {
                if (context.InputParameters.Properties.Contains("Target") &&
                    context.InputParameters.Properties["Target"] is DynamicEntity)
                {
                    DynamicEntity entityInput = context.InputParameters.Properties["Target"] as DynamicEntity;
                    if (entityInput.Properties.Contains("regardingobjectid"))
                    {
                        Lookup regardingObjectLookup = entityInput.Properties["regardingobjectid"] as Lookup;
                        service = context.CreateCrmService(true);
                       
                        // Only using this for contacts
                        if (regardingObjectLookup.type == EntityName.contact.ToString())
                        {
                            // Pull parent contact - using helper method
                            DynamicEntity ctn = CRMUtilities.RetrieveById(service, EntityName.contact.ToString(), "contactid", regardingObjectLookup.Value, new ColumnSet(new string[]{"new_secondarycontactemail1", "new_secondarycontactemail2"}));
                            if (!ctn.Properties.Contains("new_secondarycontactemail1") && !ctn.Properties.Contains("new_secondarycontactemail2"))
                                return;



                            string email1 = ctn.Properties.Contains("new_secondarycontactemail1") ? ctn.Properties["new_secondarycontactemail1"].ToString() : "";
                            string email2 = ctn.Properties.Contains("new_secondarycontactemail2") ? ctn.Properties["new_secondarycontactemail2"].ToString() : "";


                            DynamicEntity[] partyArrayExisting = entityInput.Properties.Contains("cc") ? entityInput.Properties["cc"] as DynamicEntity[] : new DynamicEntity[] { };
                            List<DynamicEntity> partyList = new List<DynamicEntity>(partyArrayExisting);



                            if (email1 != "" && !IsEmailAlreadyInCC(email1, partyList))
                            {
                                DynamicEntity party = new DynamicEntity();
                                party.Name = EntityName.activityparty.ToString();
                                party.Properties["addressused"] = email1;
                                partyList.Add(party);
                            }



                            if (email2 != "" && !IsEmailAlreadyInCC(email2, partyList))
                            {
                                DynamicEntity party = new DynamicEntity();
                                party.Name = EntityName.activityparty.ToString();
                                party.Properties["addressused"] = email2;
                                partyList.Add(party);
                            }



                            // Generate CC's list by adding in those from contacts
                            if (partyList.Count > 0)
                                entityInput.Properties["cc"] = partyList.ToArray();


                        }


                    }
                }
            }
            catch (SoapException se)
            {
                throw new Exception(se.Detail.InnerText);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            finally
            {
                if (service != null)
                {
                    service.Dispose();
                    service = null;
                }
            }
        }



        private bool IsEmailAlreadyInCC(string email, List<DynamicEntity> activityPartyList)
        {
            bool bAlreadyExists = false;
            foreach (DynamicEntity existingParty in activityPartyList)
            {
                // compare to existing CCs
                if (existingParty.Properties.Contains("addressused") &&
                    (existingParty.Properties["addressused"].ToString() == email))
                {
                    bAlreadyExists = true;
                    break;
                }
            }
            return bAlreadyExists;
        }
    }
}



36 comments:

心痛 said...

cool blog,期待更新.........................

草莓花園 said...

Drive carefully. It is not only cars that can be recalled by their Maker.............................................

99.3.14 said...

無碼尋夢視訊聊天a漫a片a圖一夜情一葉情人妻激情情色寫真美女自拍辣妹自拍正妹自拍美女走光辣妹走光正妹走光脫衣秀脫衣走光色情自慰自拍成人全裸打炮打手槍打飛機巨乳巨奶女優大奶性交性愛淫蕩

佩怡 said...

It may be that your sole purpose in life is simply to serve as a warning to others.............................................

于名于名 said...

how do u do?................................................................

黃政弘 said...

如果你批評他人。你就沒有時間付出愛......................................................

睿玄 said...

thank you for you to make me learn more,thank you∩0∩

DesiraeF_Creech0709 said...

我從來不認為不同意我的看法就是冒犯........................................

EmogeneJ said...

Actions speak louder than words. ........................................

筠銘he0326ribertogarber said...

以簡單的行為愉悅他人的心靈,勝過千人低頭禱告........................................

退 said...

Hard day......................................................................

俊宏 said...

能付出愛心就是福;能消除煩惱就是慧。.............................................

CharitaA_Reese said...

要持續更新下去喲!!期待~~..................................................

EdmundoK_黎 said...

呵。。。。好可愛~~..................................................

又陽 said...

Knowledge is power.............................................................

佳皓 said...

文章不求沽名釣譽,率性就是真的..................................................................

育財 said...

原來天鵝嫁給癩蛤蟆就會生出醜小鴨.................................................................

陳隆 said...

與人相處不妨多用眼睛說話,多用嘴巴思考.................................................................

江婷 said...

良言一句三冬暖,惡語傷人六月寒。.................................................................

于庭 said...

幸福不是一切,人還有責任。............................................................

said...

向著星球長驅直進的人,反比踟躕在峽路上的人,更容易達到目的。............................................................

chen said...

After a storm comes a calm...................................................................

盈廖生家秀蔡 said...

第一次來這裡 愛上你的部落格 感謝你的分享............................................................

宥妃宥妃 said...

加油!期待更新哦!............................................................

楊儀卉 said...

人不可以求其備,必捨其所短,取其所長............................................................

琬安琬安 said...

此處是值得一探究竟的好部落格!!..................................................................

穆靜謝苡帆如 said...

Lets cross the bridge when we come to it............................................................

ToryO_Vis建銘 said...

It is easier to get than to keep it.......................................................................

珍盈洪 said...

來替你打氣,加油A_A............................................................

文王廷 said...

Cheek brings success.............................................................

王辛江淑萍康 said...

這一生中有多少人擦肩而過?而朋友是多麼可貴啊!......................................................................

陳雅吳水以竹 said...

時時關心,時時感動。..................................................

黃智樺黃智樺 said...

卡爾.桑得柏:「除非先有夢,否則一切皆不成。」共勉!.. .. ............................................................

佳張張張張燕張張張張張 said...

善言能贏得聽眾,善聽才能贏得朋友。......................................................................

韋陳富 said...

卡爾.桑得柏:「除非先有夢,否則一切皆不成。」共勉!.................................................................

王怡迪 said...

一棵樹除非在春天開了花,否則難望在秋天結果。......................................... ........................