2026/4/15 1:29:25
网站建设
项目流程
招聘网站建设推广,怎么创一个网站,互联网销售可以卖什么产品,响应式网站不加载图片本文档详细介绍了如何通过编程方式调用 Google Gmail API 来发送电子邮件。整个过程不依赖于 SMTP#xff0c;而是使用现代的 OAuth 2.0 授权流程和 REST API 调用#xff0c;这使得它可以在任何网络环境#xff08;包括限制了 SMTP 端口的云服务器#xff09;下工作。
目…本文档详细介绍了如何通过编程方式调用 Google Gmail API 来发送电子邮件。整个过程不依赖于 SMTP而是使用现代的 OAuth 2.0 授权流程和 REST API 调用这使得它可以在任何网络环境包括限制了 SMTP 端口的云服务器下工作。目录前置条件第一步启用 API 和创建 OAuth 凭据第二步获取授权 Token第三步发送邮件附录常见问题FAQ1. 前置条件在开始之前请确保您拥有一个 Google 账户任何标准的gmail.com账户或 Google Workspace 账户都可以。这个账户将是发送邮件的账户。一个 Google Cloud Platform (GCP) 项目这是调用所有 Google API 的管理中心。即使您的代码不运行在 GCP 上也必须拥有一个 GCP 项目来启用 API 和创建凭据。如果您没有可以免费创建一个。Python 环境本地或服务器上需要安装 Python 3。2. 第一步启用 API 和创建 OAuth 凭据此步骤的目标是在您的 GCP 项目中创建一个“应用身份证”即credentials.json文件。登录 GCP 控制台访问 Google Cloud Console 并选择您的项目。启用 Gmail API在顶部的搜索栏中输入Gmail API。在搜索结果中选择 “Gmail API” 并点击“启用”按钮。创建 OAuth 客户端 ID导航到 “API 和服务” “凭据” 页面。点击“ 创建凭据”并选择“OAuth 客户端 ID”。如果系统提示您配置“OAuth 同意屏幕”请按以下步骤操作选择“外部”(External)。填写必要的应用信息应用名称、用户支持电子邮件等。在“测试用户”步骤中添加您将要用来发邮件的那个 Gmail 账户。保存并继续。返回创建凭据页面在“应用类型”(Application type) 中选择“桌面应用”(Desktop app)。给它一个名称例如“Gmail Sender Script”。点击“创建”。下载凭据文件创建成功后会弹出一个窗口显示您的客户端 ID 和密钥。请不要复制它们。点击右侧的“下载 JSON”按钮。将下载的文件重命名为credentials.json并将其保存在您的项目文件夹中。此文件非常机密切勿泄露。3. 第二步获取授权 Token此步骤的目标是让您的 Gmail 账户授权给上一步创建的应用并生成一把“钥匙”即token.json文件。这是一个一次性的本地操作。创建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。 credsNone# 如果 token.json 已存在则先加载它ifos.path.exists(token.json):credsCredentials.from_authorized_user_file(token.json,SCOPES)# 如果没有有效的凭据则启动新的授权流程ifnotcredsornotcreds.valid:# 如果 token 已过期且有 refresh_token则刷新它ifcredsandcreds.expiredandcreds.refresh_token:creds.refresh(Request())else:# 否则从 credentials.json 启动新的网页授权流程flowInstalledAppFlow.from_client_secrets_file(credentials.json,SCOPES)credsflow.run_local_server(port0)# 将新获取的凭据写入 token.json 文件withopen(token.json,w)astoken:token.write(creds.to_json())print(token.json 文件已成功生成或刷新。)if__name____main__:main()安装必要的库在终端中运行以下命令pipinstall--upgradegoogle-api-python-client google-auth-httplib2 google-auth-oauthlib运行脚本在终端中运行脚本python get_token.py在浏览器中完成授权脚本会自动在您的浏览器中打开一个 Google 登录页面。登录您希望用来发邮件的 Gmail 账户。您可能会看到一个“此应用未经 Google 验证”的警告。这是正常的因为这是您自己的应用。请点击“高级”“转至…不安全”。在下一个页面中点击“允许”授予权限。授权成功后您会看到 “The authentication flow has completed” 的消息并且终端会显示 “token.json 文件已成功生成”。现在您的项目文件夹中应该有credentials.json和token.json两个文件了。4. 第三步发送邮件这是最终发送邮件的脚本。我们使用 Python 内置的urllib库因为它在有网络代理的环境下表现更稳定。创建send_email_raw_api.py脚本在同一个文件夹中创建以下脚本# send_email_raw_api.pyimportjsonimportbase64importloggingimporturllib.requestfromemail.mime.textimportMIMETextfromurllib.errorimportURLError,HTTPError# 配置日志记录logging.basicConfig(levellogging.INFO,format%(asctime)s - %(levelname)s - %(message)s)defget_access_token(proxy_urlNone):使用 refresh_token 获取新的 access_tokenlogging.info(尝试刷新 access_token...)try:withopen(token.json,r)asf:token_datajson.load(f)withopen(credentials.json,r)asf:# 兼容从 GCP 下载的两种 JSON 格式creds_datajson.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}datajson.dumps(params).encode(utf-8)requrllib.request.Request(creds_data[token_uri],datadata,headers{Content-Type:application/json})# 配置代理如果提供ifproxy_url:proxy_handlerurllib.request.ProxyHandler({https:proxy_url,http:proxy_url})openerurllib.request.build_opener(proxy_handler)else:openerurllib.request.build_opener()withopener.open(req,timeout30)asresponse:resultjson.loads(response.read().decode(utf-8))logging.info(成功刷新 access_token。)returnresult[access_token]exceptExceptionase:logging.error(f刷新 access_token 失败:{e},exc_infoTrue)returnNonedefsend_email_raw(access_token,to,subject,message_text,proxy_urlNone):使用原始 HTTP 请求和 access_token 发送邮件logging.info(使用原始 API 请求发送邮件...)try:messageMIMEText(message_text,plain,utf-8)message[to]to message[from]memessage[subject]subject raw_messagebase64.urlsafe_b64encode(message.as_bytes()).decode()api_urlhttps://www.googleapis.com/gmail/v1/users/me/messages/sendheaders{Authorization:fBearer{access_token},Content-Type:application/json}body{raw:raw_message}datajson.dumps(body).encode(utf-8)requrllib.request.Request(api_url,datadata,headersheaders,methodPOST)# 配置代理如果提供ifproxy_url:proxy_handlerurllib.request.ProxyHandler({https:proxy_url,http:proxy_url})openerurllib.request.build_opener(proxy_handler)else:openerurllib.request.build_opener()logging.info(f向{api_url}发送 POST 请求...)withopener.open(req,timeout30)asresponse:response_datajson.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_infoTrue)ifhasattr(e,read):logging.error(f错误详情:{e.read().decode()})exceptExceptionase:logging.error(f发送邮件时发生未知错误:{e},exc_infoTrue)returnNoneif__name____main__:# --- 配置 ---RECIPIENT_EMAIL收件人邮箱example.comEMAIL_SUBJECT来自应用的 API 调用问候EMAIL_BODY这是一封通过纯 Python urllib 库调用 Gmail API 发送的邮件。# 如果需要通过代理发送请设置代理地址否则设为 None# PROXY_ADDRESS http://127.0.0.1:7890PROXY_ADDRESSNone# --- 配置结束 ---# 1. 获取最新的 access_tokenaccess_tokenget_access_token(proxy_urlPROXY_ADDRESS)# 2. 如果成功获取则发送邮件ifaccess_token:send_email_raw(access_tokenaccess_token,toRECIPIENT_EMAIL,subjectEMAIL_SUBJECT,message_textEMAIL_BODY,proxy_urlPROXY_ADDRESS)修改配置并运行打开send_email_raw_api.py文件。在文件底部的if __name__ __main__:部分修改RECIPIENT_EMAIL,EMAIL_SUBJECT, 和EMAIL_BODY的值。如果您需要通过代理发送请修改PROXY_ADDRESS。保存文件并在终端运行python send_email_raw_api.py如果一切顺利您将在终端看到成功发送的日志并且收件人会收到邮件。5. 附录常见问题FAQQ: 为什么必须要有 GCP 项目A: GCP 项目是您作为“开发者”的身份标识。所有 Google API 的启用、凭据创建和用量管理都必须依托于一个 GCP 项目。Q:credentials.json和token.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所以您几乎无感。