Showing posts with label email. Show all posts
Showing posts with label email. Show all posts

Sunday, February 05, 2017

Emailing Queues internally - OrgDBOrg to the rescue

Using queues is in D365/CRM for managing functional email addresses is the the only way to go as
far as I know, unless you want to set it up as a full user, which I don't really see the point of.

I recently ran into an interesting issue with a customer pertaining to queues and that is when you want to be able to forward mails internally to users that are registered in D365/CRM. What happens is that with the standard setting you will get two emails. Hence, you might think that going into System settings and the email tab and unchecking the "Track emails sent between CRM users as two activities". However, this will have the unpleasant effect of disabling internal emails to queues, or in other words, if an internal user sends an email to a queue, to a system with this setting unchecked, D365/CRM will simply ignore the mail and not pull it into the D365/CRM.
By RRZE - Own work, CC BY-SA 3.0, Link

So, do we have to choose between duplicate emails for internal users and being able to send emails from internal users or not getting duplicates and no emails from internal users? Well, no, there is a very special set of settings to the rescue, OrgDBOrg, which are described here: https://support.microsoft.com/en-us/help/2691237/orgdborgsettings-tool-for-microsoft-dynamics-crm

There is a setting here called: DoNotIgnoreInternalEmailToQueues which by default is set to False. So, if you uncheck the "Track email sent between to activities" and then set this to True, the system will not ignore your internal emails.

A small word of caution, OrgDBOrg settings are fringe (but still supported) settings which hence are probable not as tested as normal settings in D365. I would hence recommend that you only use OrgDBOrg setting in the case you need very specifically them.

Gustaf Westerlund
MVP, Founder and CTO at CRM-konsulterna AB
www.crmkonsulterna.se

Wednesday, January 18, 2017

Warnings mean something - don't just click them away


Warnings like the one you see above, I often see in my customers systems when rudely looking over their shoulders. And what do they do? Call support and tell them that there is some weird error about email coming up and that there must be some error in the CRM-Exchange inter-server email synchronization mechanism? No. They don't. They ignore it. Totally. Every time. They typically get a bit annoyed every time and think the system is a bit crappy but they ignore it. And we as their CRM-partner might never know that there is anything wrong unless we have very deep monitoring of their system (has anyone built this? Would be a great tool! Tanguy to the rescue perhaps?)

