Microsoft CRM Customization – programming Closed E

Microsoft CRM Customization – programming Closed Email Activity

by: Boris Makushkin

Microsoft CRM is CRM answer from Microsoft and attempt to get market share from Siebel, Oracle and others traditional Client Relationship Management System vendors. Microsoft CRM uses all the spectrum of Microsoft recent technologies: .Net, MS Exchange, MS Outlook, MS SQL Server, Replication, Indexing, Active Directory, Windows 2000/2003 security model, C#, VB.Net, HTML, XML Web Service, XLTP, Javascript to name a few.

Todayกs topic is Activity of email type programming you usually deal with these customizations when you improve Microsoft Exchange CRM connector. How do you create closed activity this is the main discussion topic. We’ll use C#.Net coding

One of the roles of our Exchange Event Handler/Sink is creation MS CRM Closed Activity in handling incoming and outgoing email messages. The interaction with Microsoft CRM uses two approached – using MS CRM SDK (handling inbound and outbound XML messages) and via direct access to MS CRM Database. Let’s first look at the Closed Activity creation algorithm:

1. First we need to understand the entity we need to create activity for: Account, Lead or Contact. The selection should use specific criteria – in our case this is email address:

if ((crmAccount = crmConnector.GetAccount(mailboxFrom)) != null) {

}

else if ((crmContact = crmConnector.GetContact(mailboxFrom)) != null) {

}

else if ((crmLead = crmConnector.GetLead(mailboxFrom)) != null) {

}

2. Then we have to get GUID of MS CRM user, who owns this entity, C# code like this:

crmUser = crmConnector.GetUser(crmAccount.GetOwnerId());

3. Next step is closed Activity creation:

emailId = crmConnector.CreateEmailActivity(

crmUser.GetId(),

Microsoft.Crm.Platform.Types.ObjectType.otAccount, crmAccount.GetId(),

Microsoft.Crm.Platform.Types.ObjectType.otSystemUser, crmUser.GetId(),

crmAccount.GetEmailAddress(), crmUser.GetEmailAddress(), sSubject, sBody);

4. The method to create closed activity:

public Guid CreateEmailActivity(Guid userId, int fromObjectType, Guid fromObjectId, int toObjectType, Guid toObjectId, string mailFrom, string mailTo, string subject, string body) {

try {

log.Debug(กPrepare for Mail Activity Creatingก);

// BizUser proxy object

Microsoft.Crm.Platform.Proxy.BizUser bizUser = new Microsoft.Crm.Platform.Proxy.BizUser();

ICredentials credentials = new NetworkCredential(sysUserId, sysPassword, sysDomain);

bizUser.Url = crmDir + กBizUser.srfก;

bizUser.Credentials = credentials;

Microsoft.Crm.Platform.Proxy.CUserAuth userAuth = bizUser.WhoAmI();

// CRMEmail proxy object

Microsoft.Crm.Platform.Proxy.CRMEmail email = new Microsoft.Crm.Platform.Proxy.CRMEmail();

email.Credentials = credentials;

email.Url = crmDir + กCRMEmail.srfก;

// Set up the XML string for the activity

string strActivityXml = กก;

strActivityXml += กก;

strActivityXml += กก) + กก;

strActivityXml += กก;

strActivityXml += userId.ToString(กBก) + กก;

strActivityXml += กก;

// Set up the XML string for the activity parties

string strPartiesXml = กก;

strPartiesXml += กก;

strPartiesXml += กก + mailTo + กก;

if (toObjectType == Microsoft.Crm.Platform.Types.ObjectType.otSystemUser) {

strPartiesXml += กก + Microsoft.Crm.Platform.Types.ObjectType.otSystemUser.ToString() + กก;

}

else if (toObjectType == Microsoft.Crm.Platform.Types.ObjectType.otAccount) {

strPartiesXml += กก + Microsoft.Crm.Platform.Types.ObjectType.otAccount.ToString() + กก;

}

else if (toObjectType == Microsoft.Crm.Platform.Types.ObjectType.otContact) {

strPartiesXml += กก + Microsoft.Crm.Platform.Types.ObjectType.otContact.ToString() + กก;

}

else if (toObjectType == Microsoft.Crm.Platform.Types.ObjectType.otLead) {

strPartiesXml += กก + Microsoft.Crm.Platform.Types.ObjectType.otLead.ToString() + กก;

}

strPartiesXml += กก+ toObjectId.ToString(กBก) + กก;

strPartiesXml += กก;

strPartiesXml += Microsoft.Crm.Platform.Types.ACTIVITY_PARTY_TYPE.ACTIVITY_PARTY_TO_RECIPIENT.ToString();

strPartiesXml += กก;

strPartiesXml += กก;

strPartiesXml += กก;

strPartiesXml += กก + mailFrom + กก;

if (fromObjectType == Microsoft.Crm.Platform.Types.ObjectType.otSystemUser) {

strPartiesXml += กก + Microsoft.Crm.Platform.Types.ObjectType.otSystemUser.ToString() + กก;

}

else if (fromObjectType == Microsoft.Crm.Platform.Types.ObjectType.otAccount) {

strPartiesXml += กก + Microsoft.Crm.Platform.Types.ObjectType.otAccount.ToString() + กก;

}

else if (fromObjectType == Microsoft.Crm.Platform.Types.ObjectType.otContact) {

strPartiesXml += กก + Microsoft.Crm.Platform.Types.ObjectType.otContact.ToString() + กก;

}

else if (fromObjectType == Microsoft.Crm.Platform.Types.ObjectType.otLead) {

strPartiesXml += กก + Microsoft.Crm.Platform.Types.ObjectType.otLead.ToString() + กก;

}

strPartiesXml += กก+ fromObjectId.ToString(กBก) + กก;

strPartiesXml += กก;

strPartiesXml += Microsoft.Crm.Platform.Types.ACTIVITY_PARTY_TYPE.ACTIVITY_PARTY_SENDER.ToString();

strPartiesXml += กก;

strPartiesXml += กก;

strPartiesXml += กก;

log.Debug(strPartiesXml);

// Create the email object

Guid emailId = new Guid(email.Create(userAuth, strActivityXml, strPartiesXml));

return emailId;

}

