使用 gmail API 起草回复不会将草稿附加到话题

Drafting a reply with gmail API doesn't attach draft to thread

提问人:David Enders 提问时间:11/13/2023 最后编辑:Linda Lawton - DaImToDavid Enders 更新时间:11/14/2023 访问量:34

问:

我想使用 Python 中的 gmail API 实现将草稿作为回复附加到现有电子邮件线程的功能,但我打算作为线程回复的草稿被创建为独立草稿。该方法的文档在这里,RFC 2822标准的文档在这里。我相信我已经正确地设置了与正在回复的消息的标题相匹配的标题,与正在回复的消息的标题相匹配的标题,以及与被回复的消息的标题相匹配的标题,然后是(用空格分隔)。create()SubjectSubjectIn-Reply-ToMessage-IDReferencesReferencesMessage-ID

我用于从被回复的邮件中获取标题的代码位于 中,用于设置回复标头和创建草稿的代码位于 中。get_message_headers()reply_draft()

在脚本中,我调用并起草回复,输入返回的值以及新草稿的正文、目标的电子邮件地址和被回复邮件的线程 ID。mainget_message_headers()reply_draft()get_message_headers()

有谁知道我缺少什么来将草稿创建为对线程的回复而不是新草稿?

    def get_message_headers(self, message_id):
        """Get a message and return its References, In-Reply-To, and Subject headers"""
        payload = (
            self.service.users()
            .messages()
            .get(userId="me", id=message_id)
            .execute()["payload"]
        )
        references_value = None
        in_reply_to_value = None
        subject = None

        for header in payload["headers"]:
            if header["name"] == "References":
                refs = header["value"]
            elif header["name"] == "Message-ID":
                in_reply_to_value = header["value"]
            elif header["name"] == "Subject":
                subject = header["value"]
        references_value = refs + " " + in_reply_to_value
        return references_value, in_reply_to_value, subject

    def reply_draft(
        self, content, other, subject, thread_id, references_value, in_reply_to_value
    ):
        """Create and insert a draft email.
        Print the returned draft's message and id.
        Returns: Draft object, including draft id and message meta data.
        """
        try:
            message = EmailMessage()

            message.set_content(content)

            message["To"] = other
            message["From"] = self.me
            message["Subject"] = subject
            message["References"] = references_value
            message["In-Reply-To"] = in_reply_to_value

            # encoded message
            encoded_message = base64.urlsafe_b64encode(message.as_bytes()).decode()
            body = {"message": {"raw": encoded_message}}
            body["threadId"] = str(thread_id)

            draft = (
                self.service.users().drafts().create(userId="me", body=body).execute()
            )

        except HttpError as error:
            print(f"An error occurred: {error}")
            draft = None

        return draft
python gmail google-api-python-client

评论

0赞 Tanaike 11/13/2023
我必须为我糟糕的英语水平道歉。不幸的是,我无法理解你的表演脚本和脚本之间的关系。您能否提供一个示例脚本来正确复制当前问题?首先,我想正确理解您的问题。get_message_headersreply_draft
0赞 David Enders 11/14/2023
是的,@Tanaike我首先调用,然后使用返回的值调用get_message_headers()reply_draft()get_message_headers()
0赞 Tanaike 11/14/2023
感谢您的回复。现在,我注意到答案已经发布。在这种情况下,我想尊重现有的答案和讨论。

答:

1赞 Linda Lawton - DaImTo 11/13/2023 #1

如果我正确理解了您的问题,您有一条消息,并且您想要创建该消息的回复草稿。

您只需要将 threadId 与要回复的消息的 ID 一起添加即可。

try:
    # Call the Gmail API
    service = build('gmail', 'v1', credentials=creds)
    message = EmailMessage()

    message.set_content('This is automated draft mail')

    message['To'] = '[redacted]'
    message['From'] = [redacted]
    message['Subject'] = 'Automated draft'

    # encoded message
    encoded_message = base64.urlsafe_b64encode(message.as_bytes()).decode()

    create_message = {
        'message': {
            'threadId': message_id,   # The id of the main message to reply to
            'raw': encoded_message
        }
    }
    # pylint: disable=E1101
    draft = service.users().drafts().create(userId="me",
                                            body=create_message).execute()

    print(F'Draft id: {draft["id"]}\nDraft message: {draft["message"]}')

except HttpError as error:
    # TODO(developer) - Handle errors from gmail API.
    print(f'An error occurred: {error}')

评论

0赞 David Enders 11/14/2023
嗨琳达,感谢您的回复。你正确地理解了我的问题。但是,我已经设置了字段 ( in ),创建回复的要求还包括设置我上面提到的标头,我认为这可能是我问题的根源,但我不确定缺少什么,因为我似乎已经按照 RFC 2822 中的要求填写了所有内容。threadIDbody["threadId"] = str(thread_id)reply_draft()
0赞 Linda Lawton - DaImTo 11/14/2023
你试过我的代码吗?我运行了上面的代码,它可以工作。客户端库负责为您设置标头。检查你的身体与我的身体相比。你设置错了。
1赞 David Enders 11/15/2023
这很尴尬......不,我没有尝试过你的代码,只是假设我正在做的事情是等效的。我试过了(我所做的唯一改变是按照你的方式设置)并且它奏效了!非常感谢。唯一的注释是每条消息都有一个和一个.您的评论说使用“要回复的主要消息的 id”,但我使用了要回复的主要消息的 id,这奏效了。非常感谢您的帮助!threadIdidthreadIdthreadId
0赞 Linda Lawton - DaImTo 11/15/2023
任何时候我都很高兴你在这里让它最终工作:)