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

Notify Laravel Package

guanguans/notify

Send notifications through dozens of channels—DingTalk, WeChat Work, Feishu, Bark, Slack, Telegram, and more—via one unified, framework-agnostic PHP API. Clean, extensible SDK with Laravel support for fast, consistent integration.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. guanguans/notify is a standalone, Guzzle-backed SDK with a fluent, one-class-per-provider design (Notify::dingTalk()->send(...)). It is not built on Laravel's Illuminate\Notifications contracts — there is no NotificationChannel, no Notifiable trait integration, no toDingTalk() convention. That is the single most important architectural fact for us: the package is a transport library, not a framework citizen. It slots in cleanly if we treat it as an outbound gateway behind our own port interface, and poorly if we expect it to replace our existing Notifiable/queued-notification stack. Given the breadth (30+ providers), the realistic role is "swappable egress adapter for third-party push webhooks," not "core notification system."

Integration feasibility. Composer-installable, MIT licensed, no service or daemon required — it is pure HTTP fan-out, so a spike is hours, not days. The blockers are mundane and checkable: PHP version constraint against our runtime, Guzzle major-version compatibility with our existing HTTP-client usage, and whether it hard-depends on Guzzle vs. accepting a PSR-18 client (relevant for central observability/mocking). We should validate that it does not collide with laravel-notification-channels/* packages already in the tree.

Technical risk.

  • Provenance: the repository is listed as unknown and the release date (2026-09-24) is anomalous relative to today. Before anything else, confirm the canonical repo, tag signing, and that Packagist metadata maps to the same source. 690 stars and a middling score are adequate for a utility dependency, insufficient for a critical alerting path without a fallback.
  • Bus factor: single-maintainer, community-supported ecosystem. Per-provider API churn (Telegram token formats, Slack tier limits, DingTalk signing, WeWork deprecations) means the package is a moving target we do not control.
  • Channel sprawl as liability: 30+ providers means 30+ code paths we will never test. Coverage breadth is a feature for discovery and a maintenance tax for production.
  • Failure semantics: fluent builders + Guzzle mean timeouts, retries, and error surfacing are largely our responsibility. Retrying blind on a push channel risks duplicate user-facing alerts.
  • Docs language: documentation and issue history skew Chinese-first. Fine technically; a real cost for on-call engineers triaging at 3am.

Key questions for the maintainer/spike.

  1. What is the supported PHP/Laravel matrix, and is there an official service provider or only manual instantiation?
  2. Does the transport honor an injected PSR-18 client, and are timeout/retry policies configurable globally or per channel?
  3. How are non-2xx and provider-specific error envelopes surfaced — exceptions, result objects, or booleans? Can we distinguish "token expired" from "rate limited" from "malformed payload"?
  4. Is there a fake/mock mode suitable for CI, or must we intercept HTTP?
  5. Are credentials redacted from exception messages and logs by default?
  6. Do any providers support idempotency or dedupe keys?
  7. What is the maintainer's security-disclosure process and historical patch latency?

Integration Approach

Stack fit. Best treated as an egress adapter layer, not a notification framework. Concretely: define an internal PushGateway interface (send(Channel, Payload): Result), implement a GuanguansPushGateway that delegates to the SDK, and bind it in the container. Laravel Notification classes then use a single custom channel that resolves the target provider from config. This keeps the vendor behind a seam we can replace with direct HTTP calls for the 3–5 providers we actually use, and prevents provider-specific builder calls from leaking into domain code.

Migration path. Do not migrate all channels. Pick the one or two providers already in production (most likely DingTalk, Slack, or Telegram), build the adapter, and dual-run: existing code path stays primary, SDK path sends in shadow mode to a test channel with payload diffing for a week. Cut over per-provider behind a config flag. Keep the legacy path intact until the new path has a clean two-week error budget.

Compatibility. Pin to an exact minor version with a lockfile; add a Composer conflict guard for Guzzle majors we do not support. Verify PHP constraint against every runtime (web, queue workers, scheduler) — queue workers are the usual place a version skew surfaces. Confirm it coexists with our existing notification-channel packages and does not double-register an HTTP client or config namespace.

Sequencing.

  1. Provenance and license review — canonical repo, signed tags, license file in the distributed artifact. Gate for everything else.
  2. Version/PHP/Guzzle compatibility matrix against our runtimes.
  3. Spike: one provider, one real message, from a queue worker.
  4. Adapter layer + PushGateway interface + container binding + config schema (provider → credentials, timeout, retry policy).
  5. Error taxonomy and mapping into our existing alerting/observability conventions.
  6. Shadow-mode dual-run on the pilot channel.
  7. Per-provider rollout behind flags, starting with lowest-blast-radius channels (internal ops alerts) and ending with customer-facing ones.
  8. Documented fallback: direct HTTP for the top providers if the dependency is abandoned.

Operational Impact

Maintenance. Owned by whoever owns notifications — assign explicitly. Commit to a monthly dependency review plus a dependabot PR lane; pin and upgrade deliberately rather than tracking latest, because a minor bump can silently change a provider's payload shape. Budget a small recurring allowance for provider-side breakage (tokens, deprecations, rate-limit policy changes) that arrives without a package release. Treat the dependency as replaceable: the adapter seam is the real asset, and we should be able to drop the package for our top three providers in under a sprint.

Support. Community-only. No SLA, no vendor escalation. Our internal on-call is the support tier, so the runbook must cover: how to identify which provider failed, how to rotate a webhook/token, and how to disable a channel without a deploy (config flag). Documentation is largely Chinese-language; budget translation effort for the two or three providers we depend on, and capture our own internal docs rather than relying on upstream.

Scaling. Fan-out is per-message HTTP; there is no batching. Throughput ceiling is provider rate limits, not our PHP processes: Slack tiered limits, Telegram ~30 msg/s per bot, DingTalk per-webhook throttles. Enforce per-provider concurrency caps and backoff in our queue layer, not in the SDK. Memory footprint is negligible; the real scaling concern is the notification queue becoming a shared bottleneck — isolate push-sending onto its own queue and worker pool so a provider slowdown does not starve transactional mail or other jobs. Secrets scale poorly: 30 providers × environments means a secrets-management story (vault-backed config, not .env sprawl) before the third provider is enabled.

Failure modes.

  • Partial fan-out: one alert to five channels, two succeed and three silently fail. Requires per-channel result aggregation and an explicit "all channels failed" tripwire that alerts on the alert path itself.
  • Swallowed errors: fluent builders can return without throwing on non-2xx. Every send must assert on status and raise.
  • Duplicate sends: retries without idempotency re-notify users. Cap retries, prefer at-most-once for user-facing channels and at-least-once for ops channels.
  • Auth expiry: revoked Slack apps and rotated bot tokens fail closed and quietly. Add synthetic canary sends per provider on a schedule, alerting on failure.
  • Payload rendering divergence: Markdown/HTML escaping differs per provider; a message that renders on Slack can break on DingTalk. Keep payloads plain-text-first with provider-specific formatting isolated in templates.
  • Upstream abandonment: no release for N months plus an unpatched provider break is the realistic end state. Mitigate with the adapter seam and a documented direct-HTTP fallback.

Ramp-up. Sending a message is roughly an hour of ramp — the API is genuinely simple. Full production readiness (adapter, error taxonomy, retry policy, canaries, secrets, runbook, fallback) is realistically 2–4 engineer-days for a two-provider scope, and the cost scales with provider count, not with code complexity. Restrict enabled channels to the 3–5 we actually use; the remaining 25+ are discovery value only and should be treated as untested surface.

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.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core