Gmail API 连接

Posted

技术标签:

【中文标题】Gmail API 连接【英文标题】:Gmail API Connection 【发布时间】:2022-01-01 10:14:06 【问题描述】:

我一直在尝试通过 Gmail API 配置发送测试电子邮件,但收效甚微。我不确定到底出了什么问题,但我收到的错误如下:

文件“c:\Development\foodSaver\emailAPI.py”,第 20 行,在 send_message 中 message = (service.users().messages().send(userId=user_id, body=message).execute()) AttributeError: 'str' 对象没有属性 'users'

在处理上述异常的过程中,又发生了一个异常:

Traceback(最近一次调用最后一次):文件 “c:\Development\foodSaver\emailAPI.py”,第 28 行,在 send_message('Gmail', 'Person','yes') 文件“c:\Development\foodSaver\emailAPI.py”,第 23 行,在 send_message 除了errors.HttpError作为错误:NameError:未定义名称'errors'

我已将 Credentials.json 文件与我的项目放在同一目录中,但从未被要求在此脚本中引用它。

我目前的代码(产生这个错误):

from email import encoders
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import base64
import os

# Writes gmail message 
def create_message(sender, to, subject, message_text):
  message = MIMEText(message_text)
  message['to'] = to
  message['from'] = sender
  message['subject'] = subject
  message = message.as_string()
  message = message.encode('utf-8')
  return 'raw': base64.urlsafe_b64encode(message)

# Sends gmail message 
def send_message(service, user_id, message):
  try:
    message = (service.users().messages().send(userId=user_id, body=message).execute())
    print('Message Id: %s' % message['id'])
    return message
  except errors.HttpError as error:
    print('An error occurred: %s' % error)

create_message('abittar@nyit.edu','abittar@nyit.edu','This is a test email.','This is the test body message.')
send_message('Gmail', 'Person','yes')

在最后一部分,我尝试为 def 变量输入随机的东西以进行测试。

【问题讨论】:

【参考方案1】:

当您在 send_message 函数中传递错误的参数时,会发生第一个和第二个错误。 service 的内容应该是资源对象,user_id 的内容应该是电子邮件或“我”。

您需要创建凭据并使用它来构建与 Gmail API 交互的资源。您可以从关注此Python Quickstart for Gmail 开始,了解如何设置您的凭据和安装必要的库。完成设置后,您的代码应如下所示:

注意:您可以复制并粘贴代码并替换发件人和收件人电子邮件。确保credentials.json 的内容与您的主脚本处于同一级别。在下面的示例中,我使用this 来获取credentials.json 的内容

from __future__ import print_function
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from googleapiclient.errors import HttpError
from email.mime.text import MIMEText
import base64
import os

# If modifying these scopes, delete the file token.json.
SCOPES = ['https://www.googleapis.com/auth/gmail.send']


# Writes gmail message
def create_message(sender, to, subject, message_text):
    message = MIMEText(message_text)
    message['to'] = to
    message['from'] = sender
    message['subject'] = subject
    return 'raw': base64.urlsafe_b64encode(message.as_string().encode()).decode()


# Sends gmail message
def send_message(service, user_id, message):
    try:
        message = (service.users().messages().send(userId=user_id, body=message).execute())
        print('Message Id: %s' % message['id'])
        return message
    except HttpError as error:
        print('An error occurred: %s' % error)


def main():
    """Shows basic usage of the Gmail API.
    Lists the user's Gmail labels.
    """
    creds = None
    # The file token.json stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token.json'):
        creds = Credentials.from_authorized_user_file('token.json', SCOPES)
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token.json', 'w') as token:
            token.write(creds.to_json())

    service = build('gmail', 'v1', credentials=creds)

    msg = create_message('sender email', 'recipient email', 'This is a test email.',
                         'This is the test body message.')
    send_message(service, 'me', msg)


if __name__ == '__main__':
    main()

【讨论】:

@abittar2022 - 如果您觉得 accepting and upvoting 我的回答对您有用,请考虑。

以上是关于Gmail API 连接的主要内容,如果未能解决你的问题,请参考以下文章

GMAIL API NodeJs

如何在Gmail API中强制删除Google默认选定的帐户?

Google API (Gmail) 因失败的前提条件 400 而失败

用于在 Node.js 中发送邮件的 Gmail API

使用 imaplib 和 oauth 连接 Gmail

使用 imaplib 和 oauth 连接 Gmail