使用Gmail API仅读取5封邮件的Windows应用问题求助
Hey there! I see you're stuck with getting only 5 emails from Gmail API even after setting MaxResults = 100. Let's work through this step by step to fix the issue.
可能的原因1:查询条件限制了结果数量
You set emailListRequest.Q = "in:unread in:inbox"; — if your inbox only has 5 unread emails, the API will only return those 5 no matter how high you set MaxResults. Try temporarily removing the unread filter to test if you get more results:
// 先注释掉未读过滤,测试结果数量 // emailListRequest.Q = "in:unread in:inbox"; emailListRequest.Q = "in:inbox";
可能的原因2:未处理API分页
Gmail API's List endpoint paginates results by default. Even with MaxResults=100, if there are more than 100 matching emails (or if the API splits results into pages), you need to use the NextPageToken to fetch subsequent batches of emails.
修改后的GetMAILs()方法(添加分页处理)
private async Task GetMAILs() { try { UserCredential credential; using (var stream = new FileStream("client_secret.json", FileMode.Open, FileAccess.Read)) { credential = await GoogleWebAuthorizationBroker.AuthorizeAsync( GoogleClientSecrets.Load(stream).Secrets, new[] { GmailService.Scope.GmailReadonly, GmailService.Scope.MailGoogleCom, GmailService.Scope.GmailModify }, "an thanh", 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("mymail@gmail.com"); emailListRequest.LabelIds = "INBOX"; // 可根据需求保留或调整查询条件 // emailListRequest.Q = "in:unread in:inbox"; emailListRequest.Q = "in:inbox"; emailListRequest.MaxResults = 100; StringBuilder bd = new StringBuilder(); // 方法内初始化避免重复追加内容 string nextPageToken = null; do { emailListRequest.PageToken = nextPageToken; var emailListResponse = await emailListRequest.ExecuteAsync(); if (emailListResponse != null && emailListResponse.Messages != null) { foreach (var email in emailListResponse.Messages) { string from = ""; string date = ""; string subject = ""; string decoded = ""; var emailInfoRequest = gmailService.Users.Messages.Get("mymail@gmail.com", email.Id); var emailInfoResponse = await emailInfoRequest.ExecuteAsync(); 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 (emailInfoResponse.Payload.Parts != null) { foreach (var ms_part in emailInfoResponse.Payload.Parts) { if (ms_part.MimeType == "text/plain" && ms_part.Body?.Data != null) { byte[] data = FromBase64ForUrlString(ms_part.Body.Data); decoded = Encoding.UTF8.GetString(data); } } } else if (emailInfoResponse.Payload.Body?.Data != null) { byte[] data = FromBase64ForUrlString(emailInfoResponse.Payload.Body.Data); decoded = Encoding.UTF8.GetString(data); } } bd.AppendLine($"Từ: {from}"); bd.AppendLine(subject); bd.AppendLine(date); bd.AppendLine("Content: "); bd.AppendLine(decoded); bd.AppendLine("-------End-------"); bd.AppendLine("----------------------------------------------------"); } } nextPageToken = emailListResponse.NextPageToken; } while (!string.IsNullOrEmpty(nextPageToken)); // 循环获取直到没有下一页 richTextBox1.Text = bd.ToString(); } catch (Exception ex) { MessageBox.Show($"Failed to get messages!: {ex.Message}", "Failed Messages!", MessageBoxButtons.OK); } }
额外优化说明
- 我把
StringBuilder bd移到方法内初始化,避免多次调用时内容重复叠加。 - 增加了对简单邮件的处理(有些邮件的正文直接存在
Payload.Body里,没有Parts层级)。 - 添加了空值判断,防止
Body.Data为空导致的引用异常。
其他排查建议
- Double-check that your Gmail inbox actually has more than 5 emails matching your query criteria.
- Verify your authorization setup: Ensure the project linked to
client_secret.jsonhas Gmail API enabled in Google Cloud Console, and the authorized account has proper access permissions.
Hope these changes help you fetch all the emails you need!
内容的提问来源于stack exchange,提问作者binh nguyen

