更新记录
1.0.0(2025-09-23)
- 前10位保姆级协助
- 下版本更新图文配置教程
平台兼容性
云函数类插件通用教程
使用云函数类插件的前提是:使用HBuilderX 2.9+
🚀 mr-dingtalk-internal
使用前,先右侧蓝色按钮,下载示例项目跑起来后,在搞自己的项目。
Mr-dingtalk-internal 是 unicloud 快速接入 钉钉-内部H5应用-服务端API的云端插件,示例含Web项目客户端使用jssdk调用钉钉客户端API部分示例。
✅ 解决了服务端通讯的 IP白名单 问题(支持阿里云,腾讯云,支付宝云)
✅ 云对象对钉钉服务端API请求进行简单封装
- 简单封装服务端API请求,含客户端请求示例
- 服务端自动缓存更新 应用的access_token和免登sso_access_token
✅ 云对象封装服务端http推送回调函数验证处理方法,支持自定义逻辑
✅ 示例项目中的页面写了部分示例,
- 客户端查询部门列表
- 客户端免登获取用户信息
✅ 📖 请导入示例项目查看 示例为vue3,vue2的朋友自己改造下可以正常使用
🚀 每项配置参数 详细的 截图文档,小白也能轻松接入(含本地调试方法)
🚀 unicloud开发 企业微信 - 自建应用插件
🚀 unicloud开发 企业微信 - 第三方应用插件
插件示例代码片段
1-1、插件云对象中调用钉钉服务端API的模板示例,实际业务自己复制一份改改参数或者二次封装使用
/** testServer() 请求服务端API模板示例,
*
* @param {Object} data
* data.path 钉钉api路径 @string
* 如 1- 请求地址:https://oapi.dingtalk.com/topapi/v2/user/update,
* 2- 去掉https://oapi.dingtalk.com/,
* 3- 剩下的topapi/v2/user/update就是插件约定的路径参数 path 可以前端传也可以后端自己写死
*
* data.tokenType 钉钉token类型 App 默认 应用的access_token || Sso 可选 免登的access_token @string
* data.method 请求方式 GET POST 等 @string
* data.params body 请求参数 @object
* data.useSDK 请求类型 O 默认旧版 || N 新版 @string
*
* 此方法为请求模板示例,实际业务自己复制一份改改或者二次封装使用
* 1、 获取 AccessToken 2、拼接 queryPath 请求路径和参数 3、发起请求 4、返回结果
*/
testServer:async function(data){
// { path tokenType method params useSDK } = data;
// 1、 获取 AccessToken
let tokenRes = await util.getAccessToken({tokenType:data.tokenType})
let AccessToken
if(tokenRes.utilCode == 0){
AccessToken = tokenRes.result
}else{
return {utilCode:-1,utilMsg:"util获取accessToken失败",tokenRes}
}
// 2、拼接 queryPath 请求路径和参数
// @queryPath 请求路径 + 拼接 Query参数,
// 即,请求地址:https://oapi.dingtalk.com/这部分不要,后面的所有,
// 如:queryPath = `role/add_role_group?param1=value1¶m2=value2`
let queryPath = `${data.path}?access_token=${AccessToken}`
// 3、 发起请求
let queryRes = await util.serverApi({
queryPath,
method:data.method,
params:data.params,
useSDK:"O"// N => 新,O => 旧 不传默认旧
})
// 4、返回结果
// queryRes.status == 200 表示 http 请求成功,
// queryRes.data.errcode == 0 表示 钉钉api 请求成功,queryRes.data.errcode == 其他表示错误"
return queryRes.status == 200? { ...queryRes.data }:{tips:'http请求失败',...queryRes}
},
1-2、客户端页面调用云对象的示例
<script setup>
// 1 - 引入插件的云对象
const internal = uniCloud.importObject('dingtalk-internal');
// 获取部门列表 参数说明看云对象注释
async function getDeptList() {
try{
const res = await internal.testServer({
path:"topapi/role/list",
tokenType:"App",
method:"POST",
params:{
dept_id:1
}
})
// consoleLog.value.unshift({label:"获取部门列表 res =>",value:res});
}catch(err){
// consoleLog.value.unshift({label:"获取部门列表 err =>",value:err});
}
}
getDeptList() //找个地方执行
</script>
2-1、插件云对象中 http推送回调示例(选用http推送模式,是因为TA兼容三云,而Stream模式只有支付宝云支持)
// 钉钉服务端调用的http推送回调示例
callback:async function(){
// 1、被调用后,传给插件处理
let utilRes = await util.handleCallBack(this.getHttpInfo())
if(utilRes.utilCode == 0){
// 2、插件处理完成后,获取解密后的相关参数, 其中 EventType = 事件类型 ,
// 相关文档 https://open.dingtalk.com/document/development/org-event-overview
let { EventType,eventId } = utilRes.decrypMsg;
switch (EventType){
case "check_url": // 测试回调地址
// await db.collection("测试表名").add({utilRes,tips:"test check_url"})
// config.json配置文件中CollectionName.CallBackLog 这个是插件的回调日志表,
// 如果 CollectionName.NeedLog = "true",则会记录每一次回调的解密结果
break
case "org_dept_create": // 创建部门事件
// 你的逻辑开始
// await db.collection("测试表名").add({utilRes,tips:"org_dept_create"})
break
// 你的逻辑结束时break跳出switch,不要 return , 保留下面的 return {...utilRes.encryptorRes}
default: break;
}
return {...utilRes.encryptorRes} // 不要动,返回加密后的参数
}else{
// 3、处理失败,查看插件云对象的【运行日志】排查,通常是参数配置错误,或这边你自定义逻辑有错误,插件方法一般不会有问题。
return
}
}
3-1、 客户端获取临时免登码
- setp1 项目根目录右键,选择 命令行打开,执行 npm install dingtalk-jsapi --save
- setp2 页面引入钉钉 jssdk:import * as dd from 'dingtalk-jsapi';
- setp3 页面 引入云对象: const internal = uniCloud.importObject('dingtalk-internal');
<script setup>
import * as dd from 'dingtalk-jsapi';
// import unshiftLog from '../dingtalk-internal/unshift-log.vue'//自定义的日志组件
import { onLoad } from "@dcloudio/uni-app";
onLoad(()=>{
let isLogin = false //判断用户的登录状态,实际替换自己的判断逻辑
if(!isLogin) loginByApp()
})
// 四端调试工具中,使用这个方法得到code,再获取用户信息
// 此方法来自文档 https://open.dingtalk.com/document/development/jsapi-get-auth-code
function loginByApp(){
// 1、获取应用临时免登授权码code
dd.getAuthCode({
corpId: 'dingfc43cedexxxxxxxbf40eda33b7ba0',
success: (res) => {
// 添加日志看看code在哪
// consoleLog.value.unshift({label:'getAuthCode res =>',value:res});
// 2、获取用户信息
getUserInfoByCode(res.code)
},
fail: (err) => {
// consoleLog.value.unshift({label:'getAuthCode err =>',value:err});
},
complete: () => {},
});
}
// 请求云对象换取用户信息
async function getUserInfoByCode(code){
try{
const res = await internal.getUserInfo(code)
consoleLog.value.unshift({label:'getUserInfoByCode res =>',value:res});
}catch(err){
consoleLog.value.unshift({label:'getUserInfoByCode err =>',value:err});
}
}
</script>
3-2、 插件云对象 接到前端传来的免登码后,获取用户信息,
/**
* 免登获取用户信息 复制云对象模板testServer()方法,根据免登api文档,改改得到getUserInfo方法
*
* 免登api文档 https://open.dingtalk.com/document/orgapp/obtain-the-userid-of-a-user-by-using-the-log-free
*
@param code String 前端传来的免登code
*
*/
getUserInfo:async function(code){
if(!code)return {errmsg:"code不能为空",errcode:1}
// 1、 获取 应用的accessToken
let tokenRes = await util.getAccessToken({tokenType:"App"})
let AccessToken
if(tokenRes.utilCode == 0){
AccessToken = tokenRes.result
}else{
return {...tokenRes }
}
// 2、拼接 queryPath 请求路径和参数
let queryPath = `topapi/v2/user/getuserinfo?access_token=${AccessToken}`
// 3、 发起请求
let queryRes = await util.serverApi({
queryPath,
method:"POST",
params:{
code
},
useSDK:"O"// N => 新,O => 旧 不传默认旧
})
return queryRes.status == 200? { ...queryRes.data }:{tips:'http请求失败',...queryRes}
},