catch (System.Web.Services.Protocols.SoapException e) {

log.Debug(กErrorMessage: ก + e.Message + ก ก + e.Detail.OuterXml + ก Source: ก + e.Source);

}

catch (Exception e) {

log.Debug(e.Message + ก

ก + e.StackTrace);

}

return new Guid();

}

5. To make the activity just created be shown correctly you need to setup it’s flags according to MS CRM standards:

public void UpdateActivityCodes(Guid emailId) {

try {

OleDbCommand command = conn.CreateCommand();

command.CommandText = กUPDATE ActivityBase SET DirectionCode = (?), StateCode = (?), PriorityCode = (?) WHERE ActivityId = (?)ก;

command.Prepare();

command.Parameters.Add(new OleDbParameter(กDirectionCodeก, Microsoft.Crm.Platform.Types.EVENT_DIRECTION.ED_INCOMING));

command.Parameters.Add(new OleDbParameter(กStateCodeก, Microsoft.Crm.Platform.Types.ACTIVITY_STATE.ACTS_CLOSED));

command.Parameters.Add(new OleDbParameter(กPriorityCodeก, Microsoft.Crm.Platform.Types.PRIORITY_CODE.PC_MEDIUM));

command.Parameters.Add(new OleDbParameter(กActivityIdก, emailId));

log.Debug(กPrepare to update activity code ก + emailId.ToString(กBก) + ก in ActivityBaseก);

command.ExecuteNonQuery();

}

catch(Exception e) {

log.Debug(e.Message + ก

ก + e.StackTrace);

}

}

public void UpdateActivityQueueCodes(Guid emailId, Guid queueId) {

try {

OleDbCommand command = conn.CreateCommand();

command.CommandText = กUPDATE QueueItemBase SET Priority = (?), State = (?), QueueId = (?) WHERE ObjectId = (?)ก;

command.Prepare();

command.Parameters.Add(new OleDbParameter(กPriorityก, Microsoft.Crm.Platform.Types.PRIORITY_CODE.PC_MEDIUM));

command.Parameters.Add(new OleDbParameter(กStateก, Microsoft.Crm.Platform.Types.ACTIVITY_STATE.ACTS_CLOSED));

command.Parameters.Add(new OleDbParameter(กQueueIdก, queueId));

command.Parameters.Add(new OleDbParameter(กObjectIdก, emailId));

log.Debug(กPrepare to update activity queue code ก + emailId.ToString(กBก) + ก in QueueItemBaseก);

command.ExecuteNonQuery();

}

catch(Exception e) {

log.Debug(e.Message + ก

ก + e.StackTrace);

}

}

Happy customizing, implementing and modifying! If you want us to do the job give us a call 18665280577! help@albaspectrum.com

About The Author

Boris Makushkin is Lead Software Developer in Alba Spectrum Technologies – USA nationwide Microsoft CRM, Microsoft Great Plains customization company, based in Chicago, Boston, San Francisco, San Diego, Los Angeles, Houston, Dallas, Atlanta, Miami, Montreal, Toronto, Vancouver, Madrid, Moscow, Europe and internationally (www.albaspectrum.com), he is Microsoft CRM SDK, C#, VB.Net, SQL, Oracle, Unix developer. Boris can be reached: 18665280577 or borism@albaspectrum.com.

borism@albaspectrum.com

This article was posted on October 25, 2004

by Boris Makushkin

Boost Your Sales Copy With One Simple Tweak

Boost Your Sales Copy With One Simple Tweak

by: Palyn Peterson

Do you want an amazingly simple trick to move far ahead of your competition and increase sales? With this free, no software little tweak, you will be able to put customized information into a web page that is different for everyone you invite to visit. It is incredibly simple; seriously, I promise! All that you need is a very basic understanding of HTML, like how to make hyperlinks, and I will teach you everything else. Sound fair?

What can you do with this, you may be wondering? Well, if you have a newsletter, you can create a link to your web site and the page displayed could have your subscribers first name where ever you want it. It doesn’t have to be their first name either; it could quite literally be any custom variable that your newsletter managing service/script/program has saved for each of your subscribers their last name, email address, snail mail address, gender, age, favorite color, etc.

But we don’t have to stop there, not at all. You can go on and use as many variables as you want, not just one. Weกll thoroughly cover this.

Why is this HTML tweak useful, you may now be asking? Just imagine this, you email your list of subscribers about a new product you have recently released. In your email, you write a few paragraphs about the product to generate interest and conveniently provide a link for them to click on to go back to your website and read your full sales copy. Since you have such a trusting reputation with your subscribers, they give your product the benefit of the doubt and click on the link to read more. When they get to your sales copy, lo and behold their name is used throughout the page!

We all learned in Marketing 101 that your sales copy needs to be personal; that when you write it, you need to speak to one person and in everyday language. With this cool HTML tweak, you will be able to reach new levels of personalization. Yes, the subscriber will be impressed that their name is used in the middle of your sales copy, and yes, they will have more personal interest in what you are saying. It is a whole new experience at that point, because you are talking to them individually. Heck, you just used their name! It won’t just be, กYou will get big results!ก but, กFred, you will get big results!ก