Well, as you guessed I don't agree that you should just click away these error messages or actually any error messages. They usually mean something. In the case above, there is something wrong with the synchronization of emails, why emails that have be written and sent in CRM have not been delivered. Once fixed, these WILL be sent, which might be a bit problematic. Once, maybe 6 or 7 years ago, we had a customer who had had problems with synchronization of emails and hadn't told us. We got to know during our summer vacation (don't you always), and when we fixed it, the CRM system sent out loads of old emails to their customers. Which was not really appreciated. Well, we all do misstakes, but not all learn from them. So, do check which emails have Status Reason"Pending Send" as you can see in the picture below.


Having emails with this status for more than 24 hours is also what causes the alert at the top of this post. So, before fixing Server Side Sync, the Email Router or installing Outlook clients, do check this list to make sure that there are not a lot of old emails that will be sent to your customers and contacts. Advanced Find is very useful if you want to find them all, and not use the built in view that I am showing above.

Gustaf Westerlund
MVP, Founder and CTO at CRM-konsulterna AB
www.crmkonsulterna.se

Friday, August 14, 2015

Queue question and the difference between community work and putting food on the table

I received a question per email today and as I Work as a Consultant, Selling my time by the hour, while at the same time sharing my knowledge and experience on this blog and in Other places, I thought I might share my general view on how I separate the Community Work from the Work that puts food on my table.

I am a strong believer in the notion that we need to share knowledge with each other to be able to all grow and be stronger. This is why I started the blog, started CRM User Group Sweden, run Techie After Work (with Allan Varcoe and Peter Björkmarker), present at Conferences where I do not get paid for speaking. If we all do this in the Dynamics CRM Community, it will grow large, new people will quickly learn from the more experienced, and our CRM system, will prosper to all our benefit.

We all have to put food on the table
But, I also have to put food on the table, so when people ask me to help them by contacting me by
email or phone, they do actual ask me as a Consultant and I can and will charge for the time I help out. Typically an agreement, including NDA, is signed so that I can help out in a more direct manner, which of course, is different than somebody asking something general in the comment on a blog post.

So, if you have a question to me, regarding a post, I recommend leaving a comment. Sadly, there are a lot of comment spammers out there, looking for some links to their sites, why I need to moderate all comments, as I respect you as readers and I do not want to waste your time with crap comments and irrelevant links to companies trying to sell training or otherwise.

So, on to the question I got, as it was clearly directed as a comment, will answer it in the form of a blog post instead of an email reply, so that others in the Community can also benefit from it.

"I was reading your blog post on sending emails from a queue (http://gustafwesterlund.blogspot.com/2013/02/sending-emails-from-queue-with-email.html) and had a question.  I’m using CRM 2015 and trying to set up a queue for sending and I was wondering if the generic address needs to point to a mailbox on the server or if it can be a distribution list or mail-enabled public folder.  I’ve tried setting up an existing distribution list address for the email address, but I get errors because it can’t log on to a mailbox, so I didn’t know if it was possible or if there’s something else I need to do instead."

It is a good question. It is not obvious why you cannot use one type of email address or Another, but if you refer to the implementation guide (yes, I know, it is a very large document(s) and hard to navigate, but try to find your way around it) you will see that it says that the email address that you indicate in a queue has to be a user mailbox. It cannot be anything else. There are several different ways of logging in to this, the simplest is to set the credentials in the queue, but this will require you to change the password in the queue every time you change it in the AD. I wrote the Synchronization overview chapter in the CRM Field Guide (http://gustafwesterlund.blogspot.se/2015/04/the-crm-2013-field-guide-is-out.html) and I would strongly recommend that you read this or the similar parts in the implementation guide for more detailed information.

Gustaf Westerlund
MVP, Founder and CTO at CRM-konsulterna AB
www.crmkonsulterna.se

Monday, May 18, 2015

Be aware of Synchronous Workflows on incoming emails and Queue items

How synchronous workflows that fail, make emails disappear.

During the last few Days I have been having the not so pleasant experience of trying to find some really nasty errors in incoming emails to a queue in CRM. We are using CRM 2013 SP1 (on prem) and hence are using the Server Side Sync. Everything had been working great and we had developed some neat workflows that did some magic to convert emails to cases (as those features were not available, and not good enough either) when we develop our stuff.

Well, thing stopped working, I tried sending emails to the CRM server, but none were received in CRM. All I got in CRM was a not so descriptive general alert saying:

"An error occurred while creating incoming email in Microsoft Dynamics CRM for the mailbox XYZ. To view the email that failed, see the alerts in the mailbox record."

and in the mailbox:
"An error occurred while creating the incoming email "Test 1512" in Microsoft Dynamics CRM for the mailbox XYZ."

As I am working on my telepathic abilities, I have not yet reached a level where I can understand what is wrong so I had a look in the trace, and I was very happy I was running an on-prem server. It is a bit long, don't worry if you don't understand it all, nobody (I think) does.

[2015-05-15 15:21:13.459] Process:CrmAsyncService |Organization:673c5996-a1fa-e311-93ed-00155d0a831d |Thread:    4 |Category: Platform.Metadata |User: 00000000-0000-0000-0000-000000000000 |Level: Error |ReqId:  | <>c__DisplayClass1.<LoadMetadataContainerFromDatabase>b__0  ilOffset = 0x14
>Multi-org sharable cache loading system and non-system metadata with build number 6.1.0.581 and language 1033
[2015-05-15 15:33:45.132] Process:CrmAsyncService |Organization:00000000-0000-0000-0000-000000000000 |Thread:   26 |Category: Exception |User: 00000000-0000-0000-0000-000000000000 |Level: Error |ReqId: cf367175-12a2-4719-a5af-f53f7f254399 | CrmException..ctor  ilOffset = 0x7
 at CrmException..ctor(String message, Exception innerException, Int32 errorCode, Boolean isFlowControlException)  ilOffset = 0x7
 at CrmException..ctor(String message, Exception innerException, Int32 errorCode)  ilOffset = 0x5
 at Exceptions.ThrowIfGuidEmpty(Guid parameter, String name)  ilOffset = 0x18
 at OrganizationSdkServiceInternal.Retrieve(String entityName, Guid id, ColumnSet columnSet, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType, Boolean checkAdminMode)  ilOffset = 0x16
 at InprocessServiceProxy.RetrieveCore(String entityName, Guid id, ColumnSet columnSet)  ilOffset = 0x28
 at OrganizationServiceProxy.Retrieve(String entityName, Guid id, ColumnSet columnSet)  ilOffset = 0x4
 at EntityDictionary.TryRetrieveEntity(String key)  ilOffset = 0xF8
 at EntityDictionary.System.Collections.Generic.IDictionary<System.String,Microsoft.Xrm.Sdk.Entity>.get_Item(String key)  ilOffset = 0x1B
 at VisualBasicValue`1.Execute(CodeActivityContext context)  ilOffset = 0x3A
 at ActivityExecutor.ExecuteInResolutionContext(ActivityInstance parentInstance, Activity`1 expressionActivity)  ilOffset = 0x35
 at InArgument`1.TryPopulateValue(LocationEnvironment targetEnvironment, ActivityInstance activityInstance, ActivityExecutor executor)  ilOffset = 0x2F
 at ActivityInstance.InternalTryPopulateArgumentValueOrScheduleExpression(RuntimeArgument argument, Int32 nextArgumentIndex, ActivityExecutor executor, IDictionary`2 argumentValueOverrides, Location resultLocation, Boolean isDynamicUpdate)  ilOffset = 0x16
 at ActivityInstance.ResolveArguments(ActivityExecutor executor, IDictionary`2 argumentValueOverrides, Location resultLocation, Int32 startIndex)  ilOffset = 0x9C
 at ExecuteActivityWorkItem.ExecuteBody(ActivityExecutor executor, BookmarkManager bookmarkManager, Location resultLocation)  ilOffset = 0x1C
 at ActivityExecutor.OnExecuteWorkItem(WorkItem workItem)  ilOffset = 0x53
 at Callbacks.ExecuteWorkItem(WorkItem workItem)  ilOffset = 0xD
 at Scheduler.OnScheduledWork(Object state)  ilOffset = 0xC5
 at SendOrPostThunk.UnhandledExceptionFrame(Object state)  ilOffset = 0x0
 at PumpBasedSynchronizationContext.DoPump()  ilOffset = 0x2E
 at WorkflowApplication.Invoke(Activity activity, IDictionary`2 inputs, WorkflowInstanceExtensionManager extensions, TimeSpan timeout)  ilOffset = 0x23
 at WorkflowInvoker.Invoke(Activity workflow, IDictionary`2 inputs, TimeSpan timeout, WorkflowInstanceExtensionManager extensions)  ilOffset = 0x36
 at SynchronousWorkflowActivityHost.ExecuteWorkflowUsingInvoker(Activity workflow, ICommonWorkflowContext context)  ilOffset = 0xD0
 at SynchronousWorkflowActivityHost.StartWorkflow(WorkflowActivationData activationData, ICommonWorkflowContext context)  ilOffset = 0x73
 at SynchronousWorkflowActivityHost.StartWorkflow(ICommonWorkflowContext context)  ilOffset = 0xBA
 at WorkflowProcessServiceInternalHandler`1.ExecuteSyncWorkflow(Guid workflowId, PipelineExecutionContext pipelineContext, IGenericEventData workflowInstanceData, Boolean isTriggered)  ilOffset = 0x59
 at WorkflowProcessServiceInternalHandler`1.ExecuteTriggeredSyncWorkflow(Guid workflowId, PipelineExecutionContext pipelineContext)  ilOffset = 0x21
 at SyncWorkflowExecutionPlugin.Execute(IServiceProvider provider)  ilOffset = 0x2C
 at V5PluginProxyStep.ExecuteInternal(PipelineExecutionContext context)  ilOffset = 0x2A3
 at VersionedPluginProxyStepBase.Execute(PipelineExecutionContext context)  ilOffset = 0x65
 at Pipeline.Execute(PipelineExecutionContext context)  ilOffset = 0x65
 at MessageProcessor.Execute(PipelineExecutionContext context)  ilOffset = 0x1FB
 at InternalMessageDispatcher.Execute(PipelineExecutionContext context)  ilOffset = 0xE4
 at ExtensiblePlatformMessageDispatcher.Execute(PipelineExecutionContext pluginContext)  ilOffset = 0x0
 at ExtensiblePlatformMessageDispatcher.CreateWithInvocationSource(BusinessEntity entity, Int32 invocationSource, ExecutionContext context)  ilOffset = 0xB4
 at BusinessProcessObject.Create(IBusinessEntity entity, ExecutionContext context)  ilOffset = 0x54
 at GenericActivityServiceBase.Create(IBusinessEntity entity, ExecutionContext context)  ilOffset = 0xA1
 at CommunicationActivityServiceBase.Create(IBusinessEntity entity, ExecutionContext context)  ilOffset = 0x1A
 at EmailService.SetRecipientsAddAdditionalAttributeAndCreate(AddressEntry[][] allResolvedAddressEntries, Email email, Entity emailDeltaEntity, String traceSubject, ExecutionContext context)  ilOffset = 0x1DA
 at EmailService.Deliver(Boolean userPromote, Guid emailId, String messageId, String subject, String from, String to, String cc, String bcc, DateTime receivedOn, String submittedBy, String importance, String body, BusinessEntityCollection attachments, Guid campaignResponseId, Entity emailDeltaEntity, ExecutionContext context, Boolean validateBeforeDeliver)  ilOffset = 0x524
 at EmailService.DeliverIncoming(String messageId, String subject, String from, String to, String cc, String bcc, DateTime receivedOn, String submittedBy, String importance, String body, BusinessEntityCollection attachments, Entity extraProperties, Boolean validateBeforeCreate, ExecutionContext context)  ilOffset = 0xB8
 at RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)  ilOffset = 0xFFFFFFFF
 at RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)  ilOffset = 0x25
 at RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)  ilOffset = 0xCF
 at LogicalMethodInfo.Invoke(Object target, Object[] values)  ilOffset = 0x4F
 at InternalOperationPlugin.Execute(IServiceProvider serviceProvider)  ilOffset = 0x57
 at V5PluginProxyStep.ExecuteInternal(PipelineExecutionContext context)  ilOffset = 0x200
 at VersionedPluginProxyStepBase.Execute(PipelineExecutionContext context)  ilOffset = 0x65
 at Pipeline.Execute(PipelineExecutionContext context)  ilOffset = 0x65
 at MessageProcessor.Execute(PipelineExecutionContext context)  ilOffset = 0x1C5
 at InternalMessageDispatcher.Execute(PipelineExecutionContext context)  ilOffset = 0xE4
 at ExternalMessageDispatcher.ExecuteInternal(IInProcessOrganizationServiceFactory serviceFactory, IPlatformMessageDispatcherFactory dispatcherFactory, String messageName, String requestName, Int32 primaryObjectTypeCode, Int32 secondaryObjectTypeCode, ParameterCollection fields, CorrelationToken correlationToken, CallerOriginToken originToken, UserAuth userAuth, Guid callerId, Guid transactionContextId, Int32 invocationSource, Nullable`1 requestId, Version endpointVersion)  ilOffset = 0x16E
 at OrganizationSdkServiceInternal.ExecuteRequest(OrganizationRequest request, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType, UserAuth userAuth, Guid targetUserId, OrganizationContext context, Boolean returnResponse, Boolean checkAdminMode)  ilOffset = 0x1F1
 at OrganizationSdkServiceInternal.ExecuteRequest(OrganizationRequest request, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType, Boolean checkAdminMode)  ilOffset = 0x2D
 at OrganizationSdkServiceInternal.Execute(OrganizationRequest request, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType, Boolean checkAdminMode)  ilOffset = 0x26
 at InprocessServiceProxy.ExecuteCore(OrganizationRequest request)  ilOffset = 0x34
 at IncomingEmailProviderBase.DeliverMessageInternal(EmailMessage emailMessage, Boolean validateBeforeCreate)  ilOffset = 0x1B7
 at IncomingEmailProviderBase.DeliverMessage(EmailMessage emailMessage, Boolean validateBeforeCreate)  ilOffset = 0x19
 at GetItemsStep.ProcessResponse()  ilOffset = 0x5AB
 at ExchangeIncomingEmailProviderStep.EndOperation()  ilOffset = 0xFC
 at ExchangeIncomingEmailProvider.ReceiveEmails()  ilOffset = 0x92
 at IncomingActivityProviderBase.Run()  ilOffset = 0x42
 at MailboxEmailOperation.PerformOperation()  ilOffset = 0x2C
 at MailboxOperationBase`1.Execute()  ilOffset = 0xAA
 at MailboxProcessingOperation.PerformOperation()  ilOffset = 0x1A
 at MailboxOperationBase`1.Execute()  ilOffset = 0xAA
 at MailboxOperationCommand.InternalExecute(MailboxAsyncEvent asyncEvent)  ilOffset = 0x64
 at AsyncCallbackHandler`2.ResumeExecution(IAsyncEvent asyncEvent)  ilOffset = 0x56
 at AsyncEventExecutionManager`2.ExecuteHandler(IAsyncEventHandlerFactory handlerFactory)  ilOffset = 0x8A
 at PoolHandler.ProcessAsyncEvent(IAsyncEventExecutionManager asyncEventExecutionManager)  ilOffset = 0x144
 at AsyncEventOperation.<.ctor>b__2(IServiceOperation operation)  ilOffset = 0x0
 at FaultToleranceBehavior.Execute(ServiceOperationAction operation, IServiceOperation operationParameter)  ilOffset = 0x18
 at MonitoredOperation.Execute()  ilOffset = 0xD
 at ThreadPoolQueueExecutionEngine.InvokeNextOperationInThreadPool(Object state)  ilOffset = 0xC
 at ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)  ilOffset = 0x70
 at ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)  ilOffset = 0x4
 at QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()  ilOffset = 0x30
 at ThreadPoolWorkQueue.Dispatch()  ilOffset = 0xA3
