当前位置: 首页 > java >正文

使用GMail API 发送邮箱

1️⃣ 准备工作

创建 Google Cloud 项目

打开 Google Cloud Console → Cloud 概览 →欢迎 → 创建新项目

启用 Gmail API

直接搜索:Gmail API

启用服务并选择相应的项目

创建 OAuth 2.0 客户端 ID创建之前需要前置操作 ,先选择项目  点击开始配置Google Auth Platform

找到“OAuth 客户端 ID”并点击

类型选择 桌面应用程序(快捷方便)下载 client_secret_xxx.json

client_secret_xxx.jsonGoogle OAuth 2.0 客户端凭证 文件,里面包含了你在 Google Cloud Console 创建的 OAuth 2.0 凭证信息,主要用于认证和授权。

安装依赖(我这里使用的是python 环境)

pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib

2️⃣ 授权流程(第一次)

下面是client_sercret_xxx.json 与token之间的关系

文件作用生命周期使用方式
client_secret_xxx.json应用身份长期不变首次授权时必须
token.pickle用户身份 + 授权access_token 1 小时,refresh_token 长期有效发邮件、刷新 token

为啥要进行手动授权:

阶段原因/作用说明
首次手动授权保护用户账户安全Gmail 涉及敏感数据(邮箱、邮件内容),Google 不允许应用直接用用户名/密码访问。手动授权让用户明确允许应用访问哪些权限。
首次获取 refresh_tokenOAuth 2.0 设计中,refresh_token 只会在用户同意授权后发放一次,确保应用无法偷偷获取长期访问权限。
防止滥用如果每次都能自动授权,恶意应用可能会无声访问用户邮箱。手动授权是防护措施。
后续自动使用不需要再次手动授权第一次授权后拿到 refresh_token(长期有效),后续可以用它自动刷新 access_token,无需再次登录或输入验证码。

手动授权如图:

代码示例:

from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
import pickle
import os.path
import pickle
# 权限范围
SCOPES = ['https://www.googleapis.com/auth/gmail.send']def send_email_via_api():creds = None# 检查是否已有凭据if os.path.exists('config/new_token.pickle'):with open('new_token.pickle', 'rb') as token:creds = pickle.load(token)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(#     'config/client_secret_2_xxx.json', SCOPES)# creds = flow.run_local_server(port=0)flow = InstalledAppFlow.from_client_secrets_file(r'config/new2.json',SCOPES)creds = flow.run_local_server(port=8080,open_browser=True,access_type='offline',prompt='consent')# 保存凭据供下次使用with open('config/token.pickle', 'wb') as token:pickle.dump(creds, token)

说明

  • access_type='offline' → 获取长期 refresh_token

  • prompt='consent' → 保证用户每次授权时都会返回 refresh_token

  • 第一次授权后,会弹出浏览器让用户登录 Gmail 并同意权限

  • 每次使用 creds.valid 检查 access_token 是否过期

  • 如果过期且有 refresh_token,调用:

creds.refresh(Request())
with open('token.pickle', 'wb') as token:pickle.dump(creds, token)
  • 不需要再次输入验证码,refresh_token 是长期有效的


3️⃣ 发送邮件

使用 Gmail API 发送邮件,需要构造 MIME 消息并 Base64 编码:

# 1. 获取访问令牌(从已有的token.pickle中提取)
with open('./config/token.pickle', 'rb') as f:creds = pickle.load(f)
access_token = creds.token# 2. 手动构建邮件内容6
message = MIMEText('20250822测试')
message['to'] = 'xxx@163.com'
# message['from'] = 'a'
message['subject'] = '客户验收程序20250822测试'
raw_message = base64.urlsafe_b64encode(message.as_bytes()).decode()# 3. 配置请求参数(可手动设置代理)
url = 'https://www.googleapis.com/gmail/v1/users/me/messages/send'
headers = {'Authorization': f'Bearer {access_token}','Content-Type': 'application/json'
}
data = {'raw': raw_message}# 4. 发送请求(支持代理配置)
proxies = {# 根据VPN/代理类型设置,如SOCKS5需安装requests[socks]'https': 'socks5://127.0.0.1:1080'  # 示例:本地SOCKS5代理
}try:response = requests.post(url,headers=headers,data=json.dumps(data),# proxies=proxies,  # 可选:需要时启用timeout=30)response.raise_for_status()  # 抛出HTTP错误print("HTTP直接调用成功:", response.json())
except requests.exceptions.RequestException as e:print(f"HTTP请求失败:{e}")if response:print("响应内容:", response.text)

 注意事项

  1. token.pickle

    • 保存 access_tokenrefresh_token,确保刷新后更新文件

  2. 发送限制

    • Gmail API 每日免费发送上限约 500 封(G Suite 可更高)

  3. 安全性

    • 不要在前端暴露 client_secretrefresh_token

    • 服务器端统一管理发送逻辑

  4. 附件邮件

    • 如果要发送附件,需要构造 MIMEMultipart 并附加 MIMEBase 对象

http://www.xdnf.cn/news/18508.html

相关文章:

  • OpenSCA开源社区每日安全漏洞及投毒情报资讯|21th Aug. , 2025
  • 前端github-workflows部署腾讯云轻量服务器
  • 实用R语言机器学习指南:从数据预处理到模型实战(附配套学习资源)
  • docker 查看容器 docker 筛选容器
  • 循环神经网络实战:GRU 对比 LSTM 的中文情感分析(三)
  • Flask数据库迁移实战指南
  • LeetCode100-76最小覆盖子串
  • 数据库备份sql文件过大,phpAdmin无法执行Sql
  • Python递归下降解析器深度解析:从原理到工程实践
  • 异常值检测:孤立森林模型(IsolationForest)总结
  • Flowise 任意文件上传漏洞 含Flowise Docker安装、漏洞复现(CVE-2025-26319)
  • 如何使用 DeepSeek 助力工作:全面指南​
  • AWS OpenSearch 是什么
  • ROS2下YOLO+Moveit+PCL机械臂自主避障抓取方案
  • 如何理解AP服务发现协议中“如果某项服务需要被配置为可通过多个不同的网络接口进行访问,则应为每个网络接口使用一个独立的客户端服务实例”?
  • Unreal Engine APawn 与 ACharacter 比较
  • 停车场道闸的常见形式
  • Docker的安装
  • 什么是数据分类分级?数据分类分级技术实现路径及产品推荐
  • 逆向代码笔记
  • centos7安装oracle19c流程(自用)
  • 全面解析 `strchr` 字符串查找函数
  • 闲置笔记本链接硬盘盒充当Windows NAS 网易UU远程助力数据读取和处理
  • vivo招AI架构专家(AI Agent方向)
  • 云原生(Cloud Native)技术概述
  • 密码管理中硬编码密码
  • react的基本使用
  • 【学习记录】structuredClone,URLSearchParams,groupBy
  • 树莓派采集、计算机推理:基于GStreamer的YOLOv5实现方案
  • 隧道代理无需手动获取IP的核心机制与技术优势