Now, letกs get on to the code! For this example, we are going to be using an HTML file named กchoppers.htmก.

Open up กchoppers.htmก in your favorite editor. Now, where ever you want the subscribers first name to appear, put this code: กก (minus the quotes), and wherever you want their last name to appear, put: กก (again, minus the quotes).

Do you see the ก$aก in the first bit of code and the ก$bก in the second? For every custom variable you want to appear on your web page, just put that little bit of code with a different letter.

To explain it a little more, for every place the subscribers first name should appear, put กก. For every place the subscribers last name should appear, put กก. For every place the subscribers email address should appear, put กก. And so on and so forth. Yes, you can use each bit of code as often as you want. No, it doesn’t really matter that the first name is using the code with ก$aก it could be ก$hก, ก$pก or even ก$zก, just as long as each custom variable uses a different letter.

Now you will need to rename กchoppers.htmก to กchoppers.phpก. Some HTML editors do not open up .php files, so I suggest only doing a กsave asก to a .php file. That way, you will still have กchoppers.htmก to edit whenever you need to, then just do another กsave asก. Upload the .php file to your web host.

Now we need to create the link the subscribers will click on to get to the newly created กchoppers.phpก file. For this part, you need to know what codes your newsletter managing service/script/program uses to customize your emails. Just for this example, letกs say two of them are ;FirstName; and ;LastName;.

When you write your email, the address of your sales page in the link you will create to go to it, will look like this: กyourdomain.com/choppers.php?a=;FirstName;&b=;LastName;ก. But when you send out your email to your subscribers, your newsletter managing service/script/program will fill in those codes with the subscribers first and last name. So when the subscriber clicks on the link, the address to your sales page will actually look like this: กyourdomain.com/choppers.php?a=Fred&b=Jonesก.

If you only cared to use the subscribers first name, you would only need to use กก in กchoppers.phpก, and the address to that page in the link in your email would look like: กyourdomain.com/choppers.php?a=;FirstName;ก, and for your subscriber Fred, his link address would end up looking like: กyourdomain.com/choppers.php?a=Fredก.

You have just now taken many steps in front of your competition. You are now able to market much more personally than most people think is even possible.

Copyright © by Palyn Peterson

mailto:palyn@futureinternetmarketing.com

About The Author

Palyn Peterson publishes the acclaimed Advanced Internet Marketing News. A professional newsletter with a refreshing perspective and a strong focus on nocost techniques. http://FutureInternetMarketing.com. FREE Tips, Tricks, Tools, Resources, eBooks, and More!

This article is free to publish with resource box. If using this article, please send a brief message to mailto:palyn@futureinternetmarketing.com

This article was posted on December 18, 2003

by Palyn Peterson

Microsoft CRM Customization – programming email ac

Microsoft CRM Customization – programming email activity attachment

by: Boris Makushkin

Microsoft CRM is now on the scene and it is increasing its market share, due to Microsoft Business Solutions muscles and marketing strategy. It is tightly integrated with other Microsoft Business Solutions products such as Microsoft Great Plains, Solomon, Navision. Being relatively inexpensive in comparison to competitors, like Siebel, Oracle Microsoft CRM opens you the door for worldwide operations automation. In this small article we would like to give you, software developer, some hints on Microsoft CRM customization.

Todayกs topic is Activity of email type programming you usually deal with these customizations when you improve Microsoft Exchange CRM connector. How do you create email attachment this is the main discussion topic. We’ll use C#.Net.

In Exchange handler/event sink you create Activity of email type in MS CRM and one of the tasks is transfer the attachment(s) from the body of the incoming email to the attachment(s) in the Activity. You can realize it through direct access to Microsoft CRM DB. Let’s see C# code:

1. First we are getting access to the letter via ExOLEDB:

CDO.Message iMessage = new CDO.MessageClass();

CDO.IBodyPart iPrt;

iMessage.DataSource.Open(bstrURLItem, null, ADODB.ConnectModeEnum.adModeRead,

ADODB.RecordCreateOptionsEnum.adFailIfNotExists, ADODB.RecordOpenOptionsEnum.adOpenSource, กก, กก);

2. Next – we come through the attachment list, get their names and save their bodies into temporary catalogue:

for(int i = 1; i ก;

strXml += กActivity 1ก;

strXml += กก + attachmentNumber + กก;

strXml += กก + emailId.ToString(กBก) + กก;

strXml += กก;

// Create the activity attachment

Guid attachmentId = new Guid(activityAttachment.Create(userAuth, strXml));

log.Debug(กCreate Attachemnt ID: ก + attachmentId.ToString(กBก));

UploadFileToDB(attachmentId, filename, filesize);

return attachmentId;

}

catch (System.Web.Services.Protocols.SoapException e) {

log.Debug(กErrorMessage: ก + e.Message + ก ก + e.Detail.OuterXml + ก Source: ก + e.Source);

}

catch (Exception e) {

log.Debug(e.Message + ก

ก + e.StackTrace);

}

return new Guid();

}

5. Main problem, however is attachment body adding to MS CRM database. Main requirement is – attachment must be encoded as BASE64 stream and its length must be specified correctly together with Nine Type and file name of the file it will be knows as an attachment in activity. Let’s look at the C# code:

