news 2026/4/22 13:24:12

通过 Gmail API 发送邮件的完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
通过 Gmail API 发送邮件的完整指南

本文档详细介绍了如何通过编程方式调用 Google Gmail API 来发送电子邮件。整个过程不依赖于 SMTP,而是使用现代的 OAuth 2.0 授权流程和 REST API 调用,这使得它可以在任何网络环境(包括限制了 SMTP 端口的云服务器)下工作。

目录

  1. 前置条件
  2. 第一步:启用 API 和创建 OAuth 凭据
  3. 第二步:获取授权 Token
  4. 第三步:发送邮件
  5. 附录:常见问题(FAQ)

1. 前置条件

在开始之前,请确保您拥有:

  • 一个 Google 账户:任何标准的@gmail.com账户或 Google Workspace 账户都可以。这个账户将是发送邮件的账户。
  • 一个 Google Cloud Platform (GCP) 项目:这是调用所有 Google API 的管理中心。即使您的代码不运行在 GCP 上,也必须拥有一个 GCP 项目来启用 API 和创建凭据。如果您没有,可以免费创建一个。
  • Python 环境:本地或服务器上需要安装 Python 3。

2. 第一步:启用 API 和创建 OAuth 凭据

此步骤的目标是在您的 GCP 项目中创建一个“应用身份证”,即credentials.json文件。

  1. 登录 GCP 控制台:访问 Google Cloud Console 并选择您的项目。
  2. 启用 Gmail API
    • 在顶部的搜索栏中输入Gmail API
    • 在搜索结果中选择 “Gmail API” 并点击“启用”按钮。
  3. 创建 OAuth 客户端 ID
    • 导航到 “API 和服务” > “凭据” 页面。
    • 点击“+ 创建凭据”并选择“OAuth 客户端 ID”
    • 如果系统提示您配置“OAuth 同意屏幕”,请按以下步骤操作:
      • 选择“外部”(External)。
      • 填写必要的应用信息(应用名称、用户支持电子邮件等)。
      • 在“测试用户”步骤中,添加您将要用来发邮件的那个 Gmail 账户
      • 保存并继续。
    • 返回创建凭据页面,在“应用类型”(Application type) 中选择“桌面应用”(Desktop app)。
    • 给它一个名称(例如,“Gmail Sender Script”)。
    • 点击“创建”
  4. 下载凭据文件
    • 创建成功后,会弹出一个窗口显示您的客户端 ID 和密钥。请不要复制它们
    • 点击右侧的“下载 JSON”按钮。
    • 将下载的文件重命名为credentials.json并将其保存在您的项目文件夹中。此文件非常机密,切勿泄露。

3. 第二步:获取授权 Token

此步骤的目标是让您的 Gmail 账户授权给上一步创建的应用,并生成一把“钥匙”,即token.json文件。这是一个一次性的本地操作。

  1. 创建get_token.py脚本
    在与credentials.json相同的文件夹中,创建以下 Python 脚本:

    # get_token.pyimportos.pathfromgoogle.auth.transport.requestsimportRequestfromgoogle.oauth2.credentialsimportCredentialsfromgoogle_auth_oauthlib.flowimportInstalledAppFlow# 定义需要的权限范围,https://mail.google.com/ 是最高权限SCOPES=["https://mail.google.com/"]defmain():""" 引导用户完成 OAuth 2.0 授权流程并生成 token.json。 """creds=None# 如果 token.json 已存在,则先加载它ifos.path.exists("token.json"):creds=Credentials.from_authorized_user_file("token.json",SCOPES)# 如果没有有效的凭据,则启动新的授权流程ifnotcredsornotcreds.valid:# 如果 token 已过期且有 refresh_token,则刷新它ifcredsandcreds.expiredandcreds.refresh_token:creds.refresh(Request())else:# 否则,从 credentials.json 启动新的网页授权流程flow=InstalledAppFlow.from_client_secrets_file("credentials.json",SCOPES)creds=flow.run_local_server(port=0)# 将新获取的凭据写入 token.json 文件withopen("token.json","w")astoken:token.write(creds.to_json())print("token.json 文件已成功生成或刷新。")if__name__=="__main__":main()
  2. 安装必要的库
    在终端中运行以下命令:

    pipinstall--upgradegoogle-api-python-client google-auth-httplib2 google-auth-oauthlib
  3. 运行脚本
    在终端中运行脚本:

    python get_token.py
  4. 在浏览器中完成授权

    • 脚本会自动在您的浏览器中打开一个 Google 登录页面。
    • 登录您希望用来发邮件的 Gmail 账户
    • 您可能会看到一个“此应用未经 Google 验证”的警告。这是正常的,因为这是您自己的应用。请点击“高级”>“转至…(不安全)”
    • 在下一个页面中,点击“允许”,授予权限。
    • 授权成功后,您会看到 “The authentication flow has completed” 的消息,并且终端会显示 “token.json 文件已成功生成”。

现在,您的项目文件夹中应该有credentials.jsontoken.json两个文件了。


4. 第三步:发送邮件

这是最终发送邮件的脚本。我们使用 Python 内置的urllib库,因为它在有网络代理的环境下表现更稳定。

  1. 创建send_email_raw_api.py脚本
    在同一个文件夹中,创建以下脚本:

    # send_email_raw_api.pyimportjsonimportbase64importloggingimporturllib.requestfromemail.mime.textimportMIMETextfromurllib.errorimportURLError,HTTPError# 配置日志记录logging.basicConfig(level=logging.INFO,format='%(asctime)s - %(levelname)s - %(message)s')defget_access_token(proxy_url=None):"""使用 refresh_token 获取新的 access_token"""logging.info("尝试刷新 access_token...")try:withopen('token.json','r')asf:token_data=json.load(f)withopen('credentials.json','r')asf:# 兼容从 GCP 下载的两种 JSON 格式creds_data=json.load(f).get('installed')orjson.load(f).get('web')params={'client_id':creds_data['client_id'],'client_secret':creds_data['client_secret'],'refresh_token':token_data['refresh_token'],'grant_type':'refresh_token'}data=json.dumps(params).encode('utf-8')req=urllib.request.Request(creds_data['token_uri'],data=data,headers={'Content-Type':'application/json'})# 配置代理(如果提供)ifproxy_url:proxy_handler=urllib.request.ProxyHandler({'https':proxy_url,'http':proxy_url})opener=urllib.request.build_opener(proxy_handler)else:opener=urllib.request.build_opener()withopener.open(req,timeout=30)asresponse:result=json.loads(response.read().decode('utf-8'))logging.info("成功刷新 access_token。")returnresult['access_token']exceptExceptionase:logging.error(f"刷新 access_token 失败:{e}",exc_info=True)returnNonedefsend_email_raw(access_token,to,subject,message_text,proxy_url=None):"""使用原始 HTTP 请求和 access_token 发送邮件"""logging.info("使用原始 API 请求发送邮件...")try:message=MIMEText(message_text,'plain','utf-8')message['to']=to message['from']='me'message['subject']=subject raw_message=base64.urlsafe_b64encode(message.as_bytes()).decode()api_url='https://www.googleapis.com/gmail/v1/users/me/messages/send'headers={'Authorization':f'Bearer{access_token}','Content-Type':'application/json'}body={'raw':raw_message}data=json.dumps(body).encode('utf-8')req=urllib.request.Request(api_url,data=data,headers=headers,method='POST')# 配置代理(如果提供)ifproxy_url:proxy_handler=urllib.request.ProxyHandler({'https':proxy_url,'http':proxy_url})opener=urllib.request.build_opener(proxy_handler)else:opener=urllib.request.build_opener()logging.info(f"向{api_url}发送 POST 请求...")withopener.open(req,timeout=30)asresponse:response_data=json.loads(response.read().decode('utf-8'))logging.info(f"邮件发送成功!Message ID:{response_data.get('id')}")returnresponse_dataexcept(URLError,HTTPError)ase:logging.error(f"发送邮件时发生网络错误:{e}",exc_info=True)ifhasattr(e,'read'):logging.error(f"错误详情:{e.read().decode()}")exceptExceptionase:logging.error(f"发送邮件时发生未知错误:{e}",exc_info=True)returnNoneif__name__=='__main__':# --- 配置 ---RECIPIENT_EMAIL="收件人邮箱@example.com"EMAIL_SUBJECT="来自应用的 API 调用问候"EMAIL_BODY="这是一封通过纯 Python urllib 库调用 Gmail API 发送的邮件。"# 如果需要通过代理发送,请设置代理地址,否则设为 None# PROXY_ADDRESS = "http://127.0.0.1:7890"PROXY_ADDRESS=None# --- 配置结束 ---# 1. 获取最新的 access_tokenaccess_token=get_access_token(proxy_url=PROXY_ADDRESS)# 2. 如果成功获取,则发送邮件ifaccess_token:send_email_raw(access_token=access_token,to=RECIPIENT_EMAIL,subject=EMAIL_SUBJECT,message_text=EMAIL_BODY,proxy_url=PROXY_ADDRESS)
  2. 修改配置并运行

    • 打开send_email_raw_api.py文件。
    • 在文件底部的if __name__ == '__main__':部分,修改RECIPIENT_EMAIL,EMAIL_SUBJECT, 和EMAIL_BODY的值。
    • 如果您需要通过代理发送,请修改PROXY_ADDRESS
    • 保存文件并在终端运行:
    python send_email_raw_api.py

