我正在尝试实现一项使用 Gmail API 回复电子邮件线程的功能。尽管我做出了努力,但回复仍作为新邮件发送,而不是在原始电子邮件下串联。但是,它们确实出现在整个对话视图中的正确线程中。
这是我到目前为止所做的:
设置线程ID:
gmailMessage.ThreadId = threadId;
添加正在回复的邮件的消息ID:
mimeMessage.Headers.Add("In-Reply-To", msgId);
mimeMessage.Headers.Add("References", msgId);
确保主题相同:
mimeMessage.Subject = mailMsg.Subject
尽管执行了这些步骤,Gmail UI 仍然将回复显示为新邮件,尽管它是在内部同一线程中记录的。
供参考的代码片段:
private string AddThreadIdToMime(string base64RawMime, string threadId, string msgId)
{
var mimeMessage = MimeKit.MimeMessage.Load(new MemoryStream(Convert.FromBase64String(base64RawMime.Replace('-', '+').Replace('_', '/'))));
mimeMessage.Subject = originalSubject;
mimeMessage.Headers.Add("In-Reply-To", msgId);
mimeMessage.Headers.Add("References", msgId);
using (var memory = new MemoryStream())
{
mimeMessage.WriteTo(memory);
return Convert.ToBase64String(memory.ToArray())
.Replace('+', '-')
.Replace('/', '_')
.Replace("=", "");
}
}
发送消息:
gmailMsg.Raw = rawMime;
gmailMsg.ThreadId = threadId;
UsersResource.MessagesResource.SendRequest msgSendReq = _gmailService.Users.Messages.Send(gmailMsg, userEmail);
gmailMsg = await msgSendReq.ExecuteAsync();
}
问题:
我错过了什么?是否需要执行任何额外步骤来确保回复正确地串入 Gmail 用户界面中?
谢谢您的帮助!
为了确保您的线程请求正常工作,准确引用几个关键参数至关重要。
首先,我会确保在调用“users.send”方法时获取并使用正确的“threadId”。这会将您的电子邮件链接到适当的线程。
为了获取“threadId”,您可以使用此 Google 开发人员支持文章中直接提供的 API Explorer。填写“userId”字段(您可以使用您的用户电子邮件地址),然后在响应正文中找到“threadId”。这是一个示例响应:
{
"threads": [
{
"id": "1907666c282nsodw",
"snippet": "Thread-1 On Wed, Jul 1, 2024 at 3:19 PM Peter Parker <[email protected]> wrote: Message1",
"historyId": "1234"
},
...
}
此外,您应该正确设置请求中的标头。为了获取必要的信息(例如“参考”标题和“回复”标题,请确保在原始电子邮件中使用这些信息。您可以通过转到 Gmail 应用程序中的电子邮件,然后单击接下来,选择消息右侧的三点按钮“<>显示原始内容”。
以下是原始电子邮件标头的示例:
From: Peter Parker <[email protected]>
Subject: Re: Hello!
From: Peter Parker <[email protected]>
To: [email protected]
References: <[email protected]>
In-Reply-To: <[email protected]>
此后,使用 Base64 URL 对上述内容进行编码后,您可以在“raw”参数中使用它。上面示例的原始编码如下:
RnJvbTogUGV0ZXIgUGFya2VyIDxhZG1pbkBleGFtcGxlLmNvbT4KU3ViamVjdDogUmU6IEhlbGxvIQpGcm9tOiBQZXRlciBQYXJrZXIgPGFkbWluQGV4YW1wbGUuY29tPgpUbzogbWFyeWphbmVAZXhhbXBsZS5jb20KUmVmZXJlbmNlczogPG1lc3NhZ2VJREBtYWlsLmdtYWlsLmNvbT4KSW4tUmVwbHktVG86IDxtZXNzYWdlSURAbWFpbC5nbWFpbC5jb20-
完整的请求如下所示:
userId: [email protected]
{
"raw": "RnJvbTogUGV0ZXIgUGFya2VyIDxhZG1pbkBleGFtcGxlLmNvbT4KU3ViamVjdDogUmU6IEhlbGxvIQpGcm9tOiBQZXRlciBQYXJrZXIgPGFkbWluQGV4YW1wbGUuY29tPgpUbzogbWFyeWphbmVAZXhhbXBsZS5jb20KUmVmZXJlbmNlczogPG1lc3NhZ2VJREBtYWlsLmdtYWlsLmNvbT4KSW4tUmVwbHktVG86IDxtZXNzYWdlSURAbWFpbC5nbWFpbC5jb20-",
"threadId": "1907666c282nsodw"
}
总之,为了在线程中回复,您需要确保您拥有正确的线程 ID 以及您要回复的消息 ID。 References 和 In-Reply-To 需要是原始消息中的消息 ID,然后使用 Base64 URL 对消息进行编码。
与原始消息相比,我还测试了不同的主题,这不是问题。
您可以先在 API 浏览器中尝试一下这里。