Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Wechat Official Account Mass Bundle Laravel Package

tourze/wechat-official-account-mass-bundle

A Symfony bundle for sending mass messages through WeChat Official Accounts, wrapping the WeChat mass-send API in configurable services so you can broadcast news, text, images, and other content to subscribers from your application. It integrates with the Tourze bundle ecosystem and helps keep messa...

View on GitHub
Deep Wiki
Context7

Getting Started

tourze/wechat-official-account-mass-bundle is a Symfony bundle (not a Laravel package) that wraps the WeChat Official Account 群发消息 (mass-send) endpoints — /cgi-bin/message/mass/sendall, /mass/send, /mass/preview, /mass/get, /mass/delete. Version 0.0.1 is the initial public tag, and the only release note is a link to the commit range, so treat this as pre-alpha: read the source before trusting any method signature.

First steps:

  1. composer require tourze/wechat-official-account-mass-bundle:0.0.1 — pin the exact version, there is no stability guarantee at 0.0.x.
  2. Read, in this order: the bundle class in src/ (usually *Bundle.php), the service class that actually issues HTTP calls, and config/services.yaml (or config/*.php). The service definition file tells you what arguments the mass-send service needs — that is your integration surface.
  3. Identify the transport dependency. Tourze bundles typically sit on top of a shared kernel/HTTP package and expect an access-token provider; note the exact package and version it requires before wiring anything.
  4. Populate credentials (appid/secret) in config/services.php + .env, and add your server's egress IP to the WeChat 后台 IP whitelist — mass-send calls fail with 40164 otherwise.

Your first use case should be a preview send, not a real send: /mass/preview targets a single OpenID, is not rate-limited like a broadcast, and is the only safe way to verify payload shape, media IDs, and error handling end-to-end.

Implementation Patterns

Wiring a Symfony bundle into Laravel. There is no package auto-discovery for this. Register the bundle's services yourself in a dedicated provider, mapping the bundle's constructor arguments to Laravel config:

$this->app->singleton(\Tourze\WechatOfficialAccountMassBundle\Service\MassMessageService::class, function ($app) {
    return new \Tourze\WechatOfficialAccountMassBundle\Service\MassMessageService(
        $app->make(\Tourze\WechatKernel\AccessTokenProvider::class),
        // ...remaining constructor args per config/services.yaml
    );
});

Prefer manual singleton bindings over trying to boot the Symfony kernel — most Tourze bundles have few services and no compiler passes you need.

Preview → send → poll. The documented happy path is three distinct calls, and your code should mirror it:

  • Build the message (text / image / voice / video / music / mpnews / wxcard) as a typed object, not a raw array. Typed classes will catch field-name typos like media_id vs mediaId that WeChat reports as an opaque 40007.
  • Preview it to your own OpenID.
  • Only then sendall (by tag or all subscribers) or send (by OpenID list, max 100 per call).
  • Persist the returned msg_id and poll /mass/get — the send call returns before delivery completes.

Queue everything. Mass sends are slow and quota-metered. Wrap the call in a queued job with $tries = 1 and a manual-review failure path. Never let a generic retry policy sit in front of a broadcast endpoint.

Targeting. Prefer sendall with filter: {is_to_all: false, tag_id: N} for segment sends over maintaining OpenID lists — it keeps your payload small and avoids the 100-recipient cap on /mass/send. Cache tag IDs in config; they're stable and rarely change.

Media is a separate concern. media_id values for image/voice/video/mpnews come from the upload endpoints, which likely live in a sibling bundle. Upload once, store the media_id alongside the asset, reuse it — WeChat media for mass-send is valid for 3 days, so expire your cache accordingly.

Testing. Inject a fake HTTP client (Symfony MockHttpClient or a Laravel Http::fake() adapter behind your own thin wrapper) and assert the exact JSON body. There is no sandbox for mass send, so payload assertions are your only regression net.

Gotchas and Tips

  • Version 0.0.1 with a changelog-only release note. The tag tells you nothing about API stability. Diff the commits before every bump, and pin 0.0.1 exactly in composer.json.
  • Symfony vs Laravel lifecycle. Container registration, config loading (Extension/Configuration classes), and event dispatching are all Symfony conventions. Do not expect config/mass-message.php to be published — there is nothing to publish.
  • Retries duplicate broadcasts. A timeout on /mass/send does not mean the send failed. Check /mass/get for the msg_id before considering a re-send, or you will double-bill your monthly quota.
  • Quota errors are not transient. 45009 (rate limit), 45028 (no quota left), 48001 (API unauthorized for this account type) all require human intervention — map them to distinct exceptions and alert, don't retry.
  • Access token lifetime. Tokens last ~2 hours and refreshing invalidates the previous one. If the bundle resolves a token per call, ensure the underlying provider is cached and shared; token thrash causes intermittent 40001 failures under load.
  • Content is immutable after send. /mass/delete recalls; it does not edit. Model any "edit and resend" flow as a new send with new quota consumption.
  • Check errcode even on HTTP 200. WeChat returns 200 OK with {"errcode": 40003, "errmsg": "invalid openid"}. Wrap the service response in a normalizer that throws on non-zero errcode — the bundle may or may not do this for you, verify it explicitly.
  • Extend by decoration, not forking. Because the surface is tiny, decorate the service class (bind your own implementation under the same interface) to add logging, metrics, and errcode normalization. That keeps you upgrade-safe when 0.0.2 lands.
  • Log full request/response pairs (redacting the token) on first deployment — this is the fastest way to debug field-name mismatches with no vendor documentation and no release notes to consult.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator