guolei19850528 / laravel-wecom-toolkit
一个用于Laravel框架的企业微信(WeCom) SDK扩展包,提供Server API和Webhook API的便捷调用方式。
Package info
gitee.com/guolei19850528/laravel-wecom-toolkit
pkg:composer/guolei19850528/laravel-wecom-toolkit
dev-master
2026-08-18 07:43 UTC
Requires
- php: 8.*
- guzzlehttp/guzzle: ^7.0
- illuminate/support: 7.*||8.*||9.*||10.*||11.*||12.*||13.*
This package is auto-updated.
Last update: 2026-08-18 07:44:08 UTC
README
一个用于 Laravel 框架的企业微信(WeCom)SDK 扩展包,提供 Server API(应用消息)和 Webhook API(群机器人)的便捷调用方式。
功能特性
Server API(企业微信应用)
- 获取、刷新访问令牌(
access_token),支持缓存 - 获取企业微信 API 域名 IP 与回调 IP 列表
- 上传临时素材(
file/voice/image/video)与上传图片 - 发送多种消息类型:文本、图片、语音、视频、文件、文本卡片、图文(news)、多图文(mpnews)、Markdown、小程序通知、模板卡片
- 支持消息
safe、enable_id_trans、enable_duplicate_check等选项
Webhook API(群机器人)
- 发送文本(支持
@用户/@手机号)、Markdown、Markdown V2、图片、图文、文件、语音、模板卡片消息 - 上传媒体文件(
file/voice)获取media_id - 支持默认
@用户列表与@手机号列表
环境要求
- PHP 8.0+
- Laravel 7.x ~ 13.x(
illuminate/support) - Guzzle HTTP 客户端 7.x
安装
使用 Composer 安装扩展包:
composer require guolei19850528/laravel-wecom-toolkit
安装后,Laravel 会通过包发现机制自动注册服务提供者 Guolei19850528\Laravel\Wecom\Toolkit\ExtensionServiceProvider。
配置发布
发布配置文件到 config/laravel-wecom-toolkit.php:
php artisan vendor:publish --provider="Guolei19850528\Laravel\Wecom\Toolkit\ExtensionServiceProvider" --tag="guolei19850528/laravel-wecom-toolkit"
配置文件支持多应用/多机器人配置:
return [
// Server API 配置(企业微信应用)
'server' => [
'your app name' => [
'corpid' => '', // 企业 ID
'corpsecret' => '', // 应用 Secret
'agentid' => '', // 应用 AgentId
'baseUrl' => 'https://qyapi.weixin.qq.com',
],
],
// Webhook API 配置(群机器人)
'webhook' => [
'your key name' => [
'key' => '', // Webhook 密钥
'mentionedList' => [], // 默认 @ 用户列表
'mentionedMobileList' => [], // 默认 @ 手机号列表
'baseUrl' => 'https://qyapi.weixin.qq.com/',
],
],
];
目录结构
src/
├── ExtensionServiceProvider.php # 服务提供者,发布配置文件
├── Server/ # 企业微信 Server API(应用消息)
│ ├── Client.php # 客户端主类
│ ├── HasToken.php # 访问令牌与 IP 列表
│ ├── HasMedia.php # 临时素材与图片上传
│ ├── HasMessage.php # 消息发送
│ └── HasMsgType.php # 各类消息格式化器
└── Webhook/ # 企业微信 Webhook API(群机器人)
├── Client.php # 客户端主类
├── HasMessage.php # 消息发送
├── HasUpload.php # 媒体文件上传
└── HasMsgType.php # 各类消息格式化器
使用示例
Server API
初始化客户端并刷新访问令牌
use Guolei19850528\Laravel\Wecom\Server\Client;
$client = new Client(
corpid: 'your-corpid',
corpsecret: 'your-corpsecret',
agentid: 'your-agentid'
);
// 从缓存获取或重新拉取并缓存 access_token(默认缓存 7100 秒)
$client->refreshAccessToken();
发送文本消息
$text = $client->textFormatter(
content: '这是一条企业消息',
touser: '@all', // 或 'UserID1|UserID2'
enable_duplicate_check: 1
);
$client->messageSend($text);
上传图片并发送
$mediaId = $client->mediaUpload(
attach: ['name' => 'media', 'contents' => file_get_contents('path/to/image.jpg'), 'filename' => 'image.jpg'],
type: 'image'
);
$image = $client->imageFormatter(
mediaId: $mediaId,
touser: '@all'
);
$client->messageSend($image);
发送 Markdown 消息
$markdown = $client->markdownFormatter(
content: "# 标题\n**加粗文本**\n[链接](https://example.com)",
touser: '@all'
);
$client->messageSend($markdown);
发送图文消息
$article = $client->newsArticleFormatter(
title: '文章标题',
description: '文章描述',
url: 'https://example.com/article',
picurl: 'https://example.com/image.jpg'
);
$news = $client->newsFormatter(
articles: [$article],
touser: '@all'
);
$client->messageSend($news);
Webhook API
发送文本消息(含 @ 用户)
use Guolei19850528\Laravel\Wecom\Webhook\Client;
$bot = new Client(key: 'your-webhook-key');
$text = $bot->textFormatter(
content: '这是一条测试消息',
mentionedList: ['user1', 'user2'], // @ 指定用户
mentionedMobileList: ['13800138000'] // @ 指定手机号
);
$bot->send($text);
发送 Markdown 消息
$markdown = $bot->markdownFormatter(
content: "# 标题\n**加粗文本**\n[链接](https://example.com)"
);
$bot->send($markdown);
上传文件并发送
$mediaId = $bot->uploadMedia(
attach: ['name' => 'media', 'contents' => file_get_contents('path/to/file.pdf'), 'filename' => 'file.pdf'],
type: 'file'
);
$file = $bot->fileFormatter($mediaId);
$bot->send($file);
API 参考
Server API — Guolei19850528\Laravel\Wecom\Server\Client
__construct(
?string $corpid = '',
?string $corpsecret = '',
string|int|null $agentid = '',
?string $baseUrl = 'https://qyapi.weixin.qq.com/'
)
令牌与 IP(HasToken)
| 方法 | 返回值 | 说明 |
|---|---|---|
getToken(?array $query = [], ?string $url = '/cgi-bin/gettoken', ...) | ?string | 获取 access_token |
getApiDomainIp(...) | ?array | 获取 API 域名 IP 列表 |
getCallbackIp(...) | ?array | 获取回调 IP 列表 |
refreshAccessToken(?string $key = '', \DateTimeInterface\|\DateInterval\|int\|null $ttl = 7100): static | static | 从缓存读取或重新获取并缓存 access_token |
媒体上传(HasMedia)
| 方法 | 返回值 | 说明 |
|---|---|---|
mediaUpload(?array $attach = [], ?array $data = [], ?string $type = 'file', ...) | ?string | 上传临时素材,返回 media_id |
mediaUploadImg(?array $attach = [], ?array $data = [], ...) | ?string | 上传图片,返回图片 URL |
消息发送(HasMessage)
| 方法 | 返回值 | 说明 |
|---|---|---|
messageSend(?array $data = [], ?string $url = '/cgi-bin/message/send?access_token={access_token}', ...) | bool | 发送应用消息 |
消息格式化器(HasMsgType)
textFormatter(?string $content = '', ?string $touser = '', ?string $toparty = '', ?string $totag = '', string|int|null $agentid = null, ?int $safe = 0, ?int $enable_id_trans = 0, ?int $enable_duplicate_check = 0, ?int $duplicate_check_interval = 1800): arrayimageFormatter(?string $mediaId = '', ?string $touser = '', ?string $toparty = '', ?string $totag = '', string|int|null $agentid = null, ?int $safe = 0, ?int $enable_id_trans = 0, ?int $enable_duplicate_check = 0, ?int $duplicate_check_interval = 1800): arrayvoiceFormatter(?string $mediaId = '', ?string $touser = '', ?string $toparty = '', ?string $totag = '', string|int|null $agentid = null, ?int $enable_duplicate_check = 0, ?int $duplicate_check_interval = 1800): arrayvideoFormatter(?string $mediaId = '', ?string $title = '', ?string $description = '', ?string $touser = '', ?string $toparty = '', ?string $totag = '', string|int|null $agentid = null, ?int $safe = 0, ?int $enable_duplicate_check = 0, ?int $duplicate_check_interval = 1800): arrayfileFormatter(?string $mediaId = '', ?string $touser = '', ?string $toparty = '', ?string $totag = '', string|int|null $agentid = null, ?int $safe = 0, ?int $enable_duplicate_check = 0, ?int $duplicate_check_interval = 1800): arraytextcardFormatter(?string $title = '', ?string $description = '', ?string $url = '', ?string $btntxt = '', ?string $touser = '', ?string $toparty = '', ?string $totag = '', string|int|null $agentid = null, ?int $enable_id_trans = 0, ?int $enable_duplicate_check = 0, ?int $duplicate_check_interval = 1800): arraynewsArticleFormatter(?string $title = '', ?string $description = '', ?string $url = '', ?string $picurl = '', ?string $appid = '', ?string $pagepath = ''): arraynewsFormatter(?array $articles = [], ?string $touser = '', ?string $toparty = '', ?string $totag = '', string|int|null $agentid = null, ?int $enable_id_trans = 0, ?int $enable_duplicate_check = 0, ?int $duplicate_check_interval = 1800): arraympnewsArticleFormatter(?string $title = '', ?string $thumb_media_id = '', ?string $author = '', ?string $content_source_url = '', ?string $content = '', ?string $digest = ''): arraympnewsFormatter(?array $articles = [], ?string $touser = '', ?string $toparty = '', ?string $totag = '', string|int|null $agentid = null, ?int $safe = 0, ?int $enable_id_trans = 0, ?int $enable_duplicate_check = 0, ?int $duplicate_check_interval = 1800): arraymarkdownFormatter(?string $content = '', ?string $touser = '', ?string $toparty = '', ?string $totag = '', string|int|null $agentid = null, ?int $enable_duplicate_check = 0, ?int $duplicate_check_interval = 1800): arrayminiprogramNoticeContentItemFormatter(?string $key = '', ?string $value = '')miniprogramNoticeFormatter(?string $appid = '', ?string $page = '', ?string $title = '', ?string $description = '', ?bool $emphasis_first_item = true, ?array $content_item = [], ?string $touser = '', ?string $toparty = '', ?string $totag = '', ?int $enable_id_trans = 0, ?int $enable_duplicate_check = 0, ?int $duplicate_check_interval = 1800)templateCardFormatter(?array $template_card = [], ?string $touser = '', ?string $toparty = '', ?string $totag = '', ?string $agentid = '', ?int $enable_id_trans = 0, ?int $enable_duplicate_check = 0, ?int $duplicate_check_interval = 1800): array
Webhook API — Guolei19850528\Laravel\Wecom\Webhook\Client
__construct(
?string $key = '',
?array $mentionedList = [],
?array $mentionedMobileList = [],
?string $baseUrl = 'https://qyapi.weixin.qq.com/'
)
消息发送(HasMessage)
| 方法 | 返回值 | 说明 |
|---|---|---|
send(?array $data = null, ?string $url = '/cgi-bin/webhook/send?key={key}', ...) | bool | 发送机器人消息 |
媒体上传(HasUpload)
| 方法 | 返回值 | 说明 |
|---|---|---|
uploadMedia(?array $attach = null, ?array $data = null, ?string $url = '/cgi-bin/webhook/upload_media?key={key}&type={type}', ?string $type = 'file', ...) | ?string | 上传媒体文件,返回 media_id |
消息格式化器(HasMsgType)
textFormatter(string $content = '', array $mentionedList = [], array $mentionedMobileList = []): arraymarkdownFormatter(string $content = ''): arraymarkdownV2Formatter(string $content = ''): arrayimageFormatter(string $base64 = '', string $md5 = ''): arraynewsArticleFormatter(string $title = '', string $description = '', string $url = '', string $picurl = ''): arraynewsFormatter(array $articles = []): arrayfileFormatter(string $mediaId = ''): arrayvoiceFormatter(string $mediaId = ''): arraytemplateCardFormatter(array $template_card = []): array
通用方法签名说明
上述方法均支持以下可选参数(用于覆盖默认行为):
?array $urlParameters:URL 模板参数(如{access_token}、{key}、{type})?array $options:HTTP 客户端请求选项?\Closure $responseHandler:自定义响应处理回调,若提供则跳过默认验证逻辑?array $validatorRules:响应验证规则,默认['errcode' => 'required|integer|size:0']
注意事项
- 在企业微信管理后台正确配置应用
corpid/corpsecret/agentid与群机器人 Webhookkey,并确保相关 API 权限已开启。 access_token有效期为 7200 秒,refreshAccessToken()默认缓存 7100 秒,避免高频请求。- 关注企业微信接口的频率限制,避免触发限流。
- 上传的媒体文件有大小与格式限制,请参考企业微信官方文档。
- Webhook API 与 Server API 使用场景不同:Webhook 用于群机器人推送,Server 用于应用消息触达。
- 所有 HTTP 请求基于 Laravel 的
HttpFacade,使用 Guzzle 7 驱动。
许可证
MIT License,详见 LICENSE。
贡献
欢迎提交 Issue 与 Pull Request 来帮助改进此扩展包。