public void UploadFileToDB(Guid attachmentId, string filename, long filesize) {

string contentType = กapplication/octetstreamก;

try {

Hashtable mimes = LoadMimeDB(Environment.SystemDirectory + ก/Albaspectrum/ContentType.txtก);

if (mimes != null) {

string tmpContentType = GetMimeType(mimes, filename);

if (tmpContentType != null && !tmpContentType.Equals(กก))

contentType = tmpContentType;

}

byte[] memoryData = new byte[filesize];

FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read);

BinaryReader reader = new BinaryReader(fs);

reader.Read(memoryData, 0, (int)filesize);

reader.Close();

fs.Close();

OleDbCommand command = conn.CreateCommand();

command.CommandText = กUPDATE ActivityMimeAttachment SET FileSize = (?), MimeType = (?), FileName = (?), Body = (?) WHERE ActivityMimeAttachmentId = (?)ก;

command.Prepare();

command.Parameters.Add(new OleDbParameter(กFileSizeก, filesize));

command.Parameters.Add(new OleDbParameter(กMimeTypeก, contentType));

command.Parameters.Add(new OleDbParameter(กFileNameก, new FileInfo(filename).Name));

command.Parameters.Add(new OleDbParameter(กBodyก, Convert.ToBase64String(memoryData, 0, (int)filesize)));

command.Parameters.Add(new OleDbParameter(กActivityMimeAttachmentIdก, attachmentId));

log.Debug(กPrepare to upload attachemnt ก + attachmentId.ToString(กBก) + ก in ActivityMimeAttachmentก);

command.ExecuteNonQuery();

memoryData = null;

}

catch (Exception e) {

log.Debug(e.Message + ก

ก + e.StackTrace);

}

}

6. File ContectType.txt is matching list of the files extensions and their mimetype in the following format:

asc application/pgpencrypted Armored Encrypted file (PGP)

asd application/astound Autosave file (Word for Windows)

asm PC ASM File

asn application/astound

etc.

Happy customizing, implementing and modifying! If you want us to do the job give us a call 18665280577! help@albaspectrum.com

About The Author

Boris Makushkin is Lead Software Developer in Alba Spectrum Technologies – USA nationwide Microsoft CRM, Microsoft Great Plains customization company, based in Chicago, Boston, San Francisco, San Diego, Los Angeles, Houston, Dallas, Atlanta, Miami, Montreal, Toronto, Vancouver, Moscow and Europe and internationally (www.albaspectrum.com), he is Microsoft CRM SDK, C#, VB.Net, SQL, Oracle, Unix developer.

borism@albaspectrum.com

This article was posted on October 24, 2004

by Boris Makushkin

Search Engine Crawlers and Dynamic Web Pages

Search Engine Crawlers and Dynamic Web Pages

by: Jerry Yu

