tourze/wechat-work-intercept-rule-bundle
A Symfony bundle for managing WeChat Work (企业微信) intercept rules, offering configurable rule-based interception for API requests and messages with flexible handlers and easy integration into custom business logic.
This is an early (0.1.0) Tourze bundle covering the WeCom (企业微信) intercept rule (拦截规则) domain model. Based on the tourze/*-bundle naming convention and the 0.0.1 → 0.1.0 jump, expect a thin Symfony-style bundle: Doctrine-mapped entities, a repository, an enum or two, and a bundle class that wires them into the container. There is no documented public API surface yet, so treat the source as the specification.
Minimal steps:
composer require tourze/wechat-work-intercept-rule-bundle:^0.1 — pin the minor, not * (see Gotchas).src/ in this order: the *Bundle class → Entity/ → Enum/ → Repository/. That gives you the whole contract in a few minutes on a package this size.config/services.php/services.yaml inside the package for the extension alias and any doctrine.orm mapping registration, then confirm it appears in bin/console debug:config and bin/console doctrine:mapping:info.doctrine:schema:update --dump-sql (never --force on shared DBs) to create the backing table.First use case: you already have a WeCom sync job that pulls admin-side configuration; use this bundle as the persistence layer for intercept rules so you stop hand-rolling the table and integer status columns. Persist on sync, query on read, and let the bundle's enum own the type/status vocabulary.
Caveat: 0.1.0's release notes are a bare changelog link. Everything below is inferred from package naming and Tourze conventions — verify against
src/before designing around it.
Treat it as a data layer, not a client. Nothing in the name suggests it ships an HTTP client or token handling. Keep your existing wechat-work API/token service and use this bundle purely for the entity + repository:
final class InterceptRuleSynchronizer
{
public function __construct(
private readonly InterceptRuleRepository $rules,
private readonly WeComClient $client,
) {}
public function sync(): void
{
foreach ($this->client->listInterceptRules() as $remote) {
$rule = $this->rules->findOneByRemoteId($remote['id'])
?? new InterceptRule();
$rule->setRemoteId($remote['id']);
$rule->setName($remote['name']);
$rule->setType(InterceptRuleType::from($remote['type']));
$rule->setEnabled($remote['enabled']);
$this->rules->save($rule, flush: false);
}
$this->rules->flush();
}
}
Upsert by remote id, not by local id. WeCom is the system of record; your local table is a cache. That makes re-syncs idempotent and lets you delete local rows that no longer appear remotely.
Use the bundle's enum everywhere. The single biggest day-to-day win of a package like this is not the Entity class — it's replacing $row['type'] === 3 magic numbers with InterceptRuleType::BlockChat-style cases. Import it into your form types, API resources, and filters.
Bridge into Laravel rather than fighting it. If the host app is Laravel, don't try to boot a Symfony bundle. Two sane options: (a) read the entity for its property/column names and re-declare an Eloquent model against the same table, or (b) instantiate the bundle's enum and value objects directly (they're usually pure PHP with no container dependency) and keep persistence in Eloquent. Option (b) gives you 80% of the value for 20% of the work.
Test the repository against an in-memory SQLite DB. Cheapest way to confirm the Doctrine mapping is actually correct without touching a real WeCom tenant.
git diff 0.0.1..0.1.0 -- src/) before upgrading; the changelog link tells you nothing.doctrine:schema:validate afterwards.-bundle suffix means container extension + Doctrine mapping, not PSR-15 middleware. A Laravel app gets no auto-discovery, no service provider, no config publishing. Plan for the bridge pattern above or skip the package and copy the enum.getAccessToken(). You own token caching, retry, and the errcode/errmsg envelope handling — the bundle never sees an HTTP response.debug:container --tag=doctrine.repository_service, debug:config <alias>, doctrine:mapping:info. Mapping problems surface as "class not a valid entity" long before they surface as SQL errors.*Interface plus a default implementation registered under a container alias. If so, you can swap the repository or decorator without forking — check services.yaml for alias: entries first.How can I help you explore Laravel packages today?