【问题标题】:Importing e-mails from one gmail mailbox to another将电子邮件从一个 gmail 邮箱导入到另一个
【发布时间】:2019-08-17 17:41:03
【问题描述】:

我有 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 上传消息。我已经看到在某些情况下需要上传,但我完全不知道该怎么做才能完成这项工作。

这是我目前所拥有的(抱歉,我的风格非常老套):

# 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 上的全部内容,并想知道电子​​邮件被定向到哪个电子邮件地址)。但是现在,我只收到有关必须使用上传的错误;我不确定这是否是我真正应该做的,如果是,我不知道该怎么做。

非常感谢您的任何帮助!

【问题讨论】:

  • 为什么不直接在原始电子邮件上发送? developers.google.com/gmail/api/guides/sending
  • 您是否尝试过删除垃圾邮件标签,然后它会被发送?
  • DalmTo:我也没有尝试过实现发送,并且认为“导入”确实是最接近我想要做的事情,所以我就这样做了。如果我改为发送,恐怕我会失去在“发件人”字段中保留原始发件人的能力(或者我是否天真地认为我可以通过 Import 保留它?)
  • DalmTo:我还没有尝试删除标签。我不希望这会起作用,因为我认为在邮件进来的那一刻,gmail 中的转发就可以工作,如果以后修改就不行。不过,我可以试一试,即使对我来说,操作标签也相对容易。
  • TBH 我会删除标签,然后将其发送到以这种方式转发的新电子邮件。将消息上传到 gmail 帐户接缝就像做更多的工作一样。

标签: python gmail-api


【解决方案1】:

最后我成功了。我错过了一个事实,即有两种“获取”消息的方法,一种是简单的,另一种是“原始的”。通过“原始”方式访问消息,我可以轻松使用 import_ 函数:

message = service_dnt.users().messages().get(userId="me", id=messageId,format='raw').execute()
imported = importMessage(service_gmail,"me",{'raw': message['raw']})

importMessage 函数与我发布的原始代码相比没有变化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-08
    • 2021-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-11
    • 2012-11-23
    相关资源
    最近更新 更多