chore(M001/S01): auto-commit after complete-slice
This commit is contained in:
@@ -20,6 +20,7 @@ public interface IGmailOAuthService
|
||||
Task<IReadOnlyList<GmailMessageSummary>> ListMessagesAsync(string ownerUserId, string? query, int maxResults, CancellationToken cancellationToken);
|
||||
Task<IReadOnlyList<GmailMessageSummary>> ListMessagesForQueriesAsync(string ownerUserId, IEnumerable<string> queries, int maxResultsPerQuery, CancellationToken cancellationToken);
|
||||
Task<IReadOnlyList<GmailQueryMatchedMessage>> ListJobCandidateMessagesAsync(string ownerUserId, IEnumerable<string> queries, int maxResultsPerQuery, CancellationToken cancellationToken);
|
||||
Task<IReadOnlyList<GmailMessageSummary>> ListThreadMessagesAsync(string ownerUserId, string threadId, CancellationToken cancellationToken);
|
||||
Task<GmailMessageDetail> GetMessageAsync(string ownerUserId, string messageId, CancellationToken cancellationToken);
|
||||
}
|
||||
|
||||
@@ -225,6 +226,60 @@ public sealed class GmailOAuthService : IGmailOAuthService
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public async Task<IReadOnlyList<GmailMessageSummary>> ListThreadMessagesAsync(string ownerUserId, string threadId, CancellationToken cancellationToken)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(threadId))
|
||||
{
|
||||
return Array.Empty<GmailMessageSummary>();
|
||||
}
|
||||
|
||||
var accessToken = await GetValidAccessTokenAsync(ownerUserId, cancellationToken);
|
||||
var client = _httpClientFactory.CreateClient();
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
|
||||
|
||||
var url = $"https://gmail.googleapis.com/gmail/v1/users/me/threads/{Uri.EscapeDataString(threadId.Trim())}?format=metadata&metadataHeaders=Subject&metadataHeaders=From&metadataHeaders=To&metadataHeaders=Date";
|
||||
using var response = await client.GetAsync(url, cancellationToken);
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
using var doc = await JsonDocument.ParseAsync(await response.Content.ReadAsStreamAsync(cancellationToken), cancellationToken: cancellationToken);
|
||||
if (!doc.RootElement.TryGetProperty("messages", out var messagesElement) || messagesElement.ValueKind != JsonValueKind.Array)
|
||||
{
|
||||
return Array.Empty<GmailMessageSummary>();
|
||||
}
|
||||
|
||||
var results = new List<GmailMessageSummary>();
|
||||
foreach (var messageElement in messagesElement.EnumerateArray())
|
||||
{
|
||||
var id = messageElement.TryGetProperty("id", out var idEl) ? idEl.GetString() : null;
|
||||
if (string.IsNullOrWhiteSpace(id)) continue;
|
||||
|
||||
var messageThreadId = messageElement.TryGetProperty("threadId", out var messageThreadIdEl)
|
||||
? messageThreadIdEl.GetString() ?? threadId.Trim()
|
||||
: threadId.Trim();
|
||||
var snippet = messageElement.TryGetProperty("snippet", out var snippetEl) ? snippetEl.GetString() ?? string.Empty : string.Empty;
|
||||
var payload = messageElement.TryGetProperty("payload", out var payloadEl) ? payloadEl : default;
|
||||
var headers = payload.ValueKind == JsonValueKind.Object ? ReadHeaders(payload) : new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
DateTimeOffset? date = null;
|
||||
if (headers.TryGetValue("date", out var dateHeader) && DateTimeOffset.TryParse(dateHeader, out var parsedDate))
|
||||
{
|
||||
date = parsedDate;
|
||||
}
|
||||
|
||||
results.Add(new GmailMessageSummary(
|
||||
id.Trim(),
|
||||
messageThreadId,
|
||||
headers.TryGetValue("subject", out var subject) ? subject : string.Empty,
|
||||
headers.TryGetValue("from", out var from) ? from : string.Empty,
|
||||
headers.TryGetValue("to", out var to) ? to : string.Empty,
|
||||
date,
|
||||
snippet));
|
||||
}
|
||||
|
||||
await TouchSyncTimeAsync(ownerUserId, cancellationToken);
|
||||
return results;
|
||||
}
|
||||
|
||||
public async Task<GmailMessageDetail> GetMessageAsync(string ownerUserId, string messageId, CancellationToken cancellationToken)
|
||||
{
|
||||
var accessToken = await GetValidAccessTokenAsync(ownerUserId, cancellationToken);
|
||||
|
||||
Reference in New Issue
Block a user