feat: enrich gmail correspondence metadata
This commit is contained in:
@@ -27,7 +27,8 @@ public interface IGmailOAuthService
|
||||
public sealed record GmailOAuthExchangeResult(string GmailAddress);
|
||||
public sealed record GmailMessageSummary(string Id, string ThreadId, string Subject, string From, string To, DateTimeOffset? Date, string Snippet);
|
||||
public sealed record GmailQueryMatchedMessage(GmailMessageSummary Message, IReadOnlyList<string> MatchedQueries);
|
||||
public sealed record GmailMessageDetail(string Id, string ThreadId, string Subject, string From, string To, DateTimeOffset? Date, string Snippet, string BodyText, string? BodyHtml);
|
||||
public sealed record GmailMessageAttachment(string? FileName, string? MimeType, long? SizeBytes, string? GmailAttachmentId, bool Inline);
|
||||
public sealed record GmailMessageDetail(string Id, string ThreadId, string Subject, string From, string To, DateTimeOffset? Date, string Snippet, string BodyText, string? BodyHtml, IReadOnlyList<string> Labels, IReadOnlyList<GmailMessageAttachment> Attachments);
|
||||
|
||||
internal sealed class GmailTokenResponse
|
||||
{
|
||||
@@ -321,9 +322,13 @@ public sealed class GmailOAuthService : IGmailOAuthService
|
||||
|
||||
var threadId = root.TryGetProperty("threadId", out var threadEl) ? threadEl.GetString() ?? "" : "";
|
||||
var snippet = root.TryGetProperty("snippet", out var snippetEl) ? snippetEl.GetString() ?? "" : "";
|
||||
var labels = root.TryGetProperty("labelIds", out var labelIdsEl) && labelIdsEl.ValueKind == JsonValueKind.Array
|
||||
? labelIdsEl.EnumerateArray().Where(x => x.ValueKind == JsonValueKind.String).Select(x => x.GetString()).Where(x => !string.IsNullOrWhiteSpace(x)).Cast<string>().ToList()
|
||||
: new List<string>();
|
||||
|
||||
var payload = root.GetProperty("payload");
|
||||
var headers = ReadHeaders(payload);
|
||||
var attachments = ReadAttachments(payload);
|
||||
var bodyText = ExtractBody(payload, "text/plain");
|
||||
var bodyHtml = ExtractBody(payload, "text/html");
|
||||
if (string.IsNullOrWhiteSpace(bodyText) && !string.IsNullOrWhiteSpace(bodyHtml))
|
||||
@@ -345,7 +350,9 @@ public sealed class GmailOAuthService : IGmailOAuthService
|
||||
headers.TryGetValue("date", out var dateRaw) && DateTimeOffset.TryParse(dateRaw, out var parsedDate) ? parsedDate : null,
|
||||
snippet,
|
||||
bodyText.Trim(),
|
||||
string.IsNullOrWhiteSpace(bodyHtml) ? null : bodyHtml
|
||||
string.IsNullOrWhiteSpace(bodyHtml) ? null : bodyHtml,
|
||||
labels,
|
||||
attachments
|
||||
);
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -538,6 +545,48 @@ public sealed class GmailOAuthService : IGmailOAuthService
|
||||
return result;
|
||||
}
|
||||
|
||||
private static List<GmailMessageAttachment> ReadAttachments(JsonElement payload)
|
||||
{
|
||||
var results = new List<GmailMessageAttachment>();
|
||||
ReadAttachmentsRecursive(payload, results);
|
||||
return results;
|
||||
}
|
||||
|
||||
private static void ReadAttachmentsRecursive(JsonElement payload, List<GmailMessageAttachment> results)
|
||||
{
|
||||
var body = payload.TryGetProperty("body", out var bodyEl) && bodyEl.ValueKind == JsonValueKind.Object
|
||||
? bodyEl
|
||||
: default;
|
||||
var gmailAttachmentId = body.ValueKind == JsonValueKind.Object && body.TryGetProperty("attachmentId", out var attachmentIdEl) && attachmentIdEl.ValueKind == JsonValueKind.String
|
||||
? attachmentIdEl.GetString()
|
||||
: null;
|
||||
var filename = payload.TryGetProperty("filename", out var filenameEl) ? filenameEl.GetString() : null;
|
||||
var mimeType = payload.TryGetProperty("mimeType", out var mimeTypeEl) ? mimeTypeEl.GetString() : null;
|
||||
var sizeBytes = body.ValueKind == JsonValueKind.Object && body.TryGetProperty("size", out var sizeEl) && sizeEl.ValueKind == JsonValueKind.Number
|
||||
? sizeEl.GetInt64()
|
||||
: (long?)null;
|
||||
var disposition = payload.TryGetProperty("headers", out var headersEl) && headersEl.ValueKind == JsonValueKind.Array
|
||||
? headersEl.EnumerateArray()
|
||||
.Where(h => h.TryGetProperty("name", out var n) && string.Equals(n.GetString(), "Content-Disposition", StringComparison.OrdinalIgnoreCase))
|
||||
.Select(h => h.TryGetProperty("value", out var v) ? v.GetString() : null)
|
||||
.FirstOrDefault()
|
||||
: null;
|
||||
var isInline = !string.IsNullOrWhiteSpace(disposition) && disposition.Contains("inline", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(gmailAttachmentId) || !string.IsNullOrWhiteSpace(filename))
|
||||
{
|
||||
results.Add(new GmailMessageAttachment(filename, mimeType, sizeBytes, gmailAttachmentId, isInline));
|
||||
}
|
||||
|
||||
if (payload.TryGetProperty("parts", out var partsEl) && partsEl.ValueKind == JsonValueKind.Array)
|
||||
{
|
||||
foreach (var part in partsEl.EnumerateArray())
|
||||
{
|
||||
ReadAttachmentsRecursive(part, results);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static string ExtractBody(JsonElement payload, string mimeType)
|
||||
{
|
||||
if (payload.TryGetProperty("mimeType", out var mimeTypeEl) &&
|
||||
|
||||
Reference in New Issue
Block a user