# 钉钉
## 辅助函数
```php
/**
* curl 请求
*
* @param string $method 请求方法 POST/GET/DELETE/PUT
* @param string $url
* @param array|string $data 提交数据
* @param array $header 请求头
* @return string|null
*/
function curl_request($method = 'POST', $url, $data='', $header=[])
{
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_POSTFIELDS => $data,
CURLOPT_HTTPHEADER => $header,
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err)
throw new Exception($err, 1);
return $response;
}
```
## 封装代码
file:`application/utils/DingTalk.php`
```php
<?php
namespace app\utils;
use think\Exception;
use think\facade\Cache;
/**
* 应用密钥
*/
define('DINGTALK_CORPID', env('DINGTALK.CORPID'));
define('DINGTALK_SECRET', env('DINGTALK.SECRET'));
/**
* 钉钉
*/
class DingTalk {
/**
* 企业开发者消息ID
*/
const AGENT_ID = '';
/**
* 获取access_token
*
* @return string
*/
static function getAccessToken()
{
$access_token = Cache::get('DING_TOKEN');
if ($access_token) {
return $access_token;
}
$corpid = DINGTALK_CORPID;
$corpsecret = DINGTALK_SECRET;
$response = curl_request('GET', "https://oapi.dingtalk.com/gettoken?corpid={$corpid}&corpsecret={$corpsecret}");
// dump($response);
$result = json_decode($response, true);
if (!isset($result['access_token'])) throw new Exception($result['errmsg'], 1);
$access_token = $result['access_token'];
Cache::set('DING_TOKEN', $access_token, 60); // 60秒内用同一个
return $access_token;
}
/**
* 获取用户userid
*
* @param string $code
* @return string
*/
static function getUserid($code)
{
$access_token = self::getAccessToken();
$url = "https://oapi.dingtalk.com/user/getuserinfo?access_token={$access_token}&code={$code}";
$response = curl_request('GET', $url);
$result = json_decode($response, true);
if (!isset($result['userid'])) throw new Exception($result['errmsg'], 1);
$userid = $result['userid'];
return $userid;
}
/**
* 获取用户信息
*
* @param integer $userid
* @return array
*/
static function getUserinfo($userid)
{
$access_token = self::getAccessToken();
$url = "https://oapi.dingtalk.com/user/get?access_token={$access_token}&userid={$userid}";
$response = curl_request('POST', $url);
$result = json_encode($response, true);
return $result;
}
/**
* 发送消息
*
* @param integer $agent_id 应用agentId 参考常量: DingTalk::AGENT_ID
* @param string $user_id 钉钉用户id
* @param array $msg 消息格式参考: https://ding-doc.dingtalk.com/doc#/serverapi2/ye8tup
* @return array|null array(3) { errcode=>0, task_id=>18988591062, request_id=>6iq4ab1gd7il }
*/
static function sendMsg($agent_id, $userid = '', $msg)
{
$access_token = self::getAccessToken();
$url = "https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2?access_token=$access_token";
$postData["agent_id"] = $agent_id;
$postData["userid_list"] = $userid;
$postData["msg"] = $msg;
$result = json_decode(curl_request('POST', $url, $postData), true);
return $result;
}
/**
* 发送文本消息
*
* @param integer $agent_id 应用agentId 参考常量: DingTalk::AGENT_ID
* @param string $userid 钉钉用户id
* @param string $content 发送内容
* @return void
*/
static function sendTextMsg($agent_id, $userid, $content) {
$msgData = [
'msgtype' => 'text',
'text' => [
'content' => $content,
],
];
return self::sendMsg($agent_id, $userid, $msgData);
}
}
```
## 登录
1. 前端, 通过`corpId`换取`code`
```javascript
<scriptsrc="http://g.alicdn.com/dingding/dingtalk-pc-api/2.3.1/index.js"></script>
<scriptsrc="https://g.alicdn.com/dingding/open-develop/1.6.9/dingtalk.js"></script>
dd.ready(function(){
dd.runtime.permission.requestAuthCode({
corpId:{corpId},
onSuccess:function(result) {
// result.code
},
});
});
DingTalkPC.runtime.permission.requestAuthCode({
corpId:{corpId},
onSuccess:function(result) {
// result.code
},
onFail:function(err) {
}
});
dd.error(function(err){
alert('dd error:'+JSON.stringify(err));
});
```
2. 获取`access_token`
3. 通过`code`和`access_token`换取`userid`(钉钉用户id)
```php
$access_token = DingTalk::getAccessToken();
if (!$access_token)
error("没有成功获取access_token");
// get userid
$userid = DingTalk::getUserid($code);
if (!$userid)
error("授权失败");
// get userinfo
$userinfo = DingTalk::getUserinfo($userid);
if (!$userinfo)
error('授权失败');
```
**其他:发送消息通知**
```
$msgContent = sprintf('您的学员【%s】提交的资料被驳回了,原因请进入系统查看', '测试');
DingTalk::sendTextMsg(DingTalk::AGENT_ID, 钉钉userid, $msgContent);
```
- 前言
- Android
- 签名证书生成
- JavaScript
- WebSocket 协议心跳
- 选择预览本地图片(不上传)
- Ajax 上传文件
- 代码片
- js 播放声音
- Verify 验证
- 验证金额 / 限制保留两位小数
- 原型链&继承
- 经典算法
- 冒泡排序
- 递归算法
- 二分查找
- 帮助函数
- 取URL查询参数为对象
- Date 日期时间
- 浅拷贝与深拷贝
- 进制转换
- Canvas
- 画圆形头像
- 计算字符串宽度
- 常用第三方包
- XLSX
- Layui
- layer.open select 遮挡问题
- 模板中使用 JS 表达式
- Form 表单
- on 监听事件
- select 下拉选择框
- 取表单数据 / 置表单数据
- form.verify 表单验证
- address 三级联动
- Table 表格
- 动态添加表格行
- 设置行高
- 单元格显示图片
- 开启编辑-阻止用户修改
- 主动触发事件
- 文件上传
- 单图上传
- Vue
- Vue.js 代码片
- 模态框/弹出层
- 单页面电影院选座
- vuex
- WebSocket聊天模板
- 解决办法
- vue-router多级路由中无父级组件设置方法
- Mui
- vue2+mui实现上拉刷新下拉加载
- JQuery
- 序列号表单为 JSON 对象
- Ajax 网络请求
- 选择器
- 插件
- selectpage
- HTML+CSS 布局
- Nodejs
- flex 布局
- 水平对齐方式
- 垂直对齐方式
- 九宫格/列表
- PHP
- gd 图像处理
- 图片写字
- 图片合并
- 图像压缩
- 图片写字居中
- 超全局变量
- helper 帮助函数
- ThinkPHP
- 生成用户分享二维码
- tp5.0 模型关联查询field无效
- Composer
- phpmailer
- 第三方接口
- 快递 100 物流记录
- 动态加载
- pdf解决方案
- 图片转换pdf
- 阿里云
- OSS 对象储存
- 阿里短信
- 辅助函数
- 取两个数组差异部分
- 从完整地址中取出省市区
- 钉钉
- 进制转换 & pack/unpack
- Yii2
- ActiveForm 常见问题
- FastAdmin
- layer的妙用
- \fast\Auth 权限
- 前端的各种常见问题
- 点击图片放大预览
- js
- ajax请求
- 前端
- Table
- selectPage
- 后端
- 腾讯cos插件后台上传文件工具类
- XDebug
- php.ini
- Linux
- RabbitMQ
- 防火墙
- iptables
- firewalld
- 环境变量
- shell
- bash
- crontab 定时任务
- 数据归档与解压缩
- tar
- 图像处理
- imagemagick
- 文档表格处理
- 转换word、pdf等
- 常用命令
- 文件资源管理
- xxd 十六进制编辑与查看
- 疑难杂症
- 开启swap虚拟文件系统缓解内存紧张卡顿
- wine
- deepin-wine(qq/微信综合)
- Python
- 代码片
- bs4 解析 html 插入到数据库
- webdriver 操作浏览器
- requests 请求库
- easyxlsx 导出 excel
- opencv
- 提取印章
- orc图片文字识别
- tesseract
- 进制转换
- WebSocket
- ws 服务示例
- 进程守护
- PM2
- Golang
- net/http
- Server
- 基本
- array 数组
- 循环
- os 文件目录基本操作
- map
- json处理
- Qrcode 二维码
- go-sqlite3
- go-redis
- mysql
- go-sql-driver
- 正则表达式
- beego
- fmt
- io
- ioutil
- net
- http
- Docker
- docker run
- Nginx
- CORS 允许跨域配置
- 负载均衡&反向代理
- rewaite 重写
- nginx配置
- 易语言
- 汇编 call 执行子程序
- HpSocketTcp 大文件传输
- 类指针
- Vim
- UniApp
- request.js
- 微信小程序登录处理(oauth2)
- vuex
- WebSocket聊天
- 腾讯云-人脸核身
- Java
- Spring Boot
- 请求与响应
- nginx部署
- 配置文件
- 创建项目
- 控制器
- 一个控制器示例
- 数据库
- MySQL
- 集成 SLF4J
- 集成 PageHelper 分页
- maven
- Markdown
- mermaid
- ffmpeg
- 基本使用
- 介绍/安装
- 简单示例
- php
- python
- office
- excel
- 单元格选择数据区域
- 截取字符串
- vlookup 选择值
- iferror 错误默认值
- search 搜索
- weekday 取星期几
- left 取左边n个字符
- right 取右边n个字符
- sum 合计
- sumif 条件合计
- sumifs 多条件合计
- datedif 取时间间隔
- roundup 向上舍入数字
- rounddown 向下舍入数字
- large 取第n大值
- mod 求余函数
- word
- 邮件合并-保留两位小数
- MySql
- 安装
- 基础操作
- 备份还原数据库
- 创建、删除、修改数据表
- 表结构查询
- Docker方案
- 慢查询
- 全文搜索
- 备份与还原
- 备份数据表
- 支付
- 支付宝
- ssh证书生成
- 支付申请
- 成考
- 英语
- 音标-掐头法
- 音标-去尾法
- 音标-元音
- 对比法学习辅音发音
- 短元音-长元音
- 双元音
- 数学
- 1.实数系
- 2.乘方
- 3.代数式
- 4.单项式多项式
- 5.整式的概念与方程综合
- 6.合并同类项和移项
- 7.二次根式
- 8.方程
- Git
- WebHook
- 宝塔
- webhook工具实现
- commit 规范
- 安装
- 创建
- 发布、提交
- 查看
- 更新
- 分支
- 找回文件、目录
- Svn
- 设置默认编辑器
- ignore 忽略提交目录
- revert 恢复撤销
- C语言
- 环境安装
- 基础部分
- 单片机
- ESP8266
- ESP8266开发环境安装
- 基础知识
- sim800
- Windows
- Win7
- Win10
- wsl (Linux子系统)
- ArtTemplate
- 正则表达式
- 常用正则
- VsCode
- easy less
- 腾讯云
- 数据万象
- 任务接口
- 音视频转码任务
- 算法
- 宽高按比例缩放大小尺寸
- IOS
- 开发者账号
- uniapp-ios打包上架的坑
- 协议模板
- 隐私协议
- 酸酸乳
- bower
- SQL Server
- 多行数据连接字符串
- GROUP BY选取其他字段
- 支付宝
- IoT小程序
- 支付
- RSA秘钥生成