tourze/wechat-work-mini-program-bundle
A Symfony bundle that integrates WeChat Work (Enterprise WeChat) mini program capabilities into your PHP application, providing ready-to-use services, configuration, and dependency injection wiring for authentication, messaging, and mini program APIs so you can connect your app to WeChat Work with m...
This is the first public release (0.0.1) and the release notes contain no changelog, migration notes, or feature list — only a link to the commit range. Treat the package as unvetted scaffolding and budget time for a source read before you commit to it.
Orientation pass (do this first, ~15 minutes):
composer require tourze/wechat-work-mini-program-bundle and immediately inspect what landed:
composer.json — check the type field. The -bundle suffix and the tourze/* namespace strongly suggest a Symfony bundle, not a Laravel package. There is very likely no Illuminate\Support\ServiceProvider in the tree.src/ for the bundle entry class (typically *Bundle.php extending Symfony\Component\HttpKernel\Bundle\Bundle) and for DependencyInjection/Configuration.php + *Extension.php — that pair tells you exactly which config keys exist.README.md and any docs/ — expect Chinese-language docs or none at all.tourze/wechat-work-* or an EasyWeChat-style client). That lower-level package is what you actually want to integrate, not the bundle.First real use case for a WeChat Work (企业微信) mini program is the login exchange: take the code returned by wx.login() on the client, call the mini program's session endpoint with your corp_id/corp_secret, and get back userid/session_key/openid. Wire that into a single POST /api/login route, cache the access token, and you have a working vertical slice that exercises config, HTTP, and error handling at once.
// config/services.php
'wechat_work' => [
'corp_id' => env('WECHAT_WORK_CORP_ID'),
'corp_secret' => env('WECHAT_WORK_CORP_SECRET'),
'agent_id' => env('WECHAT_WORK_AGENT_ID'),
],
// app/Providers/WeChatWorkServiceProvider.php — adapt to the real constructor signature
$this->app->singleton(WeChatWorkClient::class, fn ($app) => new WeChatWorkClient(
corpId: config('services.wechat_work.corp_id'),
corpSecret: config('services.wechat_work.corp_secret'),
));
Do not assume the constructor signature — read it. At 0.0.1 it is unlikely to be stable.
Wrap, don't scatter. Whatever the package exposes, put a thin application-level adapter in front of it and have the rest of your codebase depend on your adapter. Given the pre-1.0 version number, this is the single highest-value decision you'll make: it lets you swap or fork the package without touching call sites.
final class WeChatWorkGateway
{
public function __construct(private WeChatWorkClient $client) {}
public function resolveUserFromCode(string $code): WeChatWorkUser
{
// normalise the vendor response into a domain object here
}
}
Token lifecycle belongs in the cache, not in the request. Access tokens are ~7200s and rate-limited per corp. Resolve them through Cache::remember() with a key namespaced by corp_id and agent_id, and refresh proactively rather than on 42001/40014 failures. If the package ships its own token cache, confirm whether it is PSR-6/PSR-16 and whether you can inject a Laravel-backed adapter — otherwise it will silently write to the filesystem under var/cache.
Inject the HTTP client. Laravel's Http facade is Macroable but not a drop-in for PSR-18/PSR-18-style clients. If the package accepts a PSR-18 client, the clean bridge is symfony/http-client (which Laravel ships with) constrained to a single client instance, so you can swap in MockHttpClient in tests. If it hardcodes its own client, that's a real testability cost — note it.
Queue the outbound calls. Message sends, media uploads, and bulk operations are slow and rate-limited. Dispatch a job with ->onQueue('wechat') and ->middleware(RateLimited::by('wechat-work')) from Illuminate\Queue\Middleware\RateLimited rather than calling inline from a controller.
Config as first-class. Mirror every key from the bundle's Configuration.php into config/wechat_work.php, back it with env() at the top level only, and add a boot-time validation (a small assertConfigured() in the provider) so a missing agent_id fails at deploy rather than at first customer request.
Testing seam. In TestCase::setUp(), bind a fake gateway. Because you've wrapped the vendor, the bulk of your suite never touches the package and you only integration-test the adapter with recorded fixtures.
-bundle naming is a Symfony convention. There will be no config/wechat_work.php to publish, no facade, no auto-discovery. Plan for manual wiring. Verify before you promise a timeline."tourze/wechat-work-mini-program-bundle": "0.0.1") and read every diff before bumping. Do not use a caret range.ls vendor/tourze/wechat-work-mini-program-bundle/tests and look for a CI badge. Absence means you are the QA.services.yaml resource-loading that assumes a Symfony kernel (%kernel.project_dir%, %kernel.debug% parameters). These throw at container compile time in Laravel and are usually easier to bypass than to fix.60020 not allow to access from your ip. This bites hardest in CI and in serverless/queue-worker environments with rotating egress IPs — which is precisely where you'd want to run the queued jobs from the pattern above. Use a NAT gateway with a fixed IP.agent_ids under the same corp have separate tokens; a shared cache key will cause intermittent 40014s under concurrency. Namespace the key.errcode/errmsg in the JSON body with HTTP 200. Any code that checks only $response->successful() will treat failures as successes. Make your adapter throw a domain exception on non-zero errcode and log the raw payload.docs/wechat-work.md recording the concrete request/response shapes you've verified — you cannot rely on the package's README to stay accurate.Verdict: usable only after a deliberate source audit and behind your own adapter. The absence of a changelog means this review cannot confirm what changed or what the package actually does — the next release note should be the trigger to revisit this assessment.
How can I help you explore Laravel packages today?