- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我尝试使用 Gmail API 发送一封简单的测试电子邮件,但对于我找到的每个代码示例,我不断收到相同的错误。
我现在的代码是这样的:
def validationService():
SCOPES = ['https://mail.google.com/']
SERVICE_ACCOUNT_FILE = 'creds.json'
creds = service_account.Credentials.from_service_account_file(SERVICE_ACCOUNT_FILE, scopes=SCOPES)
service = build('gmail', 'v1', credentials=creds)
return service
def SendMessage(service, user_id, message):
try:
message = (service.users().messages().send(userId=user_id, body=message).execute())
print('Message Id:',message['id'])
return message
except errors.HttpError as error:
print('An error occurred:', error)
def CreateMessage(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()}
service = validationService()
email = CreateMessage("<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6310060d0706110e020a0f23040e020a0f4d000c0e" rel="noreferrer noopener nofollow">[email protected]</a>", "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ef9d8a8c8a86998a9d9d828e8683af88828e8683c18c8082" rel="noreferrer noopener nofollow">[email protected]</a>", "Test", "This is a test")
sent = SendMessage(service, "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="7a091f141e1f08171b13163a1d171b131654191517" rel="noreferrer noopener nofollow">[email protected]</a>", email)
返回
>>> An error occurred: <HttpError 400 when requesting https://www.googleapis.com/gmail/v1/users/me/messages/send?alt=json returned "Bad Request">
我也不明白 CreateMessage 中的“sender”参数和 SendMessage 中的 userId 之间的区别。
如果有目的,我正在使用服务帐户凭据
-谢谢!
最佳答案
当使用 service account 时与 Gmail API 。您需要设置domain-wide delegation ,这允许服务帐户模拟 G Suite domain 中的任何用户。因此,您必须拥有 G Suite 帐户才能使用域范围委托(delegate),如文档所述:
If you have a G Suite domain—if you use G Suite, for example—an administrator of the G Suite domain can authorize an application to access user data on behalf of users in the G Suite domain.
那么现在,为什么需要冒充用户(真人)?这是因为服务帐户是一个机器人(不是真人),用于服务器到服务器的交互,使您的应用程序可以调用 Google API,尽管服务帐户有一个名为 client_email
的参数。 ,其结构类似于 <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="deb0bfb3bb9eaeacb1b4bbbdaaf3acbfb0bab1b3b0abb3bcbbacf0b7bfb3f0b9adbbaca8b7bdbbbfbdbdb1abb0aaf0bdb1b3" rel="noreferrer noopener nofollow">[email protected]</a>
这不是一封属于真人的真实电子邮件(我知道这有点令人困惑)。
话虽如此,我对您的代码做了一些更改。首先,我修改了你的validationService
函数以便使用域范围委托(delegate)构建服务。
def validationService():
# Set the crendentials
credentials = service_account.Credentials.\
from_service_account_file(SERVICE_ACCOUNT_FILE, scopes= SCOPES)
# Delegate the credentials to the user you want to impersonate
delegated_credentials = credentials.with_subject(USER_EMAIL)
service = discovery.build('gmail', 'v1', credentials=delegated_credentials)
return service
在您的 SendMessage
中功能不一定是传递要发送电子邮件的用户。使用 me 就足够了,因为 Users.messages: send Parameters状态:
userId string The user's email address. The special value me can be used to indicate the authenticated user.
def SendMessage(service, message):
message = service.users().messages().send(userId="me", body=message).execute()
return message
最后的整个代码可能如下所示:
from googleapiclient import discovery, errors
from oauth2client import file, client, tools
from google.oauth2 import service_account
from email.mime.text import MIMEText
import base64
SERVICE_ACCOUNT_FILE = 'service_account.json'
SCOPES = [' https://mail.google.com/']
# The user we want to "impersonate"
USER_EMAIL = "user@domain"
def validationService():
# Set the crendentials
credentials = service_account.Credentials.\
from_service_account_file(SERVICE_ACCOUNT_FILE, scopes= SCOPES)
# Delegate the credentials to the user you want to impersonate
delegated_credentials = credentials.with_subject(USER_EMAIL)
service = discovery.build('gmail', 'v1', credentials=delegated_credentials)
return service
def SendMessage(service, message):
message = service.users().messages().send(userId="me", body=message).execute()
return message
def CreateMessage(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()}
def main():
try:
service = validationService()
email = CreateMessage(USER_EMAIL, "receiverrmail@domain", "Test", "This is a test")
email_sent = SendMessage(service, email)
print('Message Id:', email_sent['id'])
except errors.HttpError as err:
print('\n---------------You have the following error-------------')
print(err)
print('---------------You have the following error-------------\n')
if __name__ == '__main__':
main()
您还需要通过设置 Managing API client access 来允许您的服务帐号在使用域范围委派时访问 Google 的 API在您的 G Suite 帐户中。
关于python - 使用 python 在 Gmail 中发送邮件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60961428/
只是出于好奇,我想知道gmail是如何做到的。查看页面源代码后,您看不到任何链接、onclick 方法和 javascript。我知道他们隐藏了 javascript,但页面仍然知道有点击。是否有一个
最近谷歌宣布,出于安全目的,Gmail 将使用代理加载外部图像。这导致我的应用程序在 Gmail 中显示图像时出现问题。 Gmail图片元素检查: https://ci5.googleusercont
我想将节点脚本作为 cronjob 运行,它使用 Gmail 的 API 来轮询我拥有的 gmail 帐户。 我关注 these quickstart instructions : 我被困在第一步。在
如果您在 Gmail 上处于非事件状态,则通过一段时间不移动鼠标,您的聊天状态会更改为橙色,这意味着空闲。但是当您再次开始移动鼠标时,它会变回绿色,表示处于事件状态。它如何知道您何时移动鼠标? 最佳答
您知道,当您加载 GMail 时,左侧会显示“撰写邮件”、“收件箱”、“已发送邮件”等吗?我在页面源代码中搜索了“撰写邮件”,但一无所获。 最佳答案 Gmail 界面使用 JavaScript 动态加
我正在创建一个函数,使用 Google 的 API 从一个人的 gmail 帐户导入联系人。但是我知道许多企业注册 Google 是为了拥有更专业的域名(例如 some_name@bislr.com)
我可以通过桌面应用程序使用 Gmail API 成功读取我的收件箱内容。但是,当我尝试阅读其他人的 gmail 收件箱时,我收到 Delegation denied 异常? 所以我的问题是,Gmail
我已经读到我可以使用 gmail atom 提要从谷歌创建的“内置”标签中获取邮件。 但是当我尝试从“已读”标签获取邮件时,使用 https://mail.google.com/mail/feed/a
通过 Gmail API 发送到 Gmail 地址的邮件在 Gmail 中被标记为“小心处理此邮件。它包含通常用于窃取个人信息的内容。” 该消息基本上只是说测试。并且通过 Gmail SMTP 发送的
编辑 :解决下面的第一条评论,为清楚起见,这不是代码问题。问题很简单: 我应该在新 Gmail UI 的 URI 查询字符串中输入什么来查看 Gmail API 创建的草稿邮件? 尽管这并不是一个真正
我是谷歌产品的新手。我打算开始在 gmail 中添加一些东西。使用类似于 Add on 的 Add on 或 chrome Gmail Extension 更好吗?如果是add-on,我们不能直接在s
使用标准查询格式时,Gmail api 和 Gmail Web ui 的结果有所不同,如下所述 - https://support.google.com/mail/answer/7190 . 该问题专
我正在尝试创建一个 PHP 应用程序,它将自动设置用户的电子邮件签名。这部分有效,我可以为用户设置签名。 我的问题是我在 SendAs 设置中找不到任何选项,该选项将禁用 GMail 中签名前插入的两
我的电子邮件标记通过了电子邮件标记测试器,我尝试了 JSON-LD 和微数据,但无论如何 - 我只是看不到标记在 Gmail (iOS) 客户端中的任何效果。 即使是 Google 自己文档中的基本示
我目前正在使用 Gmail 实验室功能 - canned responses.我有很多这样的预设回复并使用 their menu找到合适的,证明是耗时的。通过以下方式找到预设响应会更容易: 将预设回复
请问是否可以在我的 Gmail 状态中发布倒计时? 像“01:44:15:23”及其不断递减。 最佳答案 发现一个好 article to share : Google Talk 使用 XMPP 那么
我开发了一个上下文小工具并将其安装在我的域中。它在我的域中运行良好,但在我的域之外无法正常工作。如何在我的域外访问我的小工具? 最佳答案 您指的是您的 Google Apps 域吗?根据 Google
我在 this guide 之后配置了推送通知并在调用 watch 时端点我得到大约一周的到期时间。 在此期间,我希望收到有关我已配置的 Pub/Sub 主题的通知,而无需调用 watch。在到期日期
是否有可以在 gmail 中捕获的 API 或事件,以便我可以启动工作流甚至触发 python 脚本。 我正在尝试自动化一项工作,该工作将从已到达 gmail 的电子邮件中提取 csv 附件。然后它会
为什么网络版的 Gmail 会在不使用 = 标记中断位置的情况下对邮件内容进行换行,这使得电子邮件处理变得非常困难: 查看gmail发送的原始邮件内容: 这封由 Mac OS X Mail 发送的邮件
我是一名优秀的程序员,十分优秀!