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

Laravel Max Client Laravel Package

geekcodev/laravel-max-client

A Laravel client for the MAX messaging platform that simplifies bot integration: configure credentials, send messages, alerts, and notifications, and call the MAX API through a clean, framework-friendly PHP wrapper for Laravel services, jobs, and apps. Built to keep MAX bot calls simple inside Larav...

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

  • The package is a thin Laravel service-provider adapter over geekcodev/max-php-client. v1.2.2 adds wrappers, singleton bindings and config keys — no new architectural surface, no migrations, no schema.
  • Two independent workstreams ship together (owner decision): (a) mini-app contact verification and read-side session helpers, (b) webhook subscription type coverage. Neither changes public signatures.
  • Security-critical logic deliberately lives in the core (Security\WebAppContactVerifier); the adapter does not duplicate the signing/verification algorithm. Good for security posture, but it converts the core into a hard dependency floor (^1.1.10) that we now have to track as a first-class dependency, not a transitive detail.
  • WebAppSession is final readonly and reads keys written by the existing max.webapp middleware (ResolveWebAppIdentity) — it slots into the current request lifecycle without new middleware.

Integration feasibility

  • Composer bump only (composer update geekcodev/max-php-client), plus optional config. No DB backfill: the confirmed-contact flag lives in the session, not in max_users.
  • One mandatory operational step after upgrading: re-run php artisan max:subscribe <url> per URL. Verified empirically (2026-10-16) on a live subscription: GET getSubscriptions() went 6 → 13 types with one URL and one subscription. Then confirm with php artisan max:subscriptions.
  • Clean installs and installs without a mini-app need nothing beyond the composer bump.
  • Mini-app adoption is a drop-in class swap: our local App\Services\WebAppContactVerifier / App\Support\WebAppSession map to WebApp\WebAppContactService / WebApp\WebAppSession, same behavior.

Technical risk

  • Behavioral change in a patch release. The default webhook subscription set moves from 6 to 13 types. Anyone on ~1.2.0 picks this up without a major-version signal; the actual behavior change only lands after re-subscribe, so the blast radius is deferred and easy to lose track of.
  • Silent under-delivery is the current bug being fixed, and the fix has its own silent-failure mode. Skip the re-subscribe and the symptom ("we upgraded, but edits still don't arrive") is indistinguishable from a package defect. This is the highest-probability support issue in the release.
  • Listener readiness. Hosts will start receiving message_edited, message_removed, dialog_cleared, dialog_removed, chat_title_changed, user_added, user_removed. Non-idempotent or order-sensitive listeners (edits arriving after creates, deletes for records already gone) can corrupt state or resurrect rows.
  • Subscribed-but-ignored types. user_added/user_removed are wired ahead of the chat-member-sync plan; PersistMaxChatListener currently returns on default => null. Low risk now, but it is a planned dependency we are pre-paying for and should track against that plan.
  • Session flag key rename (contact_confirmed by default). Integrators carrying the old key (max.webapp.contact_confirmed in i2tech) silently lose confirmation state and force re-auth unless they set MAX_WEBAPP_SESSION_CONTACT_CONFIRMED.
  • Deliberate exclusions. comment_* and bot_admin_permissions_changed are not in the default; any future feature needing them requires a config change and a re-subscribe, not a code change.
  • Config footgun. webapp.max_age drives auth_date freshness; max_age=0 disables replay protection (tested and allowed). That is a security-relevant value a well-meaning operator could set.

Key questions

  • Which environments/URLs hold MAX webhook subscriptions, and is re-subscribe a deploy-pipeline step or a runbook step? Who is accountable for verifying 13 types after each release?
  • Do our listeners tolerate the 7 new types — idempotency, out-of-order edits, deletes of unknown records, and unknown-type fallthrough?
  • Forced re-auth or env alias for the session flag key? This is a product decision with a user-visible prompt.
  • Do we need mini-app bridge phone numbers in max_users.phone? v1.2.2 explicitly does not write them — only chat-button request_contact does via PersistMaxUserPhoneListener. If the product assumes otherwise, that gap must be closed separately.
  • Do we need comment_* types? If yes, we own a webhook.update_types override that will diverge from package defaults forever.
  • Who owns the geekcodev/max-php-client version floor and its patch cadence, given security logic now lives there?

Integration Approach

Stack fit

  • Laravel app already running a MAX bot and/or mini-app with max.webapp middleware: direct fit.
  • Prerequisite: core ^1.1.10. Run composer update geekcodev/max-php-client explicitly rather than relying on a lockfile refresh, and check for transitive conflicts in the same pass.
  • No frontend or database change on our side. Mini-app frontend calls window.WebApp.requestContact() and posts the payload; the server verifies with WebAppContactService::resolve()/verify() and records confirmation through WebAppSession::confirm().

Migration path

  1. Composer bump plus core floor bump; run the test suite unchanged to confirm no public-API breakage.
  2. Replace local verifier/session classes with the adapter classes — name-only substitution, behavior preserved (validated in the i2tech integration project).
  3. Add webapp.session.contact_confirmed if we want a non-default flag key; otherwise set MAX_WEBAPP_SESSION_CONTACT_CONFIRMED=max.webapp.contact_confirmed to carry existing sessions through.
  4. Optionally pin webhook.update_types; omission is the right default for most hosts.
  5. Run php artisan max:subscribe <url> per environment, then php artisan max:subscriptions and assert 13 types in the release checklist.

