如何使用 Gmail API 发送回复
Posted
技术标签:
【中文标题】如何使用 Gmail API 发送回复【英文标题】:How To Send A Reply With Gmail API 【发布时间】:2015-12-11 21:52:15 【问题描述】:我有两个 gmail 帐户,我创建了一个包含 5 条消息的线程,并在此页面 https://developers.google.com/gmail/api/v1/reference/users/threads/get 上使用 gmail gapi 检索了它们。
这是我得到的:
如您所见,尽管标识完全相同的字母,但 id 并不匹配。为什么会发生这种情况,我怎样才能获得统一的 id?
附:我这样做的真正原因是我需要使用 gmail API 发送对消息的回复,但要做到这一点,您需要知道您回复的消息的 ID。如果我用我拥有的 id(不是接收者拥有的消息 id)回复消息,它只会发送一条“新”消息。
?
提前谢谢你。
【问题讨论】:
您要回复单个消息还是回复主题? 我想回复一条消息。 【参考方案1】:作为docs say,如果您尝试发送回复并希望将电子邮件发送到线程中,请确保:
Subject
标头匹配
References
和 In-Reply-To
标头遵循 RFC 2822 标准。
如果你想自己做这件事,你可以得到Subject
、References
和Message-ID
-你想要回复的消息的标题:
请求:
userId = me
id = 14fd1c555a1352b7 // id of the message I want to respond to.
format = metadata
metadataHeaders = Subject,References,Message-ID
GET https://www.googleapis.com/gmail/v1/users/me/messages/14fd1c555a1352b7?format=metadata&metadataHeaders=Subject&metadataHeaders=References&metadataHeaders=Message-ID
回应:
"id": "14fd1c555a1352b7",
"threadId": "14fd1c52911f0f64",
"labelIds": [
"SENT",
"INBOX",
"IMPORTANT",
"UNREAD"
],
"snippet": "Next level dude 2015-09-15 18:10 GMT+02:00 Emil Tholin <emtholin@gmail.com>: wow 2015-09-15 18:",
"historyId": "575289",
"internalDate": "1442333414000",
"payload":
"mimeType": "multipart/alternative",
"headers": [
"name": "In-Reply-To",
"value": "<CADsZLRyzVPLRQuTthGSHKMCXL7Ora1jNW7h0jvoNgR+hU59BYg@mail.gmail.com>"
,
"name": "References",
"value": "<CADsZLRxZDUGn4Frx80qe2_bE5H5bQhgcqGk=GwFN9gs7Z_8oZw@mail.gmail.com> <CADsZLRyzVPLRQuTthGSHKMCXL7Ora1jNW7h0jvoNgR+hU59BYg@mail.gmail.com>"
,
"name": "Message-ID", // This is the same for both users, as you were asking about.
"value": "<CADsZLRwQWzLB-uq4_4G2E64NX9G6grn0cEeO0L=avY7ajzuAFg@mail.gmail.com>"
,
"name": "Subject",
"value": "Re: Cool"
]
,
"sizeEstimate": 1890
为了遵循 RFC 2822 标准,我们在References
-header 中添加了我们想要响应的消息的Message-ID
,并用空格分隔。 In-Reply-To
-header 还具有我们想要响应的消息的值。我们还将Re:
添加到我们的Subject
-header 以表明它是一个响应。
// Base64-encode the mail and make it URL-safe
// (replace "+" with "-", replace "/" with "_", remove trailing "=")
var encodedResponse = btoa(
"Content-Type: text/plain; charset=\"UTF-8\"\n" +
"MIME-Version: 1.0\n" +
"Content-Transfer-Encoding: 7bit\n" +
"References: <CADsZLRxZDUGn4Frx80qe2_bE5H5bQhgcqGk=GwFN9gs7Z_8oZw@mail.gmail.com> <CADsZLRyzVPLRQuTthGSHKMCXL7Ora1jNW7h0jvoNgR+hU59BYg@mail.gmail.com> <CADsZLRwQWzLB-uq4_4G2E64NX9G6grn0cEeO0L=avY7ajzuAFg@mail.gmail.com>\n" +
"In-Reply-To: <CADsZLRwQWzLB-uq4_4G2E64NX9G6grn0cEeO0L=avY7ajzuAFg@mail.gmail.com>\n" +
"Subject: Re:Cool\n" +
"From: sender@gmail.com\n" +
"To: reciever@gmail.com\n\n" +
"This is where the response text will go"
).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
$.ajax(
url: "https://www.googleapis.com/gmail/v1/users/me/messages/send?access_token=<USER_ACCESS_TOKEN>",
method: "POST",
contentType: "application/json",
data: JSON.stringify(
raw: encodedResponse
)
);
如您所见,手动操作很麻烦。您也可以只回复线程。但是,这对于您的用例可能还不够。
这样,您只需提供邮件和threadId
,并确保Subject
相同,Google 就会正确显示。
// Base64-encode the mail and make it URL-safe
// (replace "+" with "-", replace "/" with "_", remove trailing "=")
var encodedResponse = btoa(
"Content-Type: text/plain; charset=\"UTF-8\"\n" +
"MIME-Version: 1.0\n" +
"Content-Transfer-Encoding: 7bit\n" +
"Subject: Subject of the original mail\n" +
"From: sender@gmail.com\n" +
"To: reciever@gmail.com\n\n" +
"This is where the response text will go"
).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
$.ajax(
url: "https://www.googleapis.com/gmail/v1/users/me/messages/send?access_token=<USER_ACCESS_TOKEN>",
method: "POST",
contentType: "application/json",
data: JSON.stringify(
raw: encodedResponse,
threadId: "<THREAD_ID_OF_MESSAGE_TO_RESPOND_TO>"
)
);
【讨论】:
我尝试了你给出的第一个解决方案,但我收到了 2 封邮件。一个作为邮件线程的一部分,另一个是新的。第二种方法失败并出现错误“无效参数”。我正在尝试将草稿添加到线程中,但到目前为止没有成功。 Google API 文档似乎也不正确。 @vikramaditya234 你可以试试this。 如果我想要回复的现有消息没有标头 References/In-Reply-To 会怎样? ***.com/questions/44880439/… 感谢您的精彩解释和参考,它真的帮助了我。不幸的是,第一种方法不起作用 - 我收到了单独的电子邮件。但是,一旦我按照您在第二个解决方案中的建议添加了 threadId,我就得到了电子邮件链! @Tholle 在消息对象中传递 'ThreadID' 的解决方法不再起作用,并且消息没有线程化。是因为 Google 引入了新的线程更改【参考方案2】:@Tholle 的回答(谢谢!)是正确的,让我走上了正轨,但在最近的变化之后:
https://gsuiteupdates.googleblog.com/2019/03/threading-changes-in-gmail-conversation-view.html
我不得不把他的两条路混为一谈。
在我的程序中,我必须回复一个线程,但如果我只包含 threadId(如 #2),则新邮件将由 Gmail 仅在回复者的邮件中放入线程中,而在原始邮件中发件人(也是 gmail)作为新线程出现。
我通过在最后一条消息的 id 中包含 threadId 和标头“References”和“In-Reply-To”来解决。
【讨论】:
以上是关于如何使用 Gmail API 发送回复的主要内容,如果未能解决你的问题,请参考以下文章
如何在 C# 中使用带有服务帐户的 gmail api 或 google Oauth 来发送邮件?