如何使用 Gmail API 发送回复

IT技术 javascript gmail gmail-api google-api-js-client
2021-02-22 07:25:28

我有两个 Gmail 帐户,我创建了一个包含五条消息的线程,并在此页面https://developers.google.com/gmail/api/v1/reference/users/threads/get使用 gmail gapi 检索它们

这是我得到的:

在此处输入图片说明

如您所见,id 不匹配,尽管它们标识了完全相同的字母。为什么会发生这种情况,我如何获得统一 ID?

PS 我这样做的真正原因是我需要用 gmail API 回复一条消息,但要做到这一点,你需要知道你回复的消息的 ID。如果我用我拥有的 id(不是接收者拥有的消息 id)回复消息,它只会发送一条“新”消息。

如何使用 Gmail API 发送回复?

先感谢您。

2个回答

正如文档所说,如果您尝试发送回复并希望将电子邮件发送出去,请确保:

  1. Subject标题匹配
  2. ReferencesIn-Reply-To头遵循RFC 2822标准。

如果您想自己执行此操作,则可以获得要回复的消息Subject,ReferencesMessage-ID-headers :

要求:

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 标准,我们添加了Message-ID我们想要响应的消息的References-header,用空格分隔。In-Reply-To-header也有,我们要回应消息的value。我们还添加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>"
  })
});
@Tholle 在消息对象中传递“ThreadID”的解决方法不再起作用,并且消息没有被线程化。是不是因为 Google 引入了新的线程更改
2021-04-28 07:25:28
如果我想要回复的现有消息没有标题 References/In-Reply-To 会发生什么?stackoverflow.com/questions/44880439/...
2021-04-30 07:25:28
感谢您的出色解释和参考,它真的帮助了我。不幸的是,第一种方法不起作用 - 我收到了单独的电子邮件。但是,一旦我按照您在第二个解决方案中的建议添加了 threadId,我就收到了电子邮件链!
2021-05-06 07:25:28
我尝试了您提供的第一个解决方案,但我收到了 2 封邮件。一个作为邮件线程的一部分,另一个是新的。第二种方法失败,错误“参数无效”。我正在尝试将草稿添加到线程中,到目前为止没有成功。Google API 文档似乎也不正确。
2021-05-18 07:25:28
@vikramaditya234 你可以试试这个
2021-05-21 07:25:28

@Tholle(谢谢!)的答案是正确的,让我走上了正确的轨道,但在最近的变化之后:

https://gsuiteupdates.googleblog.com/2019/03/threading-changes-in-gmail-conversation-view.html

我不得不将他的两条道路混为一谈。

在我的程序中,我不得不回复一个线程,但是如果我只包含 threadId(作为 #2),则 Gmail 仅将新邮件放入回复者的邮件中,而在原始发件人的邮件中(也gmail) 作为一个新线程出现。

我通过在最后一条消息的 id 中包含 threadId 和标题“References”和“In-Reply-To”来解决。