本文目录导读:

我来为你详细介绍PHP项目中集成企业微信和钉钉的完整方案。
企业微信集成
1 基础配置
<?php
// config/wechat_work.php
return [
'corp_id' => '你的企业ID',
'agent_id' => '应用AgentID',
'secret' => '应用Secret',
'token' => '回调Token',
'encoding_aes_key' => '消息加解密密钥',
'oauth_redirect_uri' => 'https://yourdomain.com/oauth/callback'
];
2 核心SDK类
<?php
namespace App\Services;
use GuzzleHttp\Client;
class WechatWorkService
{
private $corpId;
private $agentId;
private $secret;
private $accessToken;
private $httpClient;
public function __construct()
{
$config = config('wechat_work');
$this->corpId = $config['corp_id'];
$this->agentId = $config['agent_id'];
$this->secret = $config['secret'];
$this->httpClient = new Client([
'base_uri' => 'https://qyapi.weixin.qq.com/cgi-bin/',
'timeout' => 10.0
]);
}
// 获取Access Token
public function getAccessToken()
{
$cacheKey = 'wechat_work_access_token_' . $this->agentId;
// 从缓存获取
if ($token = cache()->get($cacheKey)) {
return $token;
}
$response = $this->httpClient->get('gettoken', [
'query' => [
'corpid' => $this->corpId,
'corpsecret' => $this->secret
]
]);
$result = json_decode($response->getBody(), true);
if ($result['errcode'] === 0) {
// 缓存token(提前5分钟过期)
cache()->put($cacheKey, $result['access_token'], $result['expires_in'] - 300);
return $result['access_token'];
}
throw new \Exception('获取AccessToken失败:' . $result['errmsg']);
}
// 获取OAuth授权URL
public function getOAuthUrl($redirectUri, $state = '')
{
$redirectUri = urlencode($redirectUri);
return "https://open.weixin.qq.com/connect/oauth2/authorize?" .
"appid={$this->corpId}&" .
"redirect_uri={$redirectUri}&" .
"response_type=code&" .
"scope=snsapi_base&" .
"state={$state}#wechat_redirect";
}
// 获取用户信息
public function getUserInfo($code)
{
$token = $this->getAccessToken();
// 获取访问Token
$response = $this->httpClient->get('user/getuserinfo', [
'query' => [
'access_token' => $token,
'code' => $code
]
]);
$result = json_decode($response->getBody(), true);
if ($result['errcode'] === 0) {
// 获取用户详细信息
return $this->getUserDetail($result['UserId']);
}
throw new \Exception('获取用户信息失败:' . $result['errmsg']);
}
// 获取用户详细信息
public function getUserDetail($userId)
{
$token = $this->getAccessToken();
$response = $this->httpClient->post('user/get', [
'query' => ['access_token' => $token],
'json' => ['userid' => $userId]
]);
return json_decode($response->getBody(), true);
}
// 发送应用消息
public function sendMessage($toUser, $content, $msgType = 'text')
{
$token = $this->getAccessToken();
$message = [
'touser' => is_array($toUser) ? implode('|', $toUser) : $toUser,
'msgtype' => $msgType,
'agentid' => $this->agentId
];
switch ($msgType) {
case 'text':
$message['text'] = ['content' => $content];
break;
case 'markdown':
$message['markdown'] = ['content' => $content];
break;
case 'news':
$message['news'] = $content;
break;
}
$response = $this->httpClient->post('message/send', [
'query' => ['access_token' => $token],
'json' => $message
]);
return json_decode($response->getBody(), true);
}
}
钉钉集成
1 基础配置
<?php
// config/dingtalk.php
return [
'app_key' => '你的AppKey',
'app_secret' => '你的AppSecret',
'agent_id' => '应用AgentId',
'corp_id' => '企业CorpId',
'oauth_redirect_uri' => 'https://yourdomain.com/dingtalk/callback'
];
2 核心SDK类
<?php
namespace App\Services;
use GuzzleHttp\Client;
class DingTalkService
{
private $appKey;
private $appSecret;
private $agentId;
private $accessToken;
private $httpClient;
public function __construct()
{
$config = config('dingtalk');
$this->appKey = $config['app_key'];
$this->appSecret = $config['app_secret'];
$this->agentId = $config['agent_id'];
$this->httpClient = new Client([
'base_uri' => 'https://oapi.dingtalk.com/',
'timeout' => 10.0
]);
}
// 获取Access Token
public function getAccessToken()
{
$cacheKey = 'dingtalk_access_token';
if ($token = cache()->get($cacheKey)) {
return $token;
}
$response = $this->httpClient->post('gettoken', [
'query' => [
'appkey' => $this->appKey,
'appsecret' => $this->appSecret
]
]);
$result = json_decode($response->getBody(), true);
if ($result['errcode'] === 0) {
cache()->put($cacheKey, $result['access_token'], $result['expires_in'] - 300);
return $result['access_token'];
}
throw new \Exception('获取AccessToken失败:' . $result['errmsg']);
}
// 获取免登录授权码
public function getAuthCodeUrl($redirectUri)
{
$redirectUri = urlencode($redirectUri);
return "https://oapi.dingtalk.com/connect/oauth2/sns_authorize?" .
"appid={$this->appKey}&" .
"response_type=code&" .
"scope=snsapi_auth&" .
"state=STATE&" .
"redirect_uri={$redirectUri}";
}
// 获取用户信息
public function getUserInfo($authCode)
{
$token = $this->getAccessToken();
// 获取用户Token
$response = $this->httpClient->post('user/getuserinfo', [
'query' => ['access_token' => $token],
'json' => ['code' => $authCode]
]);
$result = json_decode($response->getBody(), true);
if ($result['errcode'] === 0) {
$userId = $result['userid'];
return $this->getUserDetail($userId);
}
throw new \Exception('获取用户信息失败:' . $result['errmsg']);
}
// 获取用户详细信息
public function getUserDetail($userId)
{
$token = $this->getAccessToken();
$response = $this->httpClient->post('user/get', [
'query' => ['access_token' => $token],
'json' => ['userid' => $userId]
]);
return json_decode($response->getBody(), true);
}
// 发送工作通知消息
public function sendMessage($userIds, $content, $msgType = 'text')
{
$token = $this->getAccessToken();
$message = [
'agent_id' => $this->agentId,
'userid_list' => is_array($userIds) ? implode(',', $userIds) : $userIds,
'msg' => [
'msgtype' => $msgType
]
];
switch ($msgType) {
case 'text':
$message['msg']['text'] = ['content' => $content];
break;
case 'markdown':
$message['msg']['markdown'] = [
'title' => '通知',
'text' => $content
];
break;
case 'action_card':
$message['msg']['action_card'] = $content;
break;
}
$response = $this->httpClient->post('topapi/message/corpconversation/asyncsend_v2', [
'query' => ['access_token' => $token],
'json' => $message
]);
return json_decode($response->getBody(), true);
}
// 创建审批实例
public function createApproval($processCode, $formData, $approvers)
{
$token = $this->getAccessToken();
$data = [
'process_code' => $processCode,
'form_component_values' => $formData,
'approvers' => $approvers,
'agent_id' => $this->agentId
];
$response = $this->httpClient->post('topapi/processinstance/create', [
'query' => ['access_token' => $token],
'json' => $data
]);
return json_decode($response->getBody(), true);
}
}
统一控制器
<?php
namespace App\Http\Controllers;
use App\Services\WechatWorkService;
use App\Services\DingTalkService;
use Illuminate\Http\Request;
class PlatformController extends Controller
{
private $wechatWorkService;
private $dingTalkService;
public function __construct(
WechatWorkService $wechatWorkService,
DingTalkService $dingTalkService
) {
$this->wechatWorkService = $wechatWorkService;
$this->dingTalkService = $dingTalkService;
}
// 企业微信登录
public function wechatLogin(Request $request)
{
$state = $request->input('state', 'wechat_work');
$url = $this->wechatWorkService->getOAuthUrl(
route('wechat.oauth.callback'),
$state
);
return redirect($url);
}
// 企业微信回调
public function wechatCallback(Request $request)
{
try {
$code = $request->input('code');
$userInfo = $this->wechatWorkService->getUserInfo($code);
// 处理用户登录逻辑
$user = User::where('wechat_work_id', $userInfo['userid'])->first();
if (!$user) {
// 创建新用户
$user = User::create([
'name' => $userInfo['name'],
'wechat_work_id' => $userInfo['userid'],
'email' => $userInfo['email'] ?? '',
'avatar' => $userInfo['avatar'] ?? ''
]);
}
auth()->login($user);
return redirect('/dashboard');
} catch (\Exception $e) {
return redirect('/login')->with('error', '企业微信登录失败');
}
}
// 钉钉登录
public function dingtalkLogin()
{
$url = $this->dingTalkService->getAuthCodeUrl(
route('dingtalk.oauth.callback')
);
return redirect($url);
}
// 钉钉回调
public function dingtalkCallback(Request $request)
{
try {
$authCode = $request->input('authCode');
$userInfo = $this->dingTalkService->getUserInfo($authCode);
// 处理用户登录逻辑
$user = User::where('dingtalk_id', $userInfo['userid'])->first();
if (!$user) {
// 创建新用户
$user = User::create([
'name' => $userInfo['name'],
'dingtalk_id' => $userInfo['userid'],
'email' => $userInfo['email'] ?? '',
'avatar' => $userInfo['avatar'] ?? ''
]);
}
auth()->login($user);
return redirect('/dashboard');
} catch (\Exception $e) {
return redirect('/login')->with('error', '钉钉登录失败');
}
}
// 发送消息(统一接口)
public function sendNotification(Request $request)
{
$validated = $request->validate([
'platform' => 'required|in:wechat,dingtalk',
'user_id' => 'required',
'content' => 'required',
'type' => 'required|in:text,markdown,news'
]);
try {
if ($validated['platform'] === 'wechat') {
$result = $this->wechatWorkService->sendMessage(
$validated['user_id'],
$validated['content'],
$validated['type']
);
} else {
$result = $this->dingTalkService->sendMessage(
$validated['user_id'],
$validated['content'],
$validated['type']
);
}
return response()->json([
'success' => true,
'message' => '消息发送成功',
'data' => $result
]);
} catch (\Exception $e) {
return response()->json([
'success' => false,
'message' => $e->getMessage()
], 500);
}
}
}
Webhook处理
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class WebhookController extends Controller
{
// 企业微信回调
public function wechatWebhook(Request $request)
{
// 验证签名
$signature = $request->input('msg_signature');
$timestamp = $request->input('timestamp');
$nonce = $request->input('nonce');
$echostr = $request->input('echostr');
// 处理回调验证
if ($echostr) {
return $this->verifyUrl($signature, $timestamp, $nonce, $echostr);
}
// 处理消息
$xmlData = $request->getContent();
$message = simplexml_load_string($xmlData, 'SimpleXMLElement', LIBXML_NOCDATA);
return $this->handleMessage($message);
}
// 钉钉回调
public function dingtalkWebhook(Request $request)
{
$data = $request->all();
// 验证回调
$signature = $data['signature'];
$timestamp = $data['timestamp'];
$nonce = $data['nonce'];
// 处理回调
$eventType = $data['EventType'];
switch ($eventType) {
case 'check_url':
return 'success';
case 'user_add_org':
return $this->handleUserAdd($data);
case 'user_leave_org':
return $this->handleUserLeave($data);
default:
return 'success';
}
}
}
使用示例
// 路由配置
Route::prefix('oauth')->group(function () {
Route::get('wechat/login', [PlatformController::class, 'wechatLogin'])->name('wechat.oauth.login');
Route::get('wechat/callback', [PlatformController::class, 'wechatCallback'])->name('wechat.oauth.callback');
Route::get('dingtalk/login', [PlatformController::class, 'dingtalkLogin'])->name('dingtalk.oauth.login');
Route::get('dingtalk/callback', [PlatformController::class, 'dingtalkCallback'])->name('dingtalk.oauth.callback');
});
// Webhook路由
Route::post('webhook/wechat', [WebhookController::class, 'wechatWebhook'])->name('webhook.wechat');
Route::post('webhook/dingtalk', [WebhookController::class, 'dingtalkWebhook'])->name('webhook.dingtalk');
// 发送通知
Route::post('notification/send', [PlatformController::class, 'sendNotification'])->name('notification.send');
依赖安装
composer require guzzlehttp/guzzle composer require illuminate/cache
这个方案提供了完整的企业微信和钉钉集成功能,包括用户认证、消息推送、Webhook处理等,你可以根据实际需求进行调整和扩展。