如何使用Gmail API检索我的Gmail邮件? [英] How to retrieve my Gmail messages using Gmail API?
问题描述
我想实现的目标:
我使用 Gmail API ,基本上我想连接到我的GMail帐户来阅读我的收件人类别的电子邮件,并获取每条消息(标题/主题, ,至,日期和发件人)的基本信息。 我正在尝试修改 此 用C#编写的Google示例,根据我自己的需要,我正在C#或Vb.Net中寻找解决方案,无论如何。 (请注意,Google为不同的用户定义的代码示例提供了不同的代码示例,国家,所以这个网页的代码可能不会每个人都是一样的,因为Google的逻辑真的很糟糕。) 我与co有关的问题如下所示: 这是我尝试过的,请注意,在调整Google的示例时,我认为 我会问最重要的需求(不过,任何帮助解决其他提及的问题都非常受欢迎): 这是我现在使用的代码,目的是检索指定的所有 我做错了什么? 目前由于某种原因,许多属性都会从任何请求中返回 目前此方法将检索所有电子邮件id和每个电子邮件ID从, 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). 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. (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: This is what I've tried, note that when adapting the Google's sample, I assumed that
I will ask for the most important need (however, any help to solve the other mentioned problems are very welcome): This is the code that I'm using right now, the intention is to retrieve a collection of all What I'm doing wrong?.
Currently for some reason or another many of the properties are coming back Currently this method will retrieve all email id's and for each email id get the 这篇关于如何使用Gmail API检索我的Gmail邮件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
问题:
lblInbox.MessagesTotal $ c $中获得一个空值c> property。
msgItem.Raw
属性始终为空。 还没有发现如何仅解析INBOX类别内的邮件。
user
参数应该是Gmail用户帐户名称MyEmail@GMail.com
),但我不确定它应该是什么。
Imports System.Collections.Generic
Imports System.IO
Imports System.Linq
Imports System.Text
Imports System .Threading
进口System.Thr eading.Tasks
进口Google.Apis.Auth.OAuth2
进口Google.Apis.Services
进口Google.Apis.Util.Store
进口Google.Apis。 Gmail
导入Google.Apis.Gmail.v1
导入Google.Apis.Gmail.v1.Data
导入Google.Apis.Gmail.v1.UsersResource
公开类Form1:继承表单
Private Async Sub Test()处理MyBase.Shown
等待GmailTest()
End Sub
公共异步函数GmailTest )作为任务
Dim凭证UserCredential
使用流作为新的FileStream(C:\GoogleAPIKey.json,FileMode.Open,FileAccess.Read)
凭证=等待GoogleWebAuthorizationBroker.AuthorizeAsync( GoogleClientSecrets.Load(流).Secrets,
{GmailService.Scope.MailGoogleCom},
MyEmail@GMail.com,
CancellationToken.None)
结束使用
'创建服务。
Dim service As New GmailService(New BaseClientService.Initializer()With {
.HttpClientInitializer = credential,
.ApplicationName =我需要在这里放置什么?
})
'获取INBOX标签/类别。
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)。
Dim msgCount As Integer? = lblInbox.MessagesTotal
MsgBox(Messages Count:& msgCount)
If(msgCount<> 0)Then
'定义请求的消息参数。
Dim msgReq As UsersResource.MessagesResource.ListRequest = service.Users.Messages.List(me)
列出INBOX类别的消息。
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 message
MsgBox(msgItem.Raw)
Next
End If
End If
End Function
End Class
问题:
更新:
Message
s的集合邮箱标签,问题在于<$ c $的 Payload
和 Body
成员c> newMsg 对象为null,所以我无法阅读电子邮件。
公共异步函数GetMessages(ByVal文件夹作为Global.Google.Apis.Gmail.v1.Data.Label)与任务(OfGlobal.Google.Apis.Gmail.v1.Data.Message))
如果不是(Me.isAuthorizedB)然后
抛出新的InvalidOperationException(Me.authExceptionMessage)
其他
Dim msgsRequest As UsersResource.MessagesResource.ListRequest = Me.client.Users.Messages.List(me)
With msgsRequest
.LabelIds = New Repeatable(Of String) ({folder.Id})
.MaxResults = 50
'.Key =您的API密钥
End With
Dim msgsResponse As ListMessagesResponse =等待msgsRequest。 ExecuteAsync()
Dim messages As Ne w(Global.Google.Apis.Gmail.v1.Data.Message)列表
Do而True
对于每个味精作为Global.Google.Apis.Gmail.v1.Data.Message msgsRequest.Format = MessageResource.GetRequest.FormatEnum.Full(me,msg.Id)
Dim newMsg As Message =等待msgRequest.ExecuteAsync()
messages.Add(newMsg)
Next msg
如果不是String.IsNullOrEmpty(msgsResponse .NextPageToken)然后
msgsRequest.PageToken = msgsResponse.NextPageToken
msgsResponse =等待msgsRequest.ExecuteAsync()
其他
退出
结束如果
循环
返回消息
结束如果
结束函数
null
。如果我们有电子邮件ID的列表,我们仍然可以解决这个问题。然后,我们可以使用这些电子邮件ID并发出另一个请求来检索更多详细信息:日期,主题和正文。 @DalmTo 也处于正确的轨道上,但对于最近更改的标题还不够接近,这将需要更多请求。
私人异步任务getEmails()
{
尝试
{
UserCredential凭证;
using(var stream = new FileStream(client_secrets.json,FileMode.Open,FileAccess.Read))
{
credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load (stream).Secrets,
//这个OAuth 2.0访问范围允许对已认证的
//用户帐户进行只读访问,但不允许其他类型的帐户访问。
new [] {GmailService.Scope.GmailReadonly,GmailService.Scope.MailGoogleCom,GmailService.Scope.GmailModify},
ACCOUNT NOT EMAIL ADDRESS的名称,
CancellationToken.None,
新的FileDataStore(this。 GetType()。ToString())
);
var gmailService = new GmailService(new BaseClientService.Initializer()
{
HttpClientInitializer =凭证,
ApplicationName = this.GetType()。 ToString()
});
var emailListRequest = gmailService.Users.Messages.List(EMAILADDRESSHERE);
emailListRequest.LabelIds =INBOX;
emailListRequest.IncludeSpamTrash = false;
//emailListRequest.Q =is:unread; //这是因为我只想要未读电子邮件的...
//得到我们的电子邮件
var emailListResponse =等待emailListRequest.ExecuteAsync();
if(emailListResponse!= null&& emailListResponse.Messages!= null)
{
//遍历每封电子邮件并获取您想要的字段...
foreach(email emailResponse.Messages)
{
var emailInfoRequest = gmailService.Users.Messages.Get(EMAIL ADDRESS HERE,email.Id);
//对该电子邮件ID发出另一个请求...
var emailInfoResponse =等待emailInfoRequest.ExecuteAsync();
if(emailInfoResponse!= null)
{
String from =;
String date =;
String subject =;
String body =;
//遍历头文件并获取我们需要的字段...
foreach(var mParts in emailInfoResponse.Payload.Headers)
{
if(mParts.Name == 日期)
{
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& amp; amp; ;& emailInfoResponse.Payload.Body!= null)
{
body = emailInfoResponse.Payload.Body.Data;
}
else
{
body = getNestedParts(emailInfoResponse.Payload.Parts,);
}
//需要将某些字符替换为电子邮件正文的数据为base64
String codedBody = body.Replace( - ,+);
codedBody = codedBody.Replace(_,/);
byte [] data = Convert.FromBase64String(codedBody);
body = Encoding.UTF8.GetString(data);
//现在你有你想要的数据了......
}
}
}
$ catch(Exception){
MessageBox.Show(无法获取消息!,失败消息!,MessageBoxButtons。好);
static String getNestedParts(IList< MessagePart> part,string curr)
{
string str = curr;
if(part == null)
{
return str;
} else {
foreach(var部分)
{
if(parts.Parts == null)
{
if(parts.Body != null&&&&& parts.Body.Data!= null)
{
str + = parts.Body.Data;
}
}
else {
return getNestedParts(parts.Parts,str);
}
}
return str;
}
}
date $ c $>获取
主题
,每个电子邮件的c>和
body
。如果您有任何不明白的地方,请通知我。在另一个说明上:在发布这个答案之前再次测试。What I want to achieve:
Problems:
lblInbox.MessagesTotal
property.msgItem.Raw
property is always empty too."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:
Update:
Message
s 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
from any of the request. We can still get around that if we have a list of the email id's. We then can use these email id's and send out another request to retrieve back 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 request.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 undread email's...
//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;
}
}
subject
,from
, date
and body
of each email. There are comments through-out 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.