Compatibility

  • Public API: additive only — new classes, Support\Config::webhookUpdateTypes(), two config keys with defaults. No signature churn; WebAppContext::verifyContact() was intentionally not added, so no facade surface to maintain.
  • Behavioral compatibility is the risk, not binary compatibility: same code, different event stream.
  • Dev/staging and production will drift until each is re-subscribed; treat subscription type count as a deploy-time invariant.
  • Long Polling (max:listen) is untouched — polling deployments get zero delta from the webhook change.
  • Explicit webhook.update_types overrides win over the new default, so hosts that pinned a list see no change at all.

Sequencing

  1. Listener audit first (before any deploy): confirm idempotency and safe handling of edits, deletes, clears, title changes and membership events.
  2. Staging upgrade + re-subscribe. Verify 6 → 13 via max:subscriptions; treat a mismatch as a release blocker.
  3. Soak. Let edit/delete/clear traffic accumulate; measure webhook request rate and log volume against the pre-upgrade baseline. Also confirm the user_added/user_removed no-op path produces no error noise.
  4. Mini-app swap in a separate PR from the framework upgrade, so either can be reverted independently. Decide re-auth vs alias before merging.
  5. Production release in a low-traffic window, with max:subscribe executed as part of the release and gated on the max:subscriptions assertion.
  6. Docs. Add re-subscribe to onboarding and upgrade runbooks, and note the excluded update types so nobody re-discovers that by reading code.

Operational Impact

Maintenance

  • Small code surface: wrappers only, no duplicated cryptography. The real maintenance obligation has shifted to keeping geekcodev/max-php-client at or above ^1.1.10 and tracking its security fixes — assign an owner.
  • Two additional env vars to document and template (MAX_WEBAPP_SESSION_CONTACT_CONFIRMED, MAX_WEBHOOK_UPDATE_TYPES), both optional with working defaults.
  • This release demonstrates a cadence risk: a patch version carried a behavioral default change. Expect future patch releases to require the same re-subscribe step; encode it in the release checklist rather than relying on memory.

Support

  • Expected ticket #1: "upgraded, edits/deletions still missing." Answer is re-subscribe; put it in release notes and the runbook, and have support ask for max:subscriptions output first.
  • Expected ticket #2: mini-app users re-prompted for contact confirmation after the default flag-key change. Pre-empt with comms or avoid entirely with the env alias.
  • Expected ticket #3: "phone from the mini-app isn't in max_users.phone." By design — bridge contacts and chat-button contacts are independent mechanisms. Needs product messaging, not engineering.
  • Verification failures log only the failure fact plus user_id (OWASP A09 compliant; no phone, no hash). Correct for compliance, but it means confirm-failure tickets have thin diagnostics — support will need a repro procedure around auth_date and max_age.

Scaling

  • Inbound webhook delivery grows from 6 to 13 types. Edits, deletes, clears and title changes are chat-activity-proportional, so on edit-heavy or high-churn chats the endpoint's request rate is likely to grow materially (estimate; measure in the staging soak rather than assuming a multiplier).
  • Per-event cost stays low: the two membership types currently short-circuit in PersistMaxChatListener, so their marginal cost is dispatch only, not writes.
  • confirm() regenerates the session id — cheap and once-per-confirmation, but it invalidates existing session payloads, so any client caching session data must handle the rotation.
  • Long Polling deployments see no scaling delta.

Failure modes

  • Missed re-subscribe → silent under-delivery with zero errors. Highest-likelihood failure. Mitigation: post-deploy assertion on max:subscriptions count, not a manual eyeball.
  • Override typo in webhook.update_types → the named type is silently not delivered. Empty/blank/duplicate values degrade safely to the 13-type default, but a mistyped name does not — validate against the known list.
  • Session flag key mismatch → every user appears unconfirmed; detect via a spike in contact-confirmation prompts immediately after deploy.
  • Core version drift below ^1.1.10 → Security\WebAppContactVerifier unresolvable; surfaces at first container resolution. Catch it at boot by resolving the binding in a health check.
  • Non-idempotent listeners now receiving message_edited/message_removed → duplicate rows or deleted-then-resurrected records.
  • webapp.max_age misconfiguration, especially 0, silently disables replay protection — a security regression that no test will flag for us.

Ramp-up

  • Engineering effort is small: composer bump, one artisan command per environment, two class-reference swaps — hours, not days. The listener-readiness review is the real work, roughly a day of focused review.
  • TPM/ops effort dominates: runbook and onboarding updates, per-environment subscription verification, and a user-comms decision on re-auth.
  • Test coverage in this release is unusually thorough for a patch — signature encoding variants, userId/phone substitution, formatted-number normalization, expiry and max_age=0, empty inputs, log-redaction assertions, session key rotation, config parsing edge cases, and command output. That substantially reduces bespoke QA; the remaining gap is one staging end-to-end test posting a real requestContact payload.
  • Recommend naming a single accountable owner for the two things most likely to be dropped: the core version floor and the re-subscribe step. Everything else in this release is self-contained.
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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager