tourze/wechat-work-group-chat-bundle
Symfony bundle from Tourze that adds WeChat Work (企业微信) group chat support to PHP applications. It streamlines configuring and integrating enterprise group messaging so you can wire chat features into your service with minimal boilerplate, following standard bundle conventions.
composer require tourze/wechat-work-group-chat-bundle:0.0.1. At 0.0.1 there is no stability guarantee and Composer's default constraint resolution is not something you want deciding your API surface for you.*Bundle.php class, a DependencyInjection/ directory with an extension and possibly compiler passes, Entity/ or Model/ classes, Attribute/ or Annotation/ markers, and a README.md that is usually thinner than the code. The composer.json require block is your fastest signal for what HTTP client and SDK layer it sits on top of.WechatWorkGroupChatServiceProvider and no publishable config. Your first task is not calling the API — it is deciding how to boot a Symfony-style bundle inside Laravel's container. In practice that means instantiating the bundle's service classes manually in a app/Providers/WechatWorkServiceProvider.php, or accepting the cost of pulling in symfony/dependency-injection and booting a minimal container just for this bundle.php artisan wecom:group-chats that resolves the client, calls the list endpoint with the corp's access token, and dd()s the first page. That single command tells you whether the bundle handles token acquisition for you or expects you to inject it — the answer changes everything downstream.// app/Providers/WechatWorkServiceProvider.php
public function register(): void
{
$this->app->singleton(GroupChatClient::class, fn ($app) => new GroupChatClient(
corpId: config('services.wecom.corp_id'),
secret: config('services.wecom.group_chat_secret'),
httpClient: $app->make(\Symfony\Contracts\HttpClient\HttpClientInterface::class),
));
}
Note the HttpClientInterface — Tourze bundles almost always type-hint Symfony contracts rather than PSR-18, so you will likely need symfony/http-client bound in the container even inside a Laravel app.
App\Services\Wecom\GroupChatRepository that exposes plain arrays or your own DTOs. This is the only reliable way to survive a 0.0.1 → 0.0.2 bump, and it keeps Symfony types out of your controllers and jobs.config/services.php, not env calls. Read WECOM_CORP_ID, WECOM_GROUP_CHAT_SECRET, and any agent ID from config so config:cache works. Never call env() from inside a service class.Cache::remember('wecom:token:'.$corpId, 7000, ...) and use a lock (Cache::lock) around the fetch so ten concurrent queue workers don't all hit the token endpoint and invalidate each other.Schedule::command(...)->hourly() and persist results to your own tables. Your UI then reads local rows and stays fast.$cursor = null;
do {
$page = $this->client->listGroupChats($cursor, limit: 100);
$this->upsert($page->items());
$cursor = $page->nextCursor();
} while ($cursor && ++$i < 200);
GroupChatSynced / GroupChatMemberJoined from your adapter, not from inside bundle callbacks. Symfony EventDispatcher hooks the bundle may expose won't be wired to Laravel's dispatcher automatically — bridge them explicitly if you need them.errcode. Depending on how thin the bundle is, it may or may not convert that into an exception. Wrap every call in a try/catch that inspects errcode and maps the common ones (40001 invalid secret, 42001 token expired, 45009 rate limit exceeded) before they reach your job's retry logic — otherwise 42001 retries forever instead of refreshing the token.0.0.1 is a link to a commit list. That means: no documented feature set, no migration guide, and no signal about what 0.0.2 will break. Budget an hour to read src/ end to end before committing to the dependency, and vendor-lock the version in composer.json with an exact constraint.DependencyInjection/ for CompilerPass classes early — they are the most common source of "it works in the bundle's tests but not in my app."errcode 40001 or an empty list with no error.45009 means you've exceeded the daily or per-minute quota; 45033 is concurrent-call throttling. If you fan out sync jobs per chat, serialize them or cap concurrency in the queue worker — parallelizing this API is how you get a 24-hour ban.BindingResolutionException for HttpClientInterface or LoggerInterface means the bundle expects Symfony's container defaults. Bind Symfony\Contracts\HttpClient\HttpClientInterface to Symfony\Component\HttpClient\HttpClient::create() (or a scoped PSR-18 adapter) in your service provider.Attribute-based mapping classes for response hydration. Overriding the token provider is usually the highest-value customization, since token handling is where 0.0.1-grade packages are most often naive.errmsg plus the request timestamp. Add a middleware or a small decorator on the transport that logs method, errcode, and errmsg at debug level; without it, debugging errcode 40003 (invalid openid/userid) in production is guesswork.0.0.1, treat it as a scaffold for the API calls and own the retry, caching, and persistence layers yourself.How can I help you explore Laravel packages today?