>Crm Exception: Message: Expected non-empty Guid., ErrorCode: -2147220989, InnerException: System.ArgumentException: Expected non-empty Guid.
Parameter name: id
[2015-05-15 15:33:45.304] Process:CrmAsyncService |Organization:00000000-0000-0000-0000-000000000000 |Thread:   26 |Category: Platform |User: 00000000-0000-0000-0000-000000000000 |Level: Error |ReqId: cf367175-12a2-4719-a5af-f53f7f254399 | ExceptionConverter.ConvertToFault  ilOffset = 0x69
>UNEXPECTED: no fault?


My first thought was that the stack trace was really long... and then there was some mentioning of User with Guid 00000000-0000-0000-0000-000000000000.

Another kind of queue ticket
As the Server Side Sync has something of a rep for not being the most reliable guy in Town, I wasn't really sure if this error really was an error that we had caused or if there was something wrong with the server side sync. As my perception was that we hadn't really changed any thing, I started with the recreating the mailbox, recreated the server profile, ran test and enable and that worked, but when I tried sending my own emails, from different email accounts, as you never know if there is something spooking it with a specific email address, I still never got the queue to read any emails, not even the test emails created by CRM. I was starting to get a bit short on hair by this time, so I resorted to my classical troubleshooting method of backing off as far as possible and seeing if things still were broken, and I hence deactivated all workflows and plugins that were associated to email and Queue item, and gave the user full access and I was once again awarded with this method, emails started arriving in the queue in CRM.

