5

问题:我们使用 CRM for Outlook 插件自动记录我们的支持电子邮件,但员工之间的内部电子邮件(其中一些包含敏感信息)也被记录下来。

理想的解决方案:我正在尝试编写一个事件前(“创建电子邮件”消息)插件来阻止内部电子邮件的自动记录,但(显然)阻止消息执行的唯一方法是在事件前阶段,但这总是会导致在 Outlook 中显示错误消息(我们显然不能拥有)。根据文档,只有“InvalidPluginExecutionExeception”应该向用户显示消息,但情况并非如此,因为所有异常都会在用户的 Outlook 应用程序中导致错误消息。

潜在解决方案:还有一个“CheckPromoteEmail”消息(根据文档)确定是否应将电子邮件提升到 CRM(我假设“提升到 CRM”的意思是“使电子邮件实体存储在 CRM 中”) ,但我在上下文中找不到任何可以让我告诉 CRM 不要推广电子邮件的内容。是否有一些标记隐藏在我可以设置的上下文中,或者以某种方式嵌入电子邮件以便 CRM 自己的逻辑决定不存储它?

解决方法解决方案:我知道的唯一其他解决方案(在此处提到)仅在创建电子邮件后清除其主题和内容,但我宁愿首先停止创建电子邮件而不是编辑或删除在浪费时间和资源创建电子邮件之后。

有没有一种干净的方法来停止插件的操作?还是来自任何地方?如果没有,有谁知道微软为什么不提供这个功能?如果操作失败,他们已经在后台具有铁定的回滚功能,为什么不给我一种调用回滚的方法呢?

这是我的代码,以防它有助于回答我的问题:

public class InternalEmailFilter : IPlugin
{
    void IPlugin.Execute(IServiceProvider serviceProvider)
    {
        IPluginExecutionContext _context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
        Entity e = (Entity)_context.InputParameters["Target"];
        bool shouldStore = ShouldStoreInCRM(e);

        if (shouldStore == false)
        {
            throw new Exception(); //attempting to stop the operation without an InvalidPluginExecutionException, but still results in error message to user
        }            
    }

    protected bool ShouldStoreInCRM(Entity e)
    {

           List<Entity> parties = new List<Entity>();

            var atttributes = e.Attributes;
            if (atttributes.ContainsKey("to") == true) parties.AddRange((atttributes["to"] as EntityCollection).Entities);
            if (atttributes.ContainsKey("from") == true) parties.AddRange((atttributes["from"] as EntityCollection).Entities);
            if (atttributes.ContainsKey("cc") == true) parties.AddRange((atttributes["cc"] as EntityCollection).Entities);
            if (atttributes.ContainsKey("bcc") == true) parties.AddRange((atttributes["bcc"] as EntityCollection).Entities);

            foreach (Entity p in parties)
            {
                if (p.LogicalName == "activityparty" && p.Attributes.ContainsKey("addressused") == true && p.Attributes["addressused"] != null)
                {
                    if (p.Attributes["addressused"].ToString().ToLower().Contains("@ourdomain.com") == false)
                    {
                        return true; //someone connected in the email is not an employee, store the email
                    }
                }
            }

            return false;  //everyone was an employee, do not store          
    }
}
4

3 回答 3

8

经过大量的血汗和泪水,我终于想出了如何做到这一点:

您必须在“创建电子邮件”消息上使用异步事件后插件,以便在创建电子邮件后使用 CRMService 从数据库中删除电子邮件。它必须是异步的,因为您需要等待 CRM 完成创建并“放开”实体,然后才能将其删除。否则,进程挂起。

这些解决方案中的任何一个都会更好,但作为参考,您不能:

  1. 在事件前抛出异常以取消创建/推广电子邮件操作,而不向用户显示错误消息或对其 Outlook 造成严重破坏。即使只有 InvlaidPluginExectuionExecption 应该向用户显示消息,但所有异常都会向用户显示错误消息。
  2. 阻止向 CRM 推广电子邮件。CheckPromoteEmail 消息前事件(令人惊讶的是)没有提供有关可能被提升的消息的信息(因此没有数据可用于决定是否应该提升消息)并且没有任何东西可用于告诉 CRM 不提升消息。而且,如果您使用 pre/post-event 并尝试使用 Output 参数并在那里更改 ShouldPromote 标志,它什么也不做。
  3. 在为其创建实体之前清除电子邮件的正文内容- 您在前事件中对正文内容所做的任何更改都不会保留在执行上下文中,并且会在核心操作开始时丢失。

令人抓狂。

于 2013-02-12T00:00:33.320 回答
2

抱歉,解决方法是您唯一的选择。通过插件停止操作的唯一方法是抛出异常。微软为什么这样做?我假设他们不希望插件默默地失败。

至于解决方法,您应该在事件前插件中清除它们进入数据库之前清除主题和正文,然后在事件后异步插件中清除记录本身。这样,敏感信息也不会进入任何审计日志。

最后,看看DeliverPromoteEmail而不是CreateEmail. DeliverPromoteEmail是 Outlook 用于创建跟踪电子邮件的内容。这样,您仍然可以在不触发此插件的 CRM UI 中创建电子邮件(如果需要)。

edit CheckPromoteEmail仅查看主题中的跟踪令牌(和/或电子邮件标头中的 MessageID)来决定是否应跟踪电子邮件,因此它也没有用。

于 2013-02-05T03:17:23.450 回答
0

您可以在个人设置中选择跟踪所有电子邮件、对 CRM 电子邮件的电子邮件回复(已跟踪的电子邮件)、来自记录(帐户等)的电子邮件以及来自启用了电子邮件的记录的电子邮件。

于 2013-02-11T12:39:49.390 回答