【问题标题】:EWS - Determine if an e-mail is a reply or has been forwardedEWS - 确定电子邮件是回复还是已转发
【发布时间】:2015-12-19 13:01:14
【问题描述】:

我正在使用 Exchange Web Services Managed API 2.2 来监控用户的收件箱,并且需要确定电子邮件是新邮件、回复邮件还是转发邮件。

我看过关于 SO 的各种文章,例如 how to notice if a mail is a forwarded mail?Is there a way to determine if a email is a reply/response using ews c#?,它们都对他们的特定情况有所帮助,但我仍然无法弄清楚如何区分回复和转发的项目。

在第一篇文章中,每次(转发或回复)都添加了额外的 5 个字节,所以我不知道最后的操作是什么。

第二篇文章建议使用InReplyTo,但是当我检查转发电子邮件的属性时,它包含原始发件人电子邮件地址(非空)。

我看过其他文章,例如 thisthis,它们建议使用扩展属性来检查 PR_ICON_INDEX、PR_LAST_VERB_EXECUTED 和 PR_LAST_VERB_EXECUTION_TIME 中的值。

我的代码如下所示,但从未返回 lastVerbExecuted 的值

var lastVerbExecutedProperty = new ExtendedPropertyDefinition(4225, MapiPropertyType.Integer);

var response = service.BindToItems(newMails, new PropertySet(BasePropertySet.IdOnly,  lastVerbExecutedProperty));
var items = response.Select(itemResponse => itemResponse.Item);

foreach (var item in items)
{
    object lastVerb;

    if (item.TryGetProperty(lastVerbExecutedProperty, out lastVerb))
    {
        // do something
    }
}

【问题讨论】:

    标签: c# exchangewebservices extended-properties


    【解决方案1】:

    PR_ICON_INDEX、PR_LAST_VERB_EXECUTED 和 PR_LAST_VERB_EXECUTION_TIME 只会告诉您收件人是否对其收件箱中的邮件采取了行动。例如,如果用户在他们的收件箱中回复或转发了一条消息,那么这些属性会在他们的收件箱中的消息上设置。在响应或转发的消息上,不会设置这些属性。我建议您使用应在任何回复或转发的邮件上设置的 In-Reply-To Transport 标头,这应包含已回复或转发的邮件的 Internet messageid,例如。

            FindItemsResults<Item> fiRs = service.FindItems(WellKnownFolderName.Inbox, new ItemView(10));
            PropertySet fiRsPropSet = new PropertySet(BasePropertySet.FirstClassProperties);
            ExtendedPropertyDefinition PR_TRANSPORT_MESSAGE_HEADERS = new ExtendedPropertyDefinition(0x007D, MapiPropertyType.String);
            fiRsPropSet.Add(PR_TRANSPORT_MESSAGE_HEADERS);
            service.LoadPropertiesForItems(fiRs.Items, fiRsPropSet);
            foreach (Item itItem in fiRs)
            {
                Object TransportHeaderValue = null;
                if(itItem.TryGetProperty(PR_TRANSPORT_MESSAGE_HEADERS,out TransportHeaderValue)) {
                    string[] stringSeparators = new string[] { "\r\n" };
                    String[] taArray = TransportHeaderValue.ToString().Split(stringSeparators, StringSplitOptions.None);
                    for (Int32 txCount = 0; txCount < taArray.Length; txCount++)
                    {
                        if (taArray[txCount].Length > 12)
                        {
                            if (taArray[txCount].Substring(0, 12).ToLower() == "in-reply-to:")
                            {
                                String OriginalId = taArray[txCount].Substring(13);
                                Console.WriteLine(OriginalId);
                            }
                        }
                    }
    
                }
            }
    

    除了在另一个链接中讨论的主题前缀之外,我不知道任何其他可以区分回复或转发的属性。

    干杯 格伦

    【讨论】:

    • 谢谢,我没有意识到只有在用户与项目交互时才设置属性
    • 感谢您的详细解答。是否还可以找出电子邮件被转发或回复给谁?
    • 您需要检查已转发或回复的邮件的 SendItems 或检查服务器上的邮件跟踪日志
    【解决方案2】:

    最好的依赖方式是Extended properties的ResponeCode

    参考下面的脚本

    private static int IsForwardOrReplyMail(ExchangeService service, EmailMessage messageToCheck)
        {
            try
            {
                // Create extended property definitions for PidTagLastVerbExecuted and PidTagLastVerbExecutionTime.
                ExtendedPropertyDefinition PidTagLastVerbExecuted = new ExtendedPropertyDefinition(0x1081, MapiPropertyType.Integer);
                ExtendedPropertyDefinition PidTagLastVerbExecutionTime = new ExtendedPropertyDefinition(0x1082, MapiPropertyType.SystemTime);
    
                PropertySet propSet = new PropertySet(BasePropertySet.IdOnly, EmailMessageSchema.Subject, PidTagLastVerbExecutionTime, PidTagLastVerbExecuted);
                messageToCheck = EmailMessage.Bind(service, messageToCheck.Id, propSet);
    
                // Determine the last verb executed on the message and display output.
                object responseType;
                messageToCheck.TryGetProperty(PidTagLastVerbExecuted, out responseType);
    
                if (responseType != null && ((Int32)responseType) == 104)
                {
                    //FORWARD
                    return 104;
                }
                else if (responseType != null && ((Int32)responseType) == 102)
                {
                    //REPLY
                    return 102;
                }
    
    
            }
            catch (Exception)
            {
                return 0;
    
                //throw new NotImplementedException();
            }
    
        }
    

    【讨论】:

      【解决方案3】:

      要确定它是否是对电子邮件的回复,您可以使用 EmailMessage 对象 InReplyTo 属性,例如:

      EmailMessage mail = ((EmailMessage)Item.Bind(service, new ItemId(UniqueId)));
      
      if (mail.InReplyTo == null)
          return;
      else
          ..your code
      

      【讨论】:

        猜你喜欢
        • 2011-06-07
        • 2012-08-10
        • 2013-07-25
        • 1970-01-01
        • 2017-07-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多