如何使用 Gmail API 检索我的 Gmail 邮件? [英] How to retrieve my Gmail messages using Gmail API?

查看:30
本文介绍了如何使用 Gmail API 检索我的 Gmail 邮件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Gmail API 基本上我想连接到我的 GMail 帐户以阅读我的收件箱类别的电子邮件,并获取每封邮件的基本信息(标题/主题,来自em>、日期和发件人).

I'm using the Gmail API and basically I would like to connect to my GMail account to read my emails, of INBOX category, and get basic info for each message (title/subject, from, to, date, and the sender).

我正在尝试适应this 用 C# 编写的 Google 示例,根据我自己的需要,我正在寻找 C# 或 Vb.Net 中的解决方案.

I'm trying to adapt this Google sample, written in C#, to my own needs, I'm searching for a solution in C# or Vb.Net, no matter.

(请注意,Google 为不同的用户国家/地区显示了不同的代码示例,因此该网页的代码可能不会对每个人都相同,Google 的逻辑真的很糟糕.)

(Be aware that Google shows different code examples for different user-countries, so the code of that webpage maybe will not be the same for every one, that Google's logic really sucks.)

我在下面的代码中遇到的问题是:

The problems I have with the code below, are these:

  • 我在 lblInbox.MessagesTotal 属性中得到一个空值.
  • msgItem.Raw 属性也始终为空.
  • 我还没有发现如何仅解析 INBOX 类别内的消息.
  • 我还没有发现如何确定消息是已读还是未读.
  • 我还没有发现如何确定消息的基本信息(主题、发件人、收件人、日期、发件人).
  • I'm getting an empty value in lblInbox.MessagesTotal property.
  • msgItem.Raw property is always empty too.
  • I haven't yet discovered how to parse only the messages that are inside the INBOX category.
  • I haven't yet discovered how to determine if a message is read or unread.
  • I haven't yet discovered how to determine the basic info of a message (subject, from, to, date, sender).

这是我尝试过的,请注意,在调整 Google 的示例时,我假设 "user" 参数应该是 Gmail 用户帐户名 ("MyEmail@GMail.com"),但我不确定应该是这样.

This is what I've tried, note that when adapting the Google's sample, I assumed that "user" argument should be the Gmail user account name ("MyEmail@GMail.com"), but I'm not sure it should be that.

Imports System.Collections.Generic
Imports System.IO
Imports System.Linq
Imports System.Text
Imports System.Threading
Imports System.Threading.Tasks

Imports Google.Apis.Auth.OAuth2
Imports Google.Apis.Services
Imports Google.Apis.Util.Store
Imports Google.Apis.Gmail
Imports Google.Apis.Gmail.v1
Imports Google.Apis.Gmail.v1.Data
Imports Google.Apis.Gmail.v1.UsersResource

Public Class Form1 : Inherits Form

    Private Async Sub Test() Handles MyBase.Shown
        Await GmailTest()
    End Sub

    Public Async Function GmailTest() As Task
        Dim credential As UserCredential
        Using stream As New FileStream("C:GoogleAPIKey.json", FileMode.Open, FileAccess.Read)
            credential = Await GoogleWebAuthorizationBroker.AuthorizeAsync(GoogleClientSecrets.Load(stream).Secrets,
                                                                           {GmailService.Scope.MailGoogleCom},
                                                                           "MyEmail@GMail.com",
                                                                           CancellationToken.None)
        End Using

        ' Create the service.
        Dim service As New GmailService(New BaseClientService.Initializer() With {
             .HttpClientInitializer = credential,
             .ApplicationName = "What I need to put here?"
        })

        ' Get the "INBOX" label/category.
        Dim lblReq As UsersResource.LabelsResource.ListRequest = service.Users.Labels.List("me")
        Dim lblInbox As Data.Label = lblReq.Execute().Labels.Where(Function(lbl) lbl.Name = "INBOX").Single
        Dim msgCount As Integer? = lblInbox.MessagesTotal

        MsgBox("Messages Count: " & msgCount)

        If (msgCount <> 0) Then

            ' Define message parameters of request.
            Dim msgReq As UsersResource.MessagesResource.ListRequest = service.Users.Messages.List("me")

            ' List messages of INBOX category.
            Dim messages As IList(Of Data.Message) = msgReq.Execute().Messages
            Console.WriteLine("Messages:")
            If (messages IsNot Nothing) AndAlso (messages.Count > 0) Then
                For Each msgItem As Data.Message In messages
                    MsgBox(msgItem.Raw)
                Next
            End If

        End If

    End Function

End Class

问题:

<小时>

我会问最重要的需求(但是,非常欢迎任何帮助解决其他提到的问题):

Question:


I will ask for the most important need (however, any help to solve the other mentioned problems are very welcome):

  • 在 C# 或 VB.Net 中,如何获取集合以迭代所有收件箱组中的电子邮件?
  • In C# or VB.Net, how can I obtain a collection to iterate all the emails that are in the INBOX group?.

这是我现在使用的代码,目的是检索指定邮箱标签的所有Message的集合,问题是newMsg 对象的 PayloadBody 成员为空,所以我无法阅读电子邮件.

This is the code that I'm using right now, the intention is to retrieve a collection of all Messages of the specified mailbox label, the problem is that the Payload and Body member of newMsg object is null, so I can't read the email.

我做错了什么?.

Public Async Function GetMessages(ByVal folder As Global.Google.Apis.Gmail.v1.Data.Label) As Task(Of List(Of Global.Google.Apis.Gmail.v1.Data.Message))

    If Not (Me.isAuthorizedB) Then
        Throw New InvalidOperationException(Me.authExceptionMessage)
    Else
        Dim msgsRequest As UsersResource.MessagesResource.ListRequest = Me.client.Users.Messages.List("me")
        With msgsRequest
            .LabelIds = New Repeatable(Of String)({folder.Id})
            .MaxResults = 50
            '.Key = "YOUR API KEY"
        End With

        Dim msgsResponse As ListMessagesResponse = Await msgsRequest.ExecuteAsync()

        Dim messages As New List(Of Global.Google.Apis.Gmail.v1.Data.Message)
        Do While True

            For Each msg As Global.Google.Apis.Gmail.v1.Data.Message In msgsResponse.Messages
                Dim msgRequest As UsersResource.MessagesResource.GetRequest = Me.client.Users.Messages.Get("me", msg.Id)
                msgRequest.Format = MessagesResource.GetRequest.FormatEnum.Full

                Dim newMsg As Message = Await msgRequest.ExecuteAsync()
                messages.Add(newMsg)
            Next msg

            If Not String.IsNullOrEmpty(msgsResponse.NextPageToken) Then
                msgsRequest.PageToken = msgsResponse.NextPageToken
                msgsResponse = Await msgsRequest.ExecuteAsync()
            Else
                Exit Do
            End If

        Loop

        Return messages

    End If

End Function

推荐答案

目前由于某种原因或其他原因,许多属性从任何请求中返回 null.如果我们有电子邮件 ID 列表,我们仍然可以解决这个问题.然后,我们可以使用这些电子邮件 ID 发出另一个请求以检索更多详细信息:fromdatesubjectbody.@DalmTo 也走在正确的轨道上,但与标题不够接近,因为它最近发生了变化,需要更多请求.

Currently for some reason or another many of the properties are coming back null from any of the requests. We can still get around that if we have a list of the email ids. We then can use these email ids to send out another request to retrieve further details: from, date, subject, and body. @DalmTo was on the right track as well, but not close enough about the headers as it has changed recently which will require a few more requests.

private async Task getEmails()
{
    try
    {
        UserCredential credential;
        using (var stream = new FileStream("client_secrets.json", FileMode.Open, FileAccess.Read))
        {
            credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
                GoogleClientSecrets.Load(stream).Secrets,
                // This OAuth 2.0 access scope allows for read-only access to the authenticated 
                // user's account, but not other types of account access.
                new[] { GmailService.Scope.GmailReadonly, GmailService.Scope.MailGoogleCom, GmailService.Scope.GmailModify },
                "NAME OF ACCOUNT NOT EMAIL ADDRESS",
                CancellationToken.None,
                new FileDataStore(this.GetType().ToString())
            );
        }

        var gmailService = new GmailService(new BaseClientService.Initializer()
        {
            HttpClientInitializer = credential,
            ApplicationName = this.GetType().ToString()
        });

        var emailListRequest = gmailService.Users.Messages.List("EMAILADDRESSHERE");
        emailListRequest.LabelIds = "INBOX";
        emailListRequest.IncludeSpamTrash = false;
        //emailListRequest.Q = "is:unread"; // This was added because I only wanted unread emails...

        // Get our emails
        var emailListResponse = await emailListRequest.ExecuteAsync();

        if (emailListResponse != null && emailListResponse.Messages != null)
        {
            // Loop through each email and get what fields you want...
            foreach (var email in emailListResponse.Messages)
            {
                var emailInfoRequest = gmailService.Users.Messages.Get("EMAIL ADDRESS HERE", email.Id);
                // Make another request for that email id...
                var emailInfoResponse = await emailInfoRequest.ExecuteAsync();

                if (emailInfoResponse != null)
                {
                    String from = "";
                    String date = "";
                    String subject = "";
                    String body = "";
                    // Loop through the headers and get the fields we need...
                    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 && emailInfoResponse.Payload.Body != null)
                            {
                                body = emailInfoResponse.Payload.Body.Data;
                            }
                            else
                            {
                                body = getNestedParts(emailInfoResponse.Payload.Parts, "");
                            }
                            // Need to replace some characters as the data for the email's body is base64
                            String codedBody = body.Replace("-", "+");
                            codedBody = codedBody.Replace("_", "/");
                            byte[] data = Convert.FromBase64String(codedBody);
                            body = Encoding.UTF8.GetString(data);                               

                            // Now you have the data you want...                         
                        }
                    }
                }                    
            }
        }           
    }
    catch (Exception)
    {
        MessageBox.Show("Failed to get messages!", "Failed Messages!", MessageBoxButtons.OK); 
    }
}

static String getNestedParts(IList<MessagePart> part, string curr)
{
    string str = curr;
    if (part == null)
    {
        return str;
    }
    else
    {
        foreach (var parts in part)
        {
            if (parts.Parts  == null)
            {
                if (parts.Body != null && parts.Body.Data != null)
                {
                    str += parts.Body.Data;
                }
            }
            else
            {
                return getNestedParts(parts.Parts, str);
            }
        }

        return str;
    }        
}

目前,此方法将检索所有电子邮件 ID,并为每个电子邮件 ID 获取 subjectfromdatebody 每封电子邮件.整个方法都有注释.如果您有什么不明白的地方,请告诉我.另请注意:在将此作为答案发布之前再次进行了测试.

Currently, this method will retrieve all email ids and for each email id get the subject,from, date and body of each email. There are comments throughout the method. If there is something you do not understand, please let me know. On another note: this was tested again before posting this as an answer.

这篇关于如何使用 Gmail API 检索我的 Gmail 邮件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