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

Rocket Chat Notifier Laravel Package

symfony/rocket-chat-notifier

Symfony Notifier integration for Rocket.Chat. Configure a webhook DSN with access token and channel, then send ChatMessages with custom payloads and attachments to control bot name, avatar, channel, and message content.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

What the package actually is symfony/rocket-chat-notifier is a transport bridge for the Symfony Notifier component, not a general-purpose Rocket.Chat SDK. It contributes one thing: a rocketchat:// DSN scheme that maps a webhook URL into a Transport implementing ChatterInterface, plus a RocketChatOptions value object for alias, emoji, avatar, channel, and attachments. All actual message delivery goes through Rocket.Chat Incoming Webhooks — there is no REST API client, no room management, no user lookup, no WebSocket support.

Architecture fit (Laravel)

  • Conceptual mismatch, low technical mismatch. Laravel has its own Notification/Channel system (Notification::channel, toRocketChat()); this package belongs to a parallel, Symfony-native notification stack. There is no Laravel bridge, service provider, or facade. Integration means running Symfony Notifier inside Laravel as a sidecar service, then either using it directly ($chatter->send(new ChatMessage(...))) or wrapping it in a custom Laravel channel.
  • FrameworkBundle autoconfiguration is unavailable. In Symfony you register via messenger/notifier YAML; in Laravel you must manually instantiate RocketChatTransportFactory, call create($dsn), and bind the resulting transport/chatter into the container. This is ~40 lines of glue that you now own.
  • Dependency footprint. Pulling symfony/notifier + symfony/http-client into a Laravel app is not free: it adds Symfony components that may collide with Laravel's own pinned symfony/* constraints (Laravel 10 → ^6.4, Laravel 11/12 → ^7.x), and it introduces a second notification abstraction the team must learn.
  • The honest alternative: a first-party Laravel channel using Http::withOptions()->post($webhookUrl, $payload) is roughly 30–50 LOC, has zero dependency risk, and matches the framework idiom. This package's real value is not capability — it is standardization, the options object, and Symfony's maintenance/security process.

Integration feasibility

  • Feasible and small in scope, provided the team accepts the "Symfony island" pattern. Configuration is a single DSN env var: rocketchat://WEBHOOK_ID%2FWEBHOOK_TOKEN@host?channel=NAME.
  • Two configuration footguns to budget for:
    1. The "ACCESS_TOKEN" is the webhook id/token pair joined by a slash and URL-encoded (%2F). A plain copy-paste of the webhook URL will silently fail auth — this is the single most likely onboarding defect.
    2. channel in the DSN is advisory; per-message channel override via payload only works if a custom Incoming Webhook Script is installed on the Rocket.Chat side. Without that script, channel and rich formatting are effectively fixed/limited. That script is JavaScript deployed in Rocket.Chat admin — a second artifact your team must own, review, and version.
  • The RocketChatOptions($attachments, $payload) constructor is positional and has two accepted shapes ("for backward compatibility both usages are valid"), and payload.text / payload.attachments are silently overridden by ChatMessage subject and constructor attachments. This is a correctness footgun that will produce "why is my title missing" tickets.

Technical risk

  • Delivery risk: high. Incoming Webhooks are fire-and-forget. Rocket.Chat can return HTTP 200 with an error body, and the bridge has no retry, no idempotency key, no delivery receipt, and no dead-letter path.
  • Version-coupling risk: medium. The package tracks Symfony's release train (5.4 → 8.0-BETA1 in the changelog), and Symfony 8 requires PHP ≥ 8.4. Upgrading the notifier may force a PHP/Laravel upgrade, not the reverse.
  • Adoption-signal risk: low, but misread it correctly. 13 stars / 0 dependents is expected for a read-only split of the symfony/symfony monorepo — usage is measured by the monorepo, not this repo. However, it does mean near-zero public Q&A, blog posts, or Laravel-specific examples; you will be reading Symfony source, not tutorials.
  • Maintenance/security risk: low. Symfony core team ownership, MIT, coordinated CVE process, predictable semver and LTS branches (6.4 LTS, 7.4 LTS).

