利用飞书集成平台达成Outlook邮件实时飞书消息提醒

利用飞书集成平台达成Outlook邮件实时飞书消息提醒

开发者广场内容精选NaN-NaN-NaN
解决方案
作者:Junxian DIAO 刁俊先
推荐理由
我们团队重度使用飞书,但是很多重要的消息提醒仍然依赖公司邮箱系统,能否做到把 Outlook 邮件在制定好规则后实时转发到飞书消息?
原始诉求
1.团队重度使用飞书,但是很多重要的消息提醒仍然依赖公司邮箱系统,能否做到把Outlook 邮件在制定好规则后实时转发到飞书消息?
2.需要具备实时性,如果实时性无法达成,可接受每天定时转发亦可。
解决思路
通过飞书捷径
2.但是目前飞书捷径已经去除了 Outlook 的连接器;
250px|700px|reset
通过 Microsoft Graph API 提取邮件
思路是通过 Microsoft Graph API 提取并识别最新邮件,找到符合规则的邮件,然后通过飞书消息实现转发;
实现路径
手动实践过程
第一步:创建 Azure Active Directory 应用
注册成功后,在应用概述页面可以看到client idtenant id
250px|700px|reset
第二步:创建证书和密码
第三步:添加阅读邮件的委托权限
这里特别注意添加的应用委托权限,而不是应用程序权限,是因为应用程序权限是对工作账户内所有账号都有权限的,可能会有安全隐私等问题。使用 oauth 获取的 access_token 可以仅对登陆的账号有效,应用注册时也无需单独配置权限。
250px|700px|reset
第四步:添加重定向地址,方便提取 access token 和 refresh token
第五步:本地登录,提取 access token 和 refresh token
from authlib.integrations.flask_client import OAuth
from flask import Flask, url_for, request
import urllib
import json
tenant_id = 'xxxx'
client_id = 'xxxxx'
client_secret = 'xxxxx'
app = Flask(__name__)
app.secret_key = 'xxxxx'
app.config['SESSION_TYPE'] = 'filesystem'
oauth = OAuth(app)
oauth.register(
name='azure',
client_id=client_id,
client_secret=client_secret,
# client_kwargs={
# 'scope': 'offline_access https://microsoftgraph.chinacloudapi.cn/Mail.Read'},
client_kwargs={
)
@app.route('/')
def login():
redirect_uri = url_for('authorize', _external=True)
return oauth.azure.authorize_redirect(redirect_uri)
@app.route('/login/authorized')
def authorize():
token = oauth.azure.authorize_access_token()
print(token)
with open("token.json", "w", encoding="utf8") as f:
f.write(json.dumps(token)) # token 保存到了 token.json 文件中
return token
@app.route("/notify", methods=['POST'])
def onedrive():
valtoken = request.args.get('validationToken')
resp = app.response_class(response=urllib.parse.unquote(valtoken), status=200, mimetype='plain/text')
return resp
app.run(host='localhost', port=5000, debug=True)
1.服务启动后,本地访问,会提示验证登录动作;
2.这里特别注意的是,国外的 Microsoft Graph API 访问的域名和国内是不一致的(21Vianet 运营的 Office 365 API 端点),会出现 github 上很多正确的示例代码,怎么尝试都是错误的。
3.这里的过程只会使用一次,提取一次 refresh token 以后,后续,通过 refresh token 反复刷新 token 即可;
第六步:飞书集成平台创建集成流,监听创建订阅后的消息事件
2.创建订阅
headers={
'Authorization': 'Bearer %s' % access_token,
'Content-type': 'application/json'
}
data = {
"changeType": "created",
"notificationUrl": "https://open.feishu.cn/anycross/xxxx",
"resource": "me/mailFolders('Inbox')/messages",
"expirationDateTime":"2023-01-18T18:23:45.9356913Z",
}
resp = requests.post(url, headers=headers, json=data)
print(resp.status_code, resp.json())
3.这里的 notificationUrl 是飞书集成平台集成流中对应的监听地址,这里需要将 Microsoft 的请求事件中的 query 部分完整返回(设置资源数据更改的通知)。且需要注意的是,要确保 notificationUrl 有效:
A status code ofHTTP 200 OK.
A content type oftext/plain.
A body that includes the URL decoded validation token. Simply reflect back the same string that was sent in thevalidationTokenquery parameter.
第七步:接收到 Microsoft Graph API 事件,请求提取完整的邮件信息
250px|700px|reset
根据 resource 字段值,拼接完整的请求路径,提取完整的邮件体;
response = requests.get(url, headers={
'Authorization': 'Bearer %s' % access_token
})
print(response.json())
第八步:制定转发规则,将需要提醒的邮件转发到对应的群组或者个人
飞书集成平台集成流完整闭环
250px|700px|reset
1.JOSN助手:先将发过来的 webhook 消息体反序列化;
2.同步回调:立即返回 http status code 200;
这里主要的原因是,需要应处理收到的每个更改通知。 应用程序必须至少执行以下任务来处理更改通知(设置资源数据更改的通知
你的进程应处理它收到的每个更改通知并发送 2xx 类代码。 如果Microsoft Graph在 3 秒内未收到 2xx 类代码,它将尝试在大约 4 小时的时间内多次发布更改通知;之后,更改通知将被删除,并且不会送达。 如果进程在 3 秒内一致未响应,则通知可能会受到限制。
如果处理预计需要 3 秒以上,则应保留通知,在响应Microsoft Graph时返回202 - Accepted状态代码,然后处理通知。 如果通知未保留,则返回 5xx 类代码以指示错误,以便重试通知。
如果处理预计花费不到 3 秒,则应处理通知,并在响应Microsoft Graph时返回200 - OK状态代码。 如果通知未正确处理,则返回 5xx 类代码以指示错误,以便重试通知。
验证clientState属性。 它必须与最初使用订阅创建请求提交的值匹配。
3.数据源:提取已经存储的 refresh token;
4.Http client 连接器:根据 refresh token 换取 access token;
5.动态脚本:根据得到的 access token 和webhook 消息体重的 resource 字段,拼接请求参数;
function handler(input) {
var url_path = input.url_path;
var token = input.token;
var access_token = `Bearer ${token}`;
return {
url: url,
access_token: access_token,
};
}
6.Http client 连接器:根据参数,发起 Get 请求,得到完整邮件内容;
7.动态脚本:根据返回值,提取需要的邮件消息体重要字段内容,拼接消息卡片消息体,需要注意的是,其中关于邮件正文的内容,直接根据 js 提取的除去 html string 格式化的内容;
var html_content = response.body.content;
var content = html_content
.replace(/<[^<>]+>/g, '')
.replace(/&nbsp;/gi, '')
.replace(/&gt;/gi, '')
.replace(/(^\s*)|(\s*$)/g, '');
8.自定义飞书机器人:根据消息体发出邮件转发的卡片消息。
总结回顾
1.Microsoft 已经提供了非常完备的消息订阅流程,只要我们想,所有该有的事件都可以实时提取;
2.创建事件订阅后,需要及时的延长订阅事件的有效期,这里也是 Microsoft 版本更新后可能会让开发者误踩的坑之一;
3.先用 Python requests 请求将整个链路走通后,在飞书集成平台完整的实现,主要原因是,飞书集成平台的使用体验依然很稳定,我们不需要单独部署服务来实现过程的集成,一方面可以降低我们服务运维的成本,另一方面也是为了方便后续将此类工作解耦,交付其他团队使用;
4.后续,准备探索将整体 Outlook 邮件转发过程打包成连接器,开源给其他飞书集成平台同学使用;
先进生产力和业务协同平台
联系我们立即试用
更多人气推荐
查看更多

先进团队,先用飞书

欢迎联系我们,飞书效能顾问将为您提供全力支持
分享先进工作方式
输送行业最佳实践
全面协助组织提效
反馈给飞书 CEO:ceo@feishu.cn