guolei19850528/laravel-wecom-toolkit

一个用于Laravel框架的企业微信(WeCom) SDK扩展包,提供Server API和Webhook API的便捷调用方式。

Maintainers

Package info

gitee.com/guolei19850528/laravel-wecom-toolkit

pkg:composer/guolei19850528/laravel-wecom-toolkit

Transparency log

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

dev-master 2026-08-18 07:43 UTC

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、小程序通知、模板卡片
  • 支持消息 safeenable_id_transenable_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): staticstatic从缓存读取或重新获取并缓存 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): array
  • imageFormatter(?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): array
  • voiceFormatter(?string $mediaId = '', ?string $touser = '', ?string $toparty = '', ?string $totag = '', string|int|null $agentid = null, ?int $enable_duplicate_check = 0, ?int $duplicate_check_interval = 1800): array
  • videoFormatter(?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): array
  • fileFormatter(?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): array
  • textcardFormatter(?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): array
  • newsArticleFormatter(?string $title = '', ?string $description = '', ?string $url = '', ?string $picurl = '', ?string $appid = '', ?string $pagepath = ''): array
  • newsFormatter(?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): array
  • mpnewsArticleFormatter(?string $title = '', ?string $thumb_media_id = '', ?string $author = '', ?string $content_source_url = '', ?string $content = '', ?string $digest = ''): array
  • mpnewsFormatter(?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): array
  • markdownFormatter(?string $content = '', ?string $touser = '', ?string $toparty = '', ?string $totag = '', string|int|null $agentid = null, ?int $enable_duplicate_check = 0, ?int $duplicate_check_interval = 1800): array
  • miniprogramNoticeContentItemFormatter(?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 = []): array
  • markdownFormatter(string $content = ''): array
  • markdownV2Formatter(string $content = ''): array
  • imageFormatter(string $base64 = '', string $md5 = ''): array
  • newsArticleFormatter(string $title = '', string $description = '', string $url = '', string $picurl = ''): array
  • newsFormatter(array $articles = []): array
  • fileFormatter(string $mediaId = ''): array
  • voiceFormatter(string $mediaId = ''): array
  • templateCardFormatter(array $template_card = []): array

通用方法签名说明

上述方法均支持以下可选参数(用于覆盖默认行为):

  • ?array $urlParameters:URL 模板参数(如 {access_token}{key}{type}
  • ?array $options:HTTP 客户端请求选项
  • ?\Closure $responseHandler:自定义响应处理回调,若提供则跳过默认验证逻辑
  • ?array $validatorRules:响应验证规则,默认 ['errcode' => 'required|integer|size:0']

注意事项

  1. 在企业微信管理后台正确配置应用 corpid / corpsecret / agentid 与群机器人 Webhook key,并确保相关 API 权限已开启。
  2. access_token 有效期为 7200 秒,refreshAccessToken() 默认缓存 7100 秒,避免高频请求。
  3. 关注企业微信接口的频率限制,避免触发限流。
  4. 上传的媒体文件有大小与格式限制,请参考企业微信官方文档。
  5. Webhook API 与 Server API 使用场景不同:Webhook 用于群机器人推送,Server 用于应用消息触达。
  6. 所有 HTTP 请求基于 Laravel 的 Http Facade,使用 Guzzle 7 驱动。

许可证

MIT License,详见 LICENSE

贡献

欢迎提交 Issue 与 Pull Request 来帮助改进此扩展包。