Key questions to resolve before committing

  1. Is Rocket.Chat a first-class, durable channel, or a nice-to-have? If durable → build a proper channel (either this package or in-house) with queue + retry + monitoring. If nice-to-have → 40 lines of Http::post wins on total cost of ownership.
  2. Do we need the custom webhook script (channel override, rich payloads)? If yes, who owns that JS, and where is it version-controlled and reviewed?
  3. Do we need anything beyond "post a message to one channel"? (DMs, threads, edits, reactions, room provisioning, two-way interaction.) If yes, this package is the wrong tool — you need the Rocket.Chat REST API, not a webhook bridge.
  4. What is our Laravel/symfony/* constraint baseline today, and does composer require resolve cleanly or force a transitive bump?
  5. Who on the team is accountable for the Symfony Notifier abstraction, and will they still be here at the next LTS hop?

Integration Approach

Stack fit assessment

Criterion Verdict
Laravel 10 (Symfony 6.4 components) Workable; pin symfony/notifier ^6.4, test resolution carefully
Laravel 11/12 (Symfony 7.x) Best fit; aligns with ^7.x bridge releases
Laravel 9 or older Not recommended — PHP/Symfony floor conflicts
PHP 8.1–8.3 Fine for 6.4/7.x bridges; Symfony 8 line needs PHP 8.4
Team Symfony fluency: low Adds a second notification paradigm — prefer an in-house channel

Recommended integration shape (if we proceed)

  1. Do not let application code touch the transport directly. Introduce a thin application-level port, e.g. App\Contracts\ChatNotifier with send(string $channel, string $text, array $fields = []), and implement it once over Symfony's ChatterInterface. This isolates the dependency so it can be swapped for Http::post in an afternoon if the bridge disappoints.
  2. Register in a dedicated service provider. Construct the transport from the DSN in config/services.php (Laravel-idiomatic) rather than adding a bespoke config/rocket_chat.php. Bind as a singleton; keep the DSN out of code and out of any config cache dump by reading it at resolve time.
  3. Validate the DSN at boot, not at first send: assert the scheme, assert the token contains the encoded %2F separator, assert the host resolves. Fail fast in CI with a smoke-test webhook channel.
  4. Wrap sending in a queued job from day one (ShouldQueue, $tries = 3, exponential backoff, failed() → log/alert). Never call the chatter synchronously from a request or from inside a DB transaction.
  5. Normalize the message layer. Build a small builder that emits Rocket.Chat-shaped attachments (color, title, text, fields) so application code never constructs raw payload arrays — this contains the "text/attachments silently overridden" footgun in one place.
  6. Version-control the Rocket.Chat webhook script (if used) in the repo under e.g. ops/rocketchat/incoming-webhook.js, with a documented deploy step and a note in the runbook.

Migration path & sequencing

  • Phase 0 (½ day): Spike — install in a throwaway branch, confirm Composer resolution against current composer.lock, confirm a real webhook round-trip from a tinker session, confirm whether the custom script is required for our target channel(s). Decision gate: proceed vs. build in-house.
  • Phase 1 (1 day): Port interface + service provider + DSN validation + queueable job + failure logging. No product features.
  • Phase 2 (1 day): Message builder + 2–3 real use cases (e.g. deploy alert, error budget breach, order exception) wired to Laravel events → jobs.
  • Phase 3 (ongoing): Alerting on the failure log, dashboard, runbook, and a documented secret-rotation procedure (rotate webhook → update env → config cache clear → deploy).

Exit strategy (state this up front): because all calls funnel through the ChatNotifier port, replacing the bridge with a native HTTP channel is a single-file change. That caps the blast radius of the low adoption signal.

Operational Impact

Maintenance

  • Package-level: low. Symfony's release train is predictable (twice-yearly minors, monthly patches, LTS branches). Expect a required bump roughly every 12–24 months, coupled to the Laravel/Symfony/PHP upgrade cycle.
  • Glue-level: yours. The service provider, DSN validation, message builder, queue job, and (if used) the Rocket.Chat-side webhook script are all unowned-by-upstream artifacts. Budget ~2–4 days/year of care and feeding.
  • Secret rotation is the recurring operational chore: the webhook token lives in a URL-shaped DSN, so rotation means env change + config:cache + deploy on every environment, including any local/staging stacks that send to shared channels.

Support

  • Upstream support runs through the symfony/symfony monorepo issue tracker, not this repo; expect Symfony-idiomatic answers and no Laravel-specific guidance. Security issues follow Symfony's coordinated disclosure and CVE process — this is a genuine advantage over hand-rolled webhook code.
  • Internal support risk is bus factor: few engineers will know ChatterInterface/RocketChatOptions semantics. Mitigate with the port abstraction and a short ADR documenting the DSN format, the %2F encoding trap, and the options precedence rules.

Scaling

  • Throughput: Incoming Webhooks are the bottleneck, not PHP. They are rate-limited per integration and are not designed for fan-out. Sustained volume above a few messages/second, or bursts during incidents, will be throttled and dropped silently.
  • Mitigation: queue with concurrency caps (e.g. 1–3 workers for this queue), token-bucket rate limiting per channel, and message digesting/aggregation for high-frequency event classes (one message with multiple fields beats 50 individual posts).
  • Fan-out design: one webhook per logical channel; if the payload-level channel override requires the custom script, that script becomes a scaling and correctness dependency — test it under load.
  • Payload size: Rocket.Chat attachments are size-limited; long stack traces or large JSON must be truncated with a link to the source of truth, never dumped raw.

Failure modes

Mode Symptom Mitigation
Malformed DSN (unencoded /) Auth failure on every send; 401/403 Boot-time DSN validation; CI smoke test
Webhook disabled/rotated 404/401, all traffic dead silently Alert on sustained send failures; healthcheck message to a canary channel
HTTP 200 with error body Appears healthy, nothing delivered Log response body; periodic synthetic message + absence detection
Rate limit (429) Dropped bursts Queue + backoff + per-channel rate limiter
Network timeout Job retries, duplicate posts Idempotency via a dedupe key in the message text/field; bounded retries
Options precedence surprise Missing title/text in message Single message builder; unit tests on output shape
Rocket.Chat down Queue backlog Bounded queue depth, dead-letter, alert on oldest-job age
Webhook script error (if used) Payload silently dropped or reformatted Script unit test against sample payloads; version it

Ramp-up

  • Symfony-fluent engineer: ~2–4 hours to be productive (Notifier concepts, DSN, options object).
  • Laravel-only engineer: ~1 day, mostly spent on concepts that don't exist in Laravel (Transport, TransportFactory, ChatterInterface, ChatMessage, options precedence) and on the DSN encoding trap. No Laravel-native docs exist, so onboarding must be internal documentation, not a link to the README.
  • On-call: the runbook must answer three questions — how do I confirm Rocket.Chat delivery is working, how do I rotate the webhook, and how do I drain or drop the notification queue.

TPM recommendation Treat this as a low-risk, low-value dependency: technically sound and well-maintained upstream, but it delivers ~150 lines of equivalent capability while adding a parallel notification abstraction to a Laravel codebase. Approve it only if Rocket.Chat is a durable, first-class channel and the team wants Symfony's security/upgrade process behind it. Otherwise, build a native Laravel channel (~1 dev-day, zero dependency risk). Either way, gate on the Phase 0 spike and mandate the ChatNotifier port so the decision remains reversible.

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.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource