作者:潘龙(phiron.pan)
推荐理由
本人是飞书小白,第一次参与开发飞书自建应用,在开发过程中收获满满,获益匪浅,现在分享出来希望能够帮助到大家。
一、关于我/我们
我是一位全栈开发工程师,喜欢折腾和学习新技术。
二、需求分析
目前公司需要在飞书服务台开发一个答题知识的自建应用,就是点击服务台按钮直接打开答题知识应用,然后参与答题,获取抽奖机会,参与抽奖。
实现这种效果(demo)
250px|700px|reset
三、方案调研
首先所有的操作都得在飞书上完成,比如连接分享可以添加积分,所以得在飞书上开发。通过阅读飞书的文档得知可以进行免登录,然后就是分享连接也可以直接在飞书打开自建应用,这样就很方便。前期调研确实遇到很多困难,首先就是分享连接怎么直接打开指定的应用,然后终于找到了飞书官方的一个applink工具,这样的,附上链接https://webview.feishu.cn/applinktool,有需要的小伙伴可以直接使用哦
然后就是在服务台后台填写生成的链接保存发布即可。
然后最终的效果就像开始展示的那样啦。
如果在飞书外浏览器或者其他工具打开,就会弹出报错
哈哈,效果就是这样子。
四、开发流程
首先我们要实现免登录流程,那就要对接飞书的登录接口了。
一开始去官方下载的案例,是前后端不分离的,但是我想做一个前后端分离,用uniapp开发,在index.html引入飞书的jsdk是无法生效的,解决方案就是直接在免登录页面进行代码引入
获取code函数放在public/index.js文件里callApiAuth() {
uni.showLoading({
title:"正在登录中..."
})
// 动态创建script标签引入外部脚本
const script = document.createElement('script');
const script1 = document.createElement('script');
// 在脚本加载完成后执行回调
script.onload = () => {
// 确保外部脚本加载完成后再调用apiAuth函数
apiAuth();
};
let that = this
setTimeout(function() {
script1.onload = () => {
var vConsole = new window.VConsole();
let code = uni.getStorageSync("code")
request('/userinfo', { code: code, }, 'POST', { Authorization: null })
.then(res => {
let pages = getCurrentPages()
let nowPage = pages[pages.length - 1]; // 当前页的实例
let prevPage = pages[pages.length - 2];// 上级页面实例
console.log(pages)
prevPage.update(res.data)
uni.navigateBack()
uni.hideLoading()
})
.catch(error => {
console.log(error)
})
}
}, 1000);
// 将脚本添加到页面
document.head.appendChild(script);
document.head.appendChild(script1);
}
我的免登录代码是直接在一个接口完成的哦,飞书文档写了要先根据预授权code获取app_access_token,然后获取access_token才能获取userinfo信息,具体的飞书接口文档链接如下,按顺序进行阅读更好function apiAuth() {
if (!window.h5sdk) {
console.log('invalid h5sdk')
alert('请在飞书中打开')
return
}
window.h5sdk.ready(() => { // ready 方法不需要每次都调用。
tt.requestAuthCode({
appId: "cli_a5ac3be6383b900e",
success: (info) => {
uni.setStorageSync("code",info.code)
},
fail: (error) => {
}
});
});
}
//导出
module.exports = {
apiAuth
}
1.通过code获取飞书app_access_token
2.通过app_access_token获取user_access_token
3.通过user_access_token获取用户信息实现免登
对了调用接口还得获取tenant_access_token放在header请求头哦,每两个小时过期,有需要的可以看一下
python代码如下
在飞书调试时,会有跨域的问题出现,导致接口无法请求到,最好的方法就是把前后端的ip都改成127.0.0.1这样调试最好啦,等到最后部署到linux服务器通过nginx代理应该就不会出现这种问题。@login_blueprint.route('/userinfo', methods=['POST'])
def userinfo():
global app_access_token
data = request.get_json()
code = data.get('code')
# 获取飞书 tenant_access_token 两小时过期
params1 = {
"grant_type": "authorization_code",
"code": code,
"app_id": feishu['appId'],
"app_secret": feishu['appSecret']
}
str_token = mredis.str_get("app_access_token")
print(str_token)
if str_token is not None:
app_access_token = str_token.decode()
if app_access_token is None:
# 获取飞书 app_access_token 两小时过期
params = {
"app_id": feishu['appId'],
"app_secret": feishu['appSecret']
}
res = req.post(url, json=params)
print("res", res)
mredis.str_set("app_access_token", res.json()["app_access_token"])
mredis.expire("app_access_token", 6000)
app_access_token = res.json()["app_access_token"]
headers = {
"Authorization": "Bearer " + app_access_token
}
print(access_token_url)
print(params1)
print(headers)
res = req.post(access_token_url, json=params1, headers=headers)
print("res", res.json())
access_token = res.json()["data"]["access_token"]
# 获取用户信息
headers = {
"Authorization": "Bearer " + access_token
}
user_info = req.get(user_url, headers=headers)
# 返回用户信息
return Res(HTTP_STATUS_OK, user_info.json()["data"], MSG_QUERY_SUCCESS)
五、更多相关开发心得
最后就是开发心得啦,感受最深的就是有问题先自己研究文档,实在弄不会,直接联系我们的飞书官方客服啦,真的太热情了,小姐姐真的超耐心超细心,还会远程视频帮我解决问题,必须给客服五星好评哈哈,希望我的文章能够帮到你们!