如果一切顺利,您将在终端看到成功发送的日志,并且收件人会收到邮件。


5. 附录:常见问题(FAQ)

  • Q: 为什么必须要有 GCP 项目?

    • A: GCP 项目是您作为“开发者”的身份标识。所有 Google API 的启用、凭据创建和用量管理都必须依托于一个 GCP 项目。
  • Q:credentials.jsontoken.json有什么区别?请用通俗的比喻解释。

    • A: 当然,这是一个核心概念。我们可以用一个“机器人管家”的例子来理解:
      • credentials.json是什么?—— 机器人的“出厂说明书 & 身份证”

        • 这个文件是在您的 GCP 工厂里生成的,它定义了您的机器人管家是谁。
        • 它包含了客户端 ID(相当于机器人的身份证号,是公开的)和客户端密钥(相当于机器人的出厂机密代码,是绝对私密的)。
        • 这份“说明书”是永久有效的,它只代表机器人的身份,但本身没有任何权力。任何不认识这个机器人的家庭都不会让它进门。
      • token.json是什么?—— 特定家庭的“门禁卡”

        • 这个文件是在您(家庭主人)亲自“面试”过机器人,并同意授权后,才颁发给这个特定机器人的“门禁卡”。
        • 它包含了access_token(一张临时通行证,可能一小时就过期)和refresh_token(一张长期身份卡)。
        • 当机器人需要进门工作时,它会出示“临时通行证” (access_token)。如果通行证过期了,它就会出示它的“长期身份卡” (refresh_token) 和自己的“身份证” (credentials.json),去物业处(Google)换一张新的“临时通行证”。
      • 它们如何协同工作?

        • 您的代码(机器人)在工作时,必须同时携带自己的“身份证” (credentials.json) 和您家颁发的“门禁卡” (token.json)。
        • 如果门禁卡里的临时通行证过期了,它就需要用门禁卡里的长期身份卡加上自己身份证上的机密代码,才能换到新的临时通行证。
        • 总结:credentials.json是“我是谁”,token.json是“我被谁授权可以做什么”。两者缺一不可。
  • Q: 我可以把这两个 JSON 文件提交到 Git 仓库吗?

    • A:绝对不能!这两个文件都是高度机密的,泄露它们等同于泄露了您应用乃至用户邮箱的控制权。请务必将它们添加到.gitignore文件中。
  • Q:token.json会过期吗?

    • A: 是的,token.json里的access_token通常只有1小时的有效期。但它包含的refresh_token有效期很长。我们提供的脚本会自动使用refresh_token去换取新的access_token,所以您几乎无感。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/21 19:32:29

深度学习毕设选题推荐:python基于ATT-LSTM的语音情感分类

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华
网站建设 2026/4/22 15:32:35

OpenCore Legacy Patcher终极指南:让老款Mac焕发新生

想让你的老款Mac电脑运行最新版macOS系统吗?OpenCore Legacy Patcher正是你需要的完美解决方案!这款开源工具能够为不受官方支持的Mac设备提供完整的系统升级能力,让你的旧设备重新获得与现代设备相同的功能体验。 【免费下载链接】OpenCore-…

作者头像 李华
网站建设 2026/4/18 7:31:08

如何快速掌握DockDoor:macOS窗口管理神器完全指南

如何快速掌握DockDoor:macOS窗口管理神器完全指南 【免费下载链接】DockDoor Window peeking for macOS 项目地址: https://gitcode.com/gh_mirrors/do/DockDoor 还在为macOS上繁琐的窗口切换而苦恼吗?DockDoor是一款专为macOS设计的强大窗口预览…

作者头像 李华
网站建设 2026/4/18 0:03:39

小爱音箱音乐自由:三步解锁海量无损音乐库

小爱音箱音乐自由:三步解锁海量无损音乐库 【免费下载链接】xiaomusic 使用小爱同学播放音乐,音乐使用 yt-dlp 下载。 项目地址: https://gitcode.com/GitHub_Trending/xia/xiaomusic 还在为小爱音箱的音乐版权限制而烦恼吗?想听的歌曲…

作者头像 李华
网站建设 2026/4/17 0:39:06

HMCL Linux权限优化:从问题诊断到安全配置的完整指南

HMCL Linux权限优化:从问题诊断到安全配置的完整指南 【免费下载链接】HMCL huanghongxun/HMCL: 是一个用于 Minecraft 的命令行启动器,可以用于启动和管理 Minecraft 游戏,支持多种 Minecraft 版本和游戏模式,可以用于开发 Minec…

作者头像 李华