I then revoked admin access and started re-enabling each single workflow/plugin until thing started
breaking again. This turned out to be a painstaking process as the only way I found to test this was to send an email to CRM and then wait for about 5 minutes until it was/or was not pulled into the queue.
It took me more or less a days work just to find the two workflows that were causing the problems.

The actual problems in them selves, arn't really that interesting, it turned out that the error message above was actually quite correct, If you try to set a null-user to an owner field, CRM will respond like this.

What I did notice however was that the workflows that we were using on "queue item" in this case were synchronous (yes, yes, we do have good reasons for it, I hope you do to, Otherwise, please choose asynchronous/background workflows) and as they broke, CRM did two interesting facts that are not very desirable and noteworthy:
  • The mailbox was shut down for further email processing. It had to be "Test and Enabled" to start receiving emails again. I have yet to see a good way to do this in an automated fashion and to be able to monitor the mailboxes to see if they are working as expected.
  • The email that was the cause of the breaking of the workflow, got lost. Even after the mailbox got reactivated, it had marked this email as read and did not read it into CRM despite the fact that it was neither in the queue nor as a lone activity which might have been the case if the Creation of the queue item broke. But obviously the entire process is handled atomically.
Based on this I have the following recommendations:
  1. If possible try to avoid an synchronous logic on receiving email or Creation of queue items. Try to move logic to asynchronous as this will cause errors to be non-fatal, like the two types of effects that are hard to handle above.
  2. If you do need to have synchronous logic on the receiving of emails or Creation of queue items try to add conditions in the beginning that will ensure that the logic only runs in those very specific cases where they are supposed to. Be aware of the fact that queue items can be associated to many different entities, so don't rely on the fact that they should be only connected to something specific. At least take into consideration the fact that they will be connected to emails at some Point in time.
  3. I read an interesting fact today, that the activation of business rules Controls in which order they will be executed. If you are using CRM 2015 with server side (Entity) scope, this could probably cause similar issues if the activation is done haphazardly and causes the execution to be done in a way that can cause a bug and break processing of the queue item or email. I havn't checked if these are run pre- or poststate but I think that depends on the action.
  4. If you get errors, especially when using CRM Online, try to replicate the error in the sandbox Environment and then either move backwards to a Point where it starts working again, or deactive Everything related to emails and queue items, make sure it works, and move forward. When you know where the error is, finding what the error is, is so much easier.

We also found a related bug in CRM today, if you try to create an asynchronous workflow that triggers on a field which has field based rights activated on it, it will break, with some weird error message about not being able to change domain for the user. The simple fix for that is to make the workflow synchronous and to make it run as the user that activates it, that worked. We didn't try to run it as the user who created the workflow, as that is the same logic that is used in asynchronous workflows, I wasn't too keen on trying something that was more likely to fail. If you have tried it, please leave a comment below.

I hope to see a lot of people tomorrow on the 19:th at the Swedish CRM UG Meeting!

Gustaf Westerlund
MVP, Founder and CTO at CRM-konsulterna AB
www.crmkonsulterna.se

Tuesday, April 22, 2014

Server side Sync Trouble shooting

I have been working with a Proof-of-concept for the lates couple of Days and have been setting up the server side sync for a CRM on-premise system. First of all I would just like to share that it is a really nice new feature, I really like the fact that we now can have an option to not have to use the email router. With the new spring release, it will also be available for CRM Online, but only CRM-Online to Exchange Online (O365) not hybrid Environments (ex. CRM Online to Exchange on-premise or vice versa).

However, I did run into some issues as none of the emails that I sent to the email account connected to the queue showed up in the queue.

The Server Sync is handled by the MSCRMAsyncService and if you switch on logging in CRM (which can be done using adding the registry key "TraceEnabled" and setting it to 1 or using Power Shell)  you will get the logging of the server sync in the async tracing loggs. It turned out that I had a missmatch in email addresses which CRM apparently didn't like and you can only have one email address for a queue, but it was easily fixed once I knew the problem. I just wonder how I would troubleshoot this if I got this in CRM Online... hopefully MSFT will be adding additional logging to the server sync functionality.