There are misunderstandings and confusions in the Search Engine Optimization (SEO) world in regard to search engines indexing of dynamic web pages.
It has been claimed that search engine spiders don’t index/crawl dynamic web pages well. This statement is only half true. The correct statement should be กSearch engines don’t index/crawl dynamic web pages well if the page URL contains ก?ก (without quotes) character.ก. Search engines do index dynamic web pages very well if the page URL contains no ก?ก character(s).
URLs that contain ก?ก are called dynamic URLs.
What web pages are dynamic?
If you have knowledge about HTML, you know the web pages you create normally have .htm, or .html, file extension. These files are static because the HTML code don’t change on the fly when requested and they are not processed by web servers. They can be viewed without using a web server.
A web page is said to be dynamic if it is created by using serverside scripting languages such as php, asp, jsp, perl, cgi and so on. These languages are like normal programming languages such as C++, Java, etc. The major difference is scripting languages can’t be compiled beforehand. They can only be processed by web servers on the fly when the page is requested by a visitor. Dynamic pages can’t be viewed without a web server.
When a dynamic page is requested, the web server first looks at the pageกs source code and if any serverside scripting code exist, it will process them and generate static HTML result. When processing of the full page has been completed, web server sends only pure HTML code to the web visitorกs browser.
Using scripting languages to create web pages gives you the power to do nearly anything you want. If the dynamic page has no ก?ก character in its URL, search engine spiders treat the page the same as a normal HTML static page.
Query string parameters
When ก?ก character is used, the pageกs full URL changes when values after ก?ก change. The portion after ก?ก is called the pageกs query string parameter(s), or simply query parameter(s). Every time when parameter(s) changes, the resulted page will be different.
A page URL can contain more than one ก?ก character. When this happens, search engine spiders will have difficult time to index the resulted page. If the page has only one ก?ก character, major search engine spiders can crawl that page well. For example, Google can index and store a pageกs URL as http://www.examplesite.com/product.asp?id=12345. But if the same pageกs URL is
http://www.examplesite.com/product.asp?id=12345&category=23&page=3
Most search engines will not be able to index it well even though Googlebot and Yahoo! Slurp may be able to index it.
(Note: Googlebot is Googleกs webcrawling robot. Yahoo! Slurp is Yahooกs webcrawling robot. Search engine robots collect documents from the web to build a searchable index.)
Yahoo help says
กYahoo! does index dynamic pages, but for page discovery, our crawler mostly follows static links. We recommend you avoid using dynamically generated links except in directories that are not intended to be crawled/indexed (e.g., those should have a /robots.txt exclusion).ก
Googleกs Webmaster Guidelines:
กIf you decide to use dynamic pages (i.e. the URL contains a ก?ก character), be aware that not every search engine spider crawls dynamic pages as well as static pages. It helps to keep the parameters short and the number of them small.ก
Letกs analyze what Google has stated above.
1. the URL contains a ก?ก character: this means the definition of dynamic pages are those containing ก?ก characters in URL.
2. keep the parameters short: this means the number of characters in each individual parameter should be short. There is no quantitative measurement given by Google but we can check some web forums to see examples. My Search engine friendly article (http://www.webactionguide/actionguide/buildsite/sefriendly.php) referenced black hat seo discussion thread on Cre8ASiteForums. Its URL is http://www.cre8asiteforums.com/viewtopic.php?t=8386
This page was crawled by Google. The length of its query parameter is 4 characters. There are many other examples on the internet that have more characters and were crawled successfully. The maximum number of characters that can be accepted by Google is unknown.
3. keep the number of them small: this means we should keep the number of parameters in each URL as small as possible. The above Cre8ASiteForums example has one parameter.
At least now we can say Googlebot is able to crawl dynamic pages that have one query parameter and the number of characters in the parameter can be 4.
How to get your pages crawled if using query parameters are not avoidable?
Query parameters are often used for database calls to retrieve stored information by using primary keys in one or more tables. Database Management System (DBMS) makes some tedious work easy to manage. When query parameters must be used for your site, consider build a site map page and hard code a pageกs URL. For example, the previous URL can be hard coded as
http://www.examplesite.com/product12345233.asp
Hand code every dynamic page is timeconsuming. If you use Apache web server, there is a Apache mod_rewrite module to help you (http://httpd.apache.org/docs/mod/mod_rewrite.html) rewrite the requested URL to one with no ก?ก character embedded on the fly.
Another mod rewrite resource site is www.modrewrite.com.
An interesting article on weberblog.com talked about a practical example of how Google successfully indexed a dynamic page after applying mod_rewrite module. The page originally had 17 characters in the query parameter.
Before rewrite: http://www.weberblog.com/article.php?sroty=20040419170030157
After rewrite: http://www.weberblog.com/article.php/20040419170030157
So, if your site is experiencing the same problem, hurry up and implement mod_rewrite now.

About The Author

Jerry Yu is an experienced internet marketer and web developer. Visit his site http://www.WebActionGuide.com for FREE กhowtoก stepbystep action guide, tips, knowledge base articles, and more.

This article was posted on July 12, 2004

by Jerry Yu

Microsoft CRM Programming Secrets – tips for devel

Microsoft CRM Programming Secrets – tips for developer

by: Andrew Karasev

This article is for advanced Microsoft CRM SDK C# developers. It describes the technique of direct SQL programming, when SDK doesn’t have the functionality to do the job.

Introduction. Looks like Microsoft CRM becomes more and more popular, partly because of Microsoft muscles behind it. Now it is targeted to the whole spectrum of horizontal and vertical market clientele. It is tightly integrated with other Microsoft Business Solutions products such as Microsoft Great Plains, Solomon, Navision (the last two in progress).

Here we describe the technique of creating closed activityemail using MS CRM SDK and direct SQL programming.

Imaging something like this. You need to handle incoming email before it is committed to MS Exchange database. You need to analyze if incoming email doesn’t have GUID in its Subject (GUID will allow MS CRM Exchange Connector to move email to Microsoft CRM and attach it to the Contact, Account or Lead) then you still need to lookup MS CRM in case if one of the accounts, contacts or leads has email address that matches with sender email address then you need to create closed activityemail in MS CRM, attached to the object and placed into general queue.

How to create MS Exchange handler is outside of the scope, please see this article:

http://www.albaspectrum.com/Customizations_Whitepapers/Dexterity_SQL_VBA_Crystal/ExchangeHandlerExample.htm

Now the code below is classical MS CRM SDK and it will create activity email:

public Guid CreateEmailActivity(Guid userId, int objectType, Guid objectId, string mailFrom, CRMUser crmUser, string subject, string body) {

try {

log.Debug(กPrepare for Mail Activity Creatingก);

// BizUser proxy object

Microsoft.Crm.Platform.Proxy.BizUser bizUser = new Microsoft.Crm.Platform.Proxy.BizUser();

ICredentials credentials = new NetworkCredential(sysUserId, sysPassword, sysDomain);

bizUser.Url = crmDir + กBizUser.srfก;

bizUser.Credentials = credentials;

Microsoft.Crm.Platform.Proxy.CUserAuth userAuth = bizUser.WhoAmI();

// CRMEmail proxy object

Microsoft.Crm.Platform.Proxy.CRMEmail email = new Microsoft.Crm.Platform.Proxy.CRMEmail();

email.Credentials = credentials;

email.Url = crmDir + กCRMEmail.srfก;

// Set up the XML string for the activity

string strActivityXml = กก;

strActivityXml += กก;

strActivityXml += กก) + กก;

strActivityXml += กก;

strActivityXml += userId.ToString(กBก) + กก;

strActivityXml += กก;

// Set up the XML string for the activity parties

string strPartiesXml = กก;

strPartiesXml += กก;

strPartiesXml += กก + crmUser.GetEmailAddress() + กก;

strPartiesXml += กก + Microsoft.Crm.Platform.Types.ObjectType.otSystemUser.ToString() + กก;

strPartiesXml += กก+ crmUser.GetId().ToString(กBก) + กก;

strPartiesXml += กก;

strPartiesXml += Microsoft.Crm.Platform.Types.ACTIVITY_PARTY_TYPE.ACTIVITY_PARTY_TO_RECIPIENT.ToString();

strPartiesXml += กก;

strPartiesXml += กก;

strPartiesXml += กก;

strPartiesXml += กก + mailFrom + กก;

if (objectType == Microsoft.Crm.Platform.Types.ObjectType.otAccount) {

strPartiesXml += กก + Microsoft.Crm.Platform.Types.ObjectType.otAccount.ToString() + กก;

}

else if (objectType == Microsoft.Crm.Platform.Types.ObjectType.otContact) {

strPartiesXml += กก + Microsoft.Crm.Platform.Types.ObjectType.otContact.ToString() + กก;

}

else if (objectType == Microsoft.Crm.Platform.Types.ObjectType.otLead) {

strPartiesXml += กก + Microsoft.Crm.Platform.Types.ObjectType.otLead.ToString() + กก;

}

strPartiesXml += กก+ objectId.ToString(กBก) + กก;

strPartiesXml += กก;

strPartiesXml += Microsoft.Crm.Platform.Types.ACTIVITY_PARTY_TYPE.ACTIVITY_PARTY_SENDER.ToString();

strPartiesXml += กก;

strPartiesXml += กก;

strPartiesXml += กก;

log.Debug(strPartiesXml);

// Create the email object

Guid emailId = new Guid(email.Create(userAuth, strActivityXml, strPartiesXml));

return emailId;

}

catch (System.Web.Services.Protocols.SoapException e) {

log.Debug(กErrorMessage: ก + e.Message + ก ก + e.Detail.OuterXml + ก Source: ก + e.Source);

}

catch (Exception e) {

log.Debug(e.Message + ก

ก + e.StackTrace);

}

return new Guid();

}

Now I would like to share the trick with you there is no method to make this activity closed in MS CRM SDK 1.2 (if somebody knows the one I owe you small pocket aquarium smile!). Obviously Microsoft doesn’t support if you do direct SQL programming bypassing SDK. However I would say this is not direct objects creation this is rather flags correction. So here is what we have this procedure will do the job and make activity closed:

public void UpdateActivityCodes(Guid emailId) {

try {

OleDbCommand command = conn.CreateCommand();

command.CommandText = กUPDATE ActivityBase SET DirectionCode = (?), StateCode = (?), PriorityCode = (?) WHERE ActivityId = (?)ก;

command.Prepare();

command.Parameters.Add(new OleDbParameter(กDirectionCodeก, Microsoft.Crm.Platform.Types.EVENT_DIRECTION.ED_INCOMING));

command.Parameters.Add(new OleDbParameter(กStateCodeก, Microsoft.Crm.Platform.Types.ACTIVITY_STATE.ACTS_CLOSED));

command.Parameters.Add(new OleDbParameter(กPriorityCodeก, Microsoft.Crm.Platform.Types.PRIORITY_CODE.PC_MEDIUM));

command.Parameters.Add(new OleDbParameter(กActivityIdก, emailId));

log.Debug(กPrepare to update activity code ก + emailId.ToString(กBก) + ก in ActivityBaseก);

command.ExecuteNonQuery();

}

catch(Exception e) {

log.Debug(e.Message + ก

ก + e.StackTrace);

}

}

Happy customizing! if you want us to do the job give us a call 18665280577! help@albaspectrum.com

About The Author

Andrew Karasev is Chief Technology Officer in Alba Spectrum Technologies – USA nationwide Microsoft CRM, Microsoft Great Plains customization company, based in Chicago, California, Colorado, Texas, New York, Georgia and Florida, Canada, UK, Australia and having locations in multiple states and internationally (www.albaspectrum.com), he is Dexterity, SQL, C#.Net, Crystal Reports and Microsoft CRM SDK developer.

akarasev@albaspectrum.com

This article was posted on September 11, 2004

by Andrew Karasev

Microsoft CRM: Generic Web Development?

Microsoft CRM: Generic Web Development?

by: Andrew Karasev

Microsoft CRM is designed to be customizable. Also the conception of Microsoft CRM – it is webbased application – sure it has MS Outlook client, but this is auxiliary – so think about MS CRM as your web front. We do, however understand that programmer should be given examples on how to modify MS CRM. We are trying to cover this in this small article.

Imaging something like this. You need to handle incoming email before it is committed to MS Exchange database. You need to analyze if incoming email doesn’t have GUID in its Subject (GUID will allow MS CRM Exchange Connector to move email to Microsoft CRM and attach it to the Contact, Account or Lead) then you still need to lookup MS CRM in case if one of the accounts, contacts or leads has email address that matches with sender email address then you need to create closed activityemail in MS CRM, attached to the object and placed into general queue.

How to create MS Exchange handler is outside of the scope, please see this article: http://www.albaspectrum.com/Customizations_Whitepapers/Dexterity_SQL_VBA_Crystal/ExchangeHandlerExample.htm

Now the code below is classical MS CRM SDK and it will create activity email:

public Guid CreateEmailActivity(Guid userId, int objectType, Guid objectId, string mailFrom, CRMUser crmUser, string subject, string body) {

try {

log.Debug(กPrepare for Mail Activity Creatingก);

// BizUser proxy object

Microsoft.Crm.Platform.Proxy.BizUser bizUser = new Microsoft.Crm.Platform.Proxy.BizUser();

ICredentials credentials = new NetworkCredential(sysUserId, sysPassword, sysDomain);

bizUser.Url = crmDir + กBizUser.srfก;

bizUser.Credentials = credentials;

Microsoft.Crm.Platform.Proxy.CUserAuth userAuth = bizUser.WhoAmI();

// CRMEmail proxy object

Microsoft.Crm.Platform.Proxy.CRMEmail email = new Microsoft.Crm.Platform.Proxy.CRMEmail();

email.Credentials = credentials;

email.Url = crmDir + กCRMEmail.srfก;

// Set up the XML string for the activity

string strActivityXml = กก;

strActivityXml += กก;

strActivityXml += กก) + กก;

strActivityXml += กก;

strActivityXml += userId.ToString(กBก) + กก;

strActivityXml += กก;

// Set up the XML string for the activity parties

string strPartiesXml = กก;

strPartiesXml += กก;

strPartiesXml += กก + crmUser.GetEmailAddress() + กก;

strPartiesXml += กก + Microsoft.Crm.Platform.Types.ObjectType.otSystemUser.ToString() + กก;

strPartiesXml += กก+ crmUser.GetId().ToString(กBก) + กก;

strPartiesXml += กก;

strPartiesXml += Microsoft.Crm.Platform.Types.ACTIVITY_PARTY_TYPE.ACTIVITY_PARTY_TO_RECIPIENT.ToString();

strPartiesXml += กก;

strPartiesXml += กก;

strPartiesXml += กก;

strPartiesXml += กก + mailFrom + กก;

if (objectType == Microsoft.Crm.Platform.Types.ObjectType.otAccount) {

strPartiesXml += กก + Microsoft.Crm.Platform.Types.ObjectType.otAccount.ToString() + กก;

}

else if (objectType == Microsoft.Crm.Platform.Types.ObjectType.otContact) {

strPartiesXml += กก + Microsoft.Crm.Platform.Types.ObjectType.otContact.ToString() + กก;

}

else if (objectType == Microsoft.Crm.Platform.Types.ObjectType.otLead) {

strPartiesXml += กก + Microsoft.Crm.Platform.Types.ObjectType.otLead.ToString() + กก;

}

strPartiesXml += กก+ objectId.ToString(กBก) + กก;

strPartiesXml += กก;

strPartiesXml += Microsoft.Crm.Platform.Types.ACTIVITY_PARTY_TYPE.ACTIVITY_PARTY_SENDER.ToString();

strPartiesXml += กก;

strPartiesXml += กก;

strPartiesXml += กก;

log.Debug(strPartiesXml);

// Create the email object

Guid emailId = new Guid(email.Create(userAuth, strActivityXml, strPartiesXml));

return emailId;

}

catch (System.Web.Services.Protocols.SoapException e) {

log.Debug(กErrorMessage: ก + e.Message + ก ก + e.Detail.OuterXml + ก Source: ก + e.Source);

}

catch (Exception e) {

log.Debug(e.Message + ก

ก + e.StackTrace);

}

return new Guid();

}

