python - 将电子邮件从一个 gmail 邮箱导入到另一个
问题描述
我有 2 个 Gmail 帐户,我使用一个(“gmail1”)将所有电子邮件转发到另一个(“gmail2”)。这很好用,但我最近(多年后!)发现,事实上,Gmail 不会转发我所有的电子邮件,而只会转发它认为不是垃圾邮件的电子邮件。因此,检查我在 gmail2 中的垃圾邮件文件夹是否有丢失的电子邮件时,我经常责怪发件人,而实际上电子邮件在 gmail1 上丢失了。我想以编程方式解决这个问题,通过定期检查 gmail1 中的垃圾邮件并将它们导入 gmail2 (然后我可以将 gmail2 归类为垃圾邮件,只要邮件到达那里)。我只是一个非常业余的程序员,到目前为止,感谢 gmail API 文档中的一些示例,我已经设法登录到我的帐户,并检索了一些与查询相对应的消息,包括例如最近的垃圾邮件。但是,我正在为“导入”概念以及如何使用它而苦苦挣扎。没有这方面的 Python 示例,我无法解决我面临的问题。
我现在在哪里: - 如果我从 gmail1 “获取”一条消息并尝试在 gmail2 上调用 import_ ,使用我刚刚检索到的消息,我会收到一个错误,因为不允许使用 threadId - 如果我这样做,然后“del message['threadId']" 则错误变为错误 400:'raw' RFC822 有效负载消息字符串或通过 /upload/* URL 上传消息。我已经看到在某些情况下需要上传,但我完全不知道应该怎么做才能完成这项工作。
到目前为止,这是我所拥有的(对于非常hacky的风格感到抱歉):
# skipping imports
SCOPES = ['https://www.googleapis.com/auth/gmail.readonly','https://www.googleapis.com/auth/gmail.modify']
def getMessage(service, user_id, msg_id):
"""from gmail API examples"""
try:
message = service.users().messages().get(userId=user_id, id=msg_id).execute()
return message
except errors.HttpError as error:
print ('An error occurred:' , error)
def listMessagesMatchingQuery(service, user_id, query=''):
"""from gmail API examples"""
# skipping some code
return messages
def login(accountId):
"""from gmail API examples, adapted to handle 2 accounts"""
# skipping some code
return build('gmail', 'v1', credentials=creds)
def importMessage(service, user_id, msg):
"""my daring attempt at using import, without any Python sample to use as a basis"""
try:
message = service.users().messages().import_(userId=user_id, body=msg).execute()
return message
except errors.HttpError as error:
print ('An error occurred:' , error)
if __name__ == '__main__':
service_gmail = login('gmail2')
service_dnt = login('gmail1')
messages = listMessagesMatchingQuery(service_dnt,"me","in:spam is:unread after:" + str(int((datetime.now() - timedelta(hours=12)).timestamp())))
# this gets me some recent unread spam messages
m=getMessage(service_dnt,"me",messages[0]['id'])
# now I have a full message - I'm just investigating for now so the first message is enough
del m['threadId']
# if I don't do that, the error I get is that threadId is not allowed here, so I remove it
imported = importMessage(service_gmail,"me",m)
# this now gives me error 400 : 'raw' RFC822 payload message string or uploading message via /upload/* URL required
我想找到使这项工作正常进行的方法,以便电子邮件出现在 gmail2 中,就好像它已被 gmail2 直接接收一样(尽管我想保留收件人:地址,因为我使用的是包罗万象的在 gmail1 上并想知道电子邮件被定向到哪个电子邮件地址)。但是现在,我只收到有关必须使用上传的错误;我不确定这是否是我真正应该做的,如果是,我不知道该怎么做。
非常感谢您的帮助!
解决方案
最后我成功了。我错过了一个事实,即有两种“获取”消息的方法,一种是简单的,另一种是“原始的”。通过“原始”方式访问消息,我可以轻松使用 import_ 函数:
message = service_dnt.users().messages().get(userId="me", id=messageId,format='raw').execute()
imported = importMessage(service_gmail,"me",{'raw': message['raw']})
与我发布的原始代码相比,importMessage 函数没有改变。
推荐阅读
- javascript - TypeError:_reactDom.default.createElement 不是函数
- flutter - Flutter firebase_admob 横幅仍然显示在每个屏幕上
- algorithm - 在不移动点的情况下将循环添加到最小生成树?
- python - 如何绘制按熊猫中的列名分组的箱线图?
- python-3.x - 如何在 Tkinter、Python 3.8 中创建文本 wiget
- arrays - 继续在 Google 表格中的各列中将公式增加 N 行
- java - azure 应用服务上的 springboot 应用在启动后立即停止
- java - Java 中的安全数据和 BufferedReader
- r - 带有标签注释的单柱堆叠条形图
- javascript - 无法在 JavaScript 中显示图形