gmail api对于特定的历史ID返回null。从Cloud Pub / Sub推送订阅收到的历史记录ID

时间:2019-07-22 09:39:54

标签: c# gmail-api

从Cloud pub / sub push服务中,我得到了一个历史ID。使用该历史记录ID,我尝试读取最近的邮件,但它返回null。

我已经配置了云发布/订阅推送订阅,并将手表添加到“未读”标签。

场景1: 我已经收到推送通知。从该推送通知中,我已获取历史记录ID以获取最新消息。返回我的空值。

方案2: 我已经登录了该已配置的邮件ID,然后将邮件加载到了收件箱中。在那之后,如果我尝试阅读,我会得到历史记录列表。

    static string[] Scopes = { GmailService.Scope.MailGoogleCom };
    static void Main(string[] args)
    {
     string UserId = "####.gmail.com";
     UserCredential credential;
     using (var stream =
                    new FileStream("client_secret_#####.json", FileMode.Open, FileAccess.Read))
                {             
                    string credPath = "token.json";
                    credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
                        GoogleClientSecrets.Load(stream).Secrets,
                        Scopes,
                        UserId,
                        CancellationToken.None,
                        new FileDataStore(credPath, true)).Result;
                    Console.WriteLine("Credential file saved to: " + credPath);
                }

     var service = new GmailService(new BaseClientService.Initializer()
                {
                    HttpClientInitializer = credential,
                    ApplicationName = ApplicationName,
                });

     List<History> result = new List<History>();
                UsersResource.HistoryResource.ListRequest request = service.Users.History.List(UserId);
    //history id received from cloud pub/sub push subscription.
                request.StartHistoryId = Convert.ToUInt64("269871");

    do
                {
                    try
                    {
                        ListHistoryResponse response = request.Execute();
                        if (response.History != null)
                        {
                            result.AddRange(response.History);
                        }
                        request.PageToken = response.NextPageToken;
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("An error occurred: " + e.Message);
                    }
                } while (!String.IsNullOrEmpty(request.PageToken));


      foreach (var vHistory in result)
                {
                    foreach (var vMsg in vHistory.Messages)
                    {
                        string date = string.Empty;
                        string from = string.Empty;
                        string subject = string.Empty;
                        string body = string.Empty;

                        var emailInfoRequest = service.Users.Messages.Get(UserId, vMsg.Id);
                        var emailInfoResponse = emailInfoRequest.Execute();
                        if(emailInfoResponse!= null)
                        {
                            foreach (var mParts in emailInfoResponse.Payload.Headers)
                            {
                                if (mParts.Name == "Date")
                                {
                                    date = mParts.Value;
                                }
                                else if (mParts.Name == "From")
                                {
                                    from = mParts.Value;
                                }
                                else if (mParts.Name == "Subject")
                                {
                                    subject = mParts.Value;
                                }
                                if (date != "" && from != "")
                                {
                                    if (emailInfoResponse.Payload.Parts != null)
                                    {
                                        foreach (MessagePart p in emailInfoResponse.Payload.Parts)
                                        {
                                            if (p.MimeType == "text/html")
                                            {
                                                byte[] data = FromBase64ForUrlString(p.Body.Data);
                                                body = Encoding.UTF8.GetString(data);
                                            }
                                            else if(p.Filename!=null && p.Filename.Length>0)
                                            {
                                                string attId = p.Body.AttachmentId;
                                                string outputDir = @"D:\#####\";
                                                MessagePartBody attachPart = service.Users.Messages.Attachments.Get(UserId, vMsg.Id, attId).Execute();
                                                String attachData = attachPart.Data.Replace('-', '+');
                                                attachData = attachData.Replace('_', '/');
                                                byte[] data = Convert.FromBase64String(attachData);
                                                File.WriteAllBytes(Path.Combine(outputDir, p.Filename), data);
                                            }
                                        }
                                    }
                                    else
                                    {
                                        byte[] data = FromBase64ForUrlString(emailInfoResponse.Payload.Body.Data);                                   
                                        body = Encoding.UTF8.GetString(data);
                                    }
                                }
                            }
                        }
                    }
                }
 public static byte[] FromBase64ForUrlString(string base64ForUrlInput)
    {
        int padChars = (base64ForUrlInput.Length % 4) == 0 ? 0 : (4 - (base64ForUrlInput.Length % 4));
        StringBuilder result = new StringBuilder(base64ForUrlInput, base64ForUrlInput.Length + padChars);
        result.Append(String.Empty.PadRight(padChars, '='));
        result.Replace('-', '+');
        result.Replace('_', '/');
        return Convert.FromBase64String(result.ToString());
    }

    }

请让我知道如何使用历史记录ID阅读完整的消息。当我收到推送通知时。

2 个答案:

答案 0 :(得分:0)

Gmail Api documentation指出Users.history:list方法要求将startHistoryId作为要执行的参数,而不是给您该参数作为响应。这令人困惑,因为它声明为可选参数,但同时也指定它是必需的。该文档还指定:

  

提供的startHistoryId应该从   邮件,主题或上一个列表响应。

我建议您通过“尝试此API”和OAuth 2.0 Playground测试您首先使用的方法。这样可以更轻松地了解您需要提供哪些参数以及可以从每种方法获得哪些响应。

答案 1 :(得分:0)

我已经处理了。关键是要把您收到的history_id解释为“发生某事的最新时刻”。因此,为了使此工作正常进行,您必须使用来自先前执行的history_id(别忘了,在GMail Push API中,这意味着您必须实现初始的完全同步,或者至少应该执行第二次 partial sync ),这将返回从上一个history_id到刚刚收到的事件。

我刚刚在媒体上发表了一篇文章,因为我认为history_id的细节可能有点偷偷摸摸。文章为here