Gustaf Westerlund
MVP, CEO and owner at CRM-konsulterna AB
www.crmkonsulterna.se

Saturday, May 11, 2013

Considerations of email address in registering CRM Online

When setting up CRM Online, especially when doing it on an already existing Office 365 Environment, there are some things that you need to know that might not be that evident, so I thought I might elaborate a bit on it.

First of all, the email address that is entered when setting up the Office 365 organization or the Trial organisation for CRM Online is very important as emails regarding the CRM service (and other services provisioned through the Office 365 portal) will be notified via this email address.
Swedish version of the Trial registration - Email field marked. It says "We will be sending important information to this email address"


Other users set up as administrators will also be receiving notifications on the email addresses set up as Alternate email address under Settings.


So is this a problem? If you are just using CRM Online, and the alternate email address you input is you main work email, no, this is probably not a problem. There are however other scenarios where this might be a problem;
- The Company is using Office 365 as their main work email address and the alternate email addresses are gmail/Yahoo/Hotmail addresses that are seldom checked. For some reason, the CRM service is not payed properly and warnings about the fact that it is to be shut down are sent out to these seldom check email address. Then the CRM system is deactivated for all users and nobody understand why until the users flagged as administrators in O365 (usually very few) finally check their alternate email inboxes and find the warning. Until this is fixed, several Days or weeks may pass with the system down severely damaging user acceptance and profits.
- The original admins setting up the system are no longer with the Company and their alternate email addresses were not directed to "impersonal" email addresses but to their own. When the billing is missed, the effects are similar to the case above.

So, my general recommendations in this case is to make sure that the alternate email addresses used are set with great care and to impersonal email aliases that will remain independent of people leaving the Company. They are to be aliases that are monitored at least once every second day. If using Office 365, the general recommendation is to not use Office 365 email boxes to monitor itself, but perhaps looping it to a Group alias outside which also include addresses within the O365 might be an idea as long as there are people outside the O365 in the alias as well.

Gustaf Westerlund
MVP, CEO and owner at CRM-konsulterna AB
www.crmkonsulterna.se

Wednesday, December 21, 2011

Problems with converting email to case

I was recently working with a customer when I noticed an interesting bug in CRM 2011, in the Outlook Client. When trying to convert an email to either a lead, case or opportunity directly from the Outlook ribbon, it does not set the "regarding" lookup field of the email that was tracked. However, if the email is first tracked, then "viewed in CRM" and then from the CRM email form converted to lead, case or opportunity, the regarding field is set correctly.

To make this a bit more clear I will describe this with a few screenshot below:


We'll start off with opening a received email and pressing the Track button in CRM


This will then allow us to press the convert to Opportunity, Case or Lead, directly from Outlook. A very neat, and new function. It came with CRM 2011. In this example, I am selecting Case.
 This will show a smaller dialog allowing you to select case (not shown here) and also prompting you if you want to open the case or not. I selected to open the case.
After opening the case, I checked the closed activities to see if the attached email that was I just converted to a case, but as you can see below there were none. I was a bit perplexed as I was showing this new functionality to the customer as was expecting to see the email here.
I went back to the email from Outlook and opened it in CRM and found that it had not been correctly connected to the case using the lookup "Regarding" field.

So, I tried it the old way. I sent myself another email, pressed the track in CRM button, and then instead of converting it directly from Outlook, i pressed the "View in CRM" button to open it in CRM.

I then converted it to a case from the ribbon menu from the CRM Email from by pressing the "To Case" button.
I was shown a similar small dialog letting me select subject for the case and similar and then the case form was shown. It was identical to when created from Outlook, but when checking the closed activities there was one important difference;

And by opening the CRM email form from the list shows it clearly:

The regarding field has been set properly.

This is a very unfortunate bug in CRM and I do hope Microsoft solve it quickly as the feature that CRM 2011 adds in Outlook by being able to convert emails to cases, opportunities and leads directly from the email form is very good but as all of you know who work close to sales or customer service people, their time is very precious and every click counts and new features that do not deliver as expected are always annoying to the user. So, until the bug has been fixed, make sure the users open the CRM form to convert the emails.

Update: Jukka Niiranen left a very informative comment to this posting below informing us that Microsoft probably will fix this bug in UR6 planned to be released in Jan 2012.
Gustaf Westerlund
CEO, Chief Architect and co-Founder at CRM-konsulterna AB
www.crmkonsulterna.se

Monday, May 28, 2007

Creating CRM-emails in C# code

I have in a previuos post described how to programmatically download a SQL RS report, create a CRM email and attach the report as a pdf to it and send it. This is quite many steps and sometimes it will just be good enough to send mails, for instance when developing addons for workflows.

email em = new email();

activityparty fromparty = new activityparty();
fromparty.partyid = new Lookup();
fromparty.partyid.type = EntityName.systemuser.ToString(); //Change to some other entity if needed.
fromparty.partyid.Value = FROM-SYSTEMUSER-GUID;
em.from = new activityparty[] { fromparty };

activityparty toparty = new activityparty();
toparty.partyid = new Lookup();
toparty.partyid.type = EntityName.contact.ToString(); //Change to some other entity if needed

toparty.partyid.Value = TO-CONTACT-GUID;
em.to = new activityparty[] { toparty };


em.subject = SUBJECT-STRING;
em.sender = "crm@example.com";

em.regardingobjectid = new Lookup();
em.regardingobjectid.type = EntityName.REGARDING ENTITY TYPE.ToString();
em.regardingobjectid.Value = REGARDING OBJECT GUID;
em.description = BODY-STRING;


em.ownerid = new Owner();
em.ownerid.type = EntityName.systemuser.ToString();
em.ownerid.Value = OWNER-SYSTEMUSER-GUID;
Guid createdEmailGuid = service.Create(em);


SendEmailRequest req = new SendEmailRequest();
req.EmailId = createdEmailGuid;
req.TrackingToken = "";
req.IssueSend = true;

// Send the email message.
SendEmailResponse res = (SendEmailResponse)service.Execute(req);

I find this code very helpfull. It can probably be generalized by using BusinessEntity object and so forth but I am usually quite satisfied with this.

Gustaf Westerlund
CRM and SharePoint Consultant

Humandata AB
www.humandata.se