我已在我的 Gmail 服务帐户上设置了 Google 发布订阅。因此,一旦电子邮件发送到此电子邮件,通知消息就会发送到配置的发布订阅主题。遵循本指南https://developers.google.com/gmail/api/guides/push
我编写了一个小型 Flask api,作为订阅的一部分,Google 发布订阅主题将通知消息发送到该 API。
使用消息数据,我获取历史 ID 并尝试通过该历史 ID 读取消息。下面是代码片段:
def get_messages(self, history_id):
messages = []
histories = self.gmail_client.users().history().list(userId=self.userId, startHistoryId=history_id).execute()
print(histories)
if histories and 'history' in histories:
for history in (history for history in histories['history'] if 'messages' in history):
for message in history['messages']:
try:
message_data = self.gmail_client.users().messages().get(userId=self.userId, id=message['id']).execute()
messages.append(message_data)
except Exception:
pass
return messages
但是,在最初的 1-2 次之后,我根本没有使用相应的历史记录 ID 获取任何消息。
我这边有什么遗漏吗?
答案 0 :(得分:0)
在 documentation 之后接收通知,您得到的 historyId
是用户的新邮箱历史 ID,因此是通知时间的最晚。
如果您使用 Pub/Sub 通知消息中的此 historyId
来调用函数 get_messages()
,则此历史记录 ID 将作为 {users.history.list
method 传递给 startHistoryId
returns {1}},然后作为“最新”历史记录 ID(当时),很可能从那时起就没有新发送的邮件(除非您在很短的时间内收到很多电子邮件)。然后结果您没有收到任何消息,您需要使用以前的/较旧的 historyId
,它可能来自以前的通知消息。
startHistoryId
:字符串,必填。返回历史记录后
指定 startHistoryId
。提供的 startHistoryId
应该是
从消息、线程或上一个 historyId
的 list
获得
回复。历史 ID 按时间顺序增加但不连续
有效 ID 之间存在随机间隙。提供无效或超出
日期 startHistoryId
通常返回 HTTP 404
错误代码。一种
historyId
通常至少在一周内有效,但在少数情况下
情况可能只有几个小时有效。如果您收到
HTTP 404
错误响应,您的应用程序应该执行完整的
同步。如果您在响应中没有收到 nextPageToken
,则没有
要检索的更新,您可以存储返回的 historyId
未来的请求。
这里要记住的是,您的代码看起来不错;但是,如果没有用于调用函数 get_messages()
的输入以及方法 users.history.list
的输出,则在运行代码时很难知道发生了什么。我建议跟踪之前的 historyId
并使用它们,而不是立即使用您从 Pub/Sub 通知消息中获得的 historyId
。
共享输入和输出时,请确保删除可能包含的任何敏感或个人数据。
根据文档,您的代码中的一些其他指针,users.history.list
方法 returns 是以下形式的对象:
{
"historyId": "A String",
"nextPageToken": "A String",
"history": [
{
"labelsRemoved": [
{
"message": { # An email message.
},
"labelIds": [
"A String",
],
},
],
"messagesAdded": [
{
"message": { # An email message.
},
},
],
"labelsAdded": [
{
"message": { # An email message.
},
"labelIds": [
"A String",
],
},
],
"id": "A String",
"messagesDeleted": [
{
"message": { # An email message.
},
},
],
"messages": [
{ # An email message.
},
],
},
],
}
其中消息(电子邮件)对象具有以下结构:
"message": { # An email message.
"threadId": "A String",
"labelIds": [
"A String",
],
"sizeEstimate": 42,
"id": "A String",
"raw": "A String",
"payload": {
"mimeType": "A String",
"partId": "A String",
"parts": [],
"headers": [
{
"name": "A String",
"value": "A String",
},
],
"body": {
"data": "A String",
"size": 42,
"attachmentId": "A String",
},
"filename": "A String",
},
"snippet": "A String",
"historyId": "A String",
"internalDate": "A String",
}
另一方面,users.messages.get
方法 https://github.com/Homebrew/brew/issues/7857 是一个具有相同结构的电子邮件对象(参见前面的片段)。
基于此,如果您从 users.history.list
方法(例如 history['messages'][0]['id']
)获取消息 ID,那么您也将获取电子邮件消息对象。因此,您尝试通过使用 history['messages']
方法迭代列表 users.messages.get
以按 ID 获取每条消息,与执行以下操作相同:
messages = history['messages']
或者,如果您想获得更具体的内容,例如 body.data
下 payload
的内容,您可以使用:
history['messages'][0]['payload']['body']['data']
# The index [0] is to point to the first message on the list,
# if you are iterating the list, the index is not necessary
# e.g. message['payload']['body']['data']
通过这种方式,您无需遍历邮件 ID 并使用 users.messages.get
方法逐个获取电子邮件,因为您已经通过 users.history.list
方法获得了它们。< /p>