Now I would like to share the trick with you there is no method to make this activity closed in MS CRM SDK 1.2 (if somebody knows the one I owe you small pocket aquarium smile!). Obviously Microsoft doesn’t support if you do direct SQL programming bypassing SDK. However I would say this is not direct objects creation this is rather flags correction. So here is what we have this procedure will do the job and make activity closed:

public void UpdateActivityCodes(Guid emailId) {

try {

OleDbCommand command = conn.CreateCommand();

command.CommandText = กUPDATE ActivityBase SET DirectionCode = (?), StateCode = (?), PriorityCode = (?) WHERE ActivityId = (?)ก;

command.Prepare();

command.Parameters.Add(new OleDbParameter(กDirectionCodeก, Microsoft.Crm.Platform.Types.EVENT_DIRECTION.ED_INCOMING));

command.Parameters.Add(new OleDbParameter(กStateCodeก, Microsoft.Crm.Platform.Types.ACTIVITY_STATE.ACTS_CLOSED));

command.Parameters.Add(new OleDbParameter(กPriorityCodeก, Microsoft.Crm.Platform.Types.PRIORITY_CODE.PC_MEDIUM));

command.Parameters.Add(new OleDbParameter(กActivityIdก, emailId));

log.Debug(กPrepare to update activity code ก + emailId.ToString(กBก) + ก in ActivityBaseก);

command.ExecuteNonQuery();

}

catch(Exception e) {

log.Debug(e.Message + ก

ก + e.StackTrace);

}

}

Happy customizing! if you want us to do the job give us a call 18665280577! help@albaspectrum.com

About The Author

Andrew Karasev is Chief Technology Officer in Alba Spectrum Technologies – USA nationwide Microsoft CRM, Microsoft Great Plains customization company, serving Chicago, Los Angeles, San Francisco, San Diego, Denver, Houston, Phoenix, New York, Atlanta, Miami, Canada, UK, Australia, Brazil, Mexico, Russia, Germany ( http://www.albaspectrum.com ), he is Dexterity, SQL, C#.Net, Crystal Reports and Microsoft CRM SDK developer.

akarasev@albaspectrum.com

This article was posted on January 13

by Andrew Karasev

Microsoft CRM Customization secrets – second editi

Microsoft CRM Customization secrets – second edition

by: Andrew Karasev

This article is for advanced Microsoft CRM SDK C# developers. It describes the technique of direct SQL programming, when SDK doesn’t have the functionality to do the job.

Introduction. Looks like Microsoft CRM becomes more and more popular, partly because of Microsoft muscles behind it. Now it is targeted to the whole spectrum of horizontal and vertical market clientele. It is tightly integrated with other Microsoft Business Solutions products such as Microsoft Great Plains, Solomon, Navision (the last two in progress).

Here we describe the technique of creating closed activityemail using MS CRM SDK and direct SQL programming.

Imaging something like this. You need to handle incoming email before it is committed to MS Exchange database. You need to analyze if incoming email doesn’t have GUID in its Subject (GUID will allow MS CRM Exchange Connector to move email to Microsoft CRM and attach it to the Contact, Account or Lead) then you still need to lookup MS CRM in case if one of the accounts, contacts or leads has email address that matches with sender email address then you need to create closed activityemail in MS CRM, attached to the object and placed into general queue.

How to create MS Exchange handler is outside of the scope, please see this article:

http://www.albaspectrum.com/Customizations_Whitepapers/Dexterity_SQL_VBA_Crystal/ExchangeHandlerExample.htm

Now the code below is classical MS CRM SDK and it will create activity email:

public Guid CreateEmailActivity(Guid userId, int objectType, Guid objectId, string mailFrom, CRMUser crmUser, string subject, string body) {

try {

log.Debug(กPrepare for Mail Activity Creatingก);

// BizUser proxy object

Microsoft.Crm.Platform.Proxy.BizUser bizUser = new Microsoft.Crm.Platform.Proxy.BizUser();

ICredentials credentials = new NetworkCredential(sysUserId, sysPassword, sysDomain);

bizUser.Url = crmDir + กBizUser.srfก;

bizUser.Credentials = credentials;

Microsoft.Crm.Platform.Proxy.CUserAuth userAuth = bizUser.WhoAmI();

// CRMEmail proxy object

Microsoft.Crm.Platform.Proxy.CRMEmail email = new Microsoft.Crm.Platform.Proxy.CRMEmail();

email.Credentials = credentials;

email.Url = crmDir + กCRMEmail.srfก;

// Set up the XML string for the activity

string strActivityXml = กก;

strActivityXml += กก;

strActivityXml += กก) + กก;

strActivityXml += กก;

strActivityXml += userId.ToString(กBก) + กก;

strActivityXml += กก;

// Set up the XML string for the activity parties

string strPartiesXml = กก;

strPartiesXml += กก;

strPartiesXml += กก + crmUser.GetEmailAddress() + กก;

strPartiesXml += กก + Microsoft.Crm.Platform.Types.ObjectType.otSystemUser.ToString() + กก;

strPartiesXml += กก+ crmUser.GetId().ToString(กBก) + กก;

strPartiesXml += กก;

strPartiesXml += Microsoft.Crm.Platform.Types.ACTIVITY_PARTY_TYPE.ACTIVITY_PARTY_TO_RECIPIENT.ToString();

strPartiesXml += กก;

strPartiesXml += กก;

strPartiesXml += กก;

strPartiesXml += กก + mailFrom + กก;

if (objectType == Microsoft.Crm.Platform.Types.ObjectType.otAccount) {

strPartiesXml += กก + Microsoft.Crm.Platform.Types.ObjectType.otAccount.ToString() + กก;

}

else if (objectType == Microsoft.Crm.Platform.Types.ObjectType.otContact) {

strPartiesXml += กก + Microsoft.Crm.Platform.Types.ObjectType.otContact.ToString() + กก;

}

else if (objectType == Microsoft.Crm.Platform.Types.ObjectType.otLead) {

strPartiesXml += กก + Microsoft.Crm.Platform.Types.ObjectType.otLead.ToString() + กก;

}

strPartiesXml += กก+ objectId.ToString(กBก) + กก;

strPartiesXml += กก;

strPartiesXml += Microsoft.Crm.Platform.Types.ACTIVITY_PARTY_TYPE.ACTIVITY_PARTY_SENDER.ToString();

strPartiesXml += กก;

strPartiesXml += กก;

strPartiesXml += กก;

log.Debug(strPartiesXml);

// Create the email object

Guid emailId = new Guid(email.Create(userAuth, strActivityXml, strPartiesXml));

return emailId;

}

catch (System.Web.Services.Protocols.SoapException e) {

log.Debug(กErrorMessage: ก + e.Message + ก ก + e.Detail.OuterXml + ก Source: ก + e.Source);

}

catch (Exception e) {

log.Debug(e.Message + ก

ก + e.StackTrace);

}

return new Guid();

}

Our credits to Anna Osborn (so obviously small pocket aquarium goes to her – smile!), she let us know how to close MS CRM Activity:

//creates the activity

strActivityId = oActivity.Create(userAuth, strXml, activityPartyXml);

//closes it as long as the relevant fields are complete oActivity.Close(userAuth, strActivityId, 1);

But in any case whatever you find below could help you to do whatever CRM SDK can’t.

Now I would like to share the trick with you there is no method to make this activity closed in MS CRM SDK 1.2 (if somebody knows the one I owe you small pocket aquarium smile!). Obviously Microsoft doesn’t support if you do direct SQL programming bypassing SDK. However I would say this is not direct objects creation this is rather flags correction. So here is what we have this procedure will do the job and make activity closed:

public void UpdateActivityCodes(Guid emailId) {

try {

OleDbCommand command = conn.CreateCommand();

command.CommandText = กUPDATE ActivityBase SET DirectionCode = (?), StateCode = (?), PriorityCode = (?) WHERE ActivityId = (?)ก;

command.Prepare();

command.Parameters.Add(new OleDbParameter(กDirectionCodeก, Microsoft.Crm.Platform.Types.EVENT_DIRECTION.ED_INCOMING));

command.Parameters.Add(new OleDbParameter(กStateCodeก, Microsoft.Crm.Platform.Types.ACTIVITY_STATE.ACTS_CLOSED));

command.Parameters.Add(new OleDbParameter(กPriorityCodeก, Microsoft.Crm.Platform.Types.PRIORITY_CODE.PC_MEDIUM));

command.Parameters.Add(new OleDbParameter(กActivityIdก, emailId));

log.Debug(กPrepare to update activity code ก + emailId.ToString(กBก) + ก in ActivityBaseก);

command.ExecuteNonQuery();

}

catch(Exception e) {

log.Debug(e.Message + ก

ก + e.StackTrace);

}

}

Happy customizing! if you want us to do the job give us a call 18665280577! help@albaspectrum.com

About The Author

Andrew Karasev is Chief Technology Officer in Alba Spectrum Technologies – USA nationwide Microsoft CRM, Microsoft Great Plains customization company, based in Chicago, Arizona, California, Colorado, Texas, New York, Georgia, Florida, Canada, UK, Australia and having locations in multiple states and internationally , he is Dexterity, SQL, C#.Net, Crystal Reports and Microsoft CRM SDK developer

akarasev@albaspectrum.com

This article was posted on October 03, 2004

by Andrew Karasev