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

Max Php Client Laravel Package

geekcodev/max-php-client

A PHP client for the MAX messaging platform API, offering convenient methods to authenticate, send messages, and handle updates within Laravel or plain PHP applications. Simplifies integration with MAX bots and services.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

  • Feature: inbound contact → phone capture — now actually reachable. v1.1.11 fixes a regression where a contact attachment arriving without hash (or with hash: null) threw InvalidResponseException, the webhook controller returned 400 invalid_payload, and the update was dropped entirely and never redelivered once MAX exhausted retries. The official OpenAPI spec declares hash nullable and non-required; our client had tightened it to mandatory in bdfc828. Net effect: "user shares contact → operator never sees it" was a live production defect, not a hypothetical. ContactPhoneExtractor::fromVcf() only delivers business value if the payload survives fromArray() first — this release makes the primitive reachable in the wild.
  • Build vs. buy: retire in-house vCard parsing. Still holds, and gets stronger. The release replaces a hand-rolled parser (RequestFlowService::telFromVcf() in i2tech) with two user-visible wins: folded vCard lines are now unfolded (previously long numbers were silently truncated at the line break and persisted truncated), and property matching is case-insensitive (tel: vs TEL). Combined with the hash fix, the "contact arrives → CRM record exists" path is now unbroken end-to-end. Fund as a bug-fix ticket, not a dependency bump.
  • New product decision: what do we do with unverified phone numbers? With the hash fix, hash-less contacts now flow through — but ContactVerifier::verify() returns false for empty hash (fail-closed, unchanged), so those numbers arrive unverified. Decide explicitly: can an unverified number create a lead / trigger a callback, or does it land in a review queue? Before v1.1.11 this question was moot because the payload never arrived; now it is a daily occurrence.
  • Roadmap: canonicalization is deliberately ours. The library returns the number as-is, no normalization; if the phone is a key (CRM, dedupe, lead matching) the consumer must canonicalize. Own an E.164 step downstream, or accept raw-format keys and the duplicate risk. Decide before shipping dedupe or lead-matching on top.
  • Data-quality risk to schedule, not ignore. Validation still rests on a single confirmed real-world capture (Android client, PRODID:ez-vcard 0.10.3, Russian number, no leading +). International formats remain unverified. Multi-country support is an open backlog item with a soft-launch / canary — not a solved problem.
  • Operator-console fix worth claiming. Attachment::$filename now carries the uploaded file's real name (read from top level, falling back to payload). Previously the admin UI showed the service name getfile because the DTO carried no name and consumers derived it from the download URL's last segment. Cheap, visible quality win in the operator experience.
  • Unblocked use cases beyond contacts. Chat with status suspended no longer throws (previously an unhandled enum value). Video attachments now expose width/height/thumbnail/duration plus rendition streams (mp4_1080 … mp4_144, hls); audio exposes transcription; callbacks expose timestamp/user with a callback.user fallback for Update::$user; subscriptions expose time. Each of these is a product surface that was silently blank — thumbnails in the operator inbox, playback quality selection, transcription-based search, callback attribution. Size them as follow-ups; they are now free to build.
  • Schema asymmetry to track. Inbound ContactAttachmentPayload has no vcf_phone; outbound payloads do. Correct consumer pattern remains $contact->vcfPhone ?? ContactPhoneExtractor::fromVcf((string) $contact->vcfInfo). Platform ask: why one-directional? Document in integration onboarding.
  • Scoping known gaps. Only the first non-empty TEL is returned; X-TEL ignored. No TYPE=cell preference, no multi-number contacts, no fallback when the first number is a fax/landline. Also newly flagged upstream: FailedUserDetails::$userId === 0 is a sentinel for "absent," so a real user_id: 0 is indistinguishable and drops out of toArray(); FileAttachmentPayload still reads legacy file_size, which the official schema does not confirm (size is now also available). Both deferred to v2.0.0 — note them as accepted limitations.
  • Deprecation reversal to absorb into planning. v1.1.11 removes @deprecated from addChatMembers() / AddChatMembersResult, explicitly cancelling the v1.1.6 line item that listed it for removal before v2.0.0. If a roadmap or migration doc says "remove before v2," correct it. Conversely, VideoUrls::$mp4 and $preview remain legacy and are slated for removal in v2.0.0 — that removal warning is now explicit.

When to Consider This Package

Adopt when:

  • You are on PHP 8.4 with a Laravel/PHP integration to the MAX messenger and need to act on shared contacts (CRM ingest, callback routing, conversation enrichment) — and especially if you are currently losing contact updates with 400 invalid_payload. That is the headline of this release.
  • You currently hand-parse vcf_info yourself — the truncation and case-sensitivity bugs are fixed for free, and v1.1.11 additionally removes a silent payload-drop path.
  • You need PII-safe behavior by default: the extractor does not log and does not throw, keeping vcf_info and the number out of journals (OWASP A09), with logging left to the caller. Appropriate for regulated environments.
  • You need richer attachment handling: filenames, video dimensions/thumbnails/renditions, audio transcription, callback attribution, suspended chats.
  • You want a maintained dependency with real engineering hygiene: PHPStan level max clean, lint clean across 112 files, PSR-12, 389 tests / 1007 assertions, 99.82% line coverage (1668/1671), composer audit clean.

Look elsewhere or plan to compensate when:

  • The release is not published yet. v1.1.11 is marked in progress as of 2026-10-20 — code and quality gate are green, but merge dev → main, the tag, the GitHub Release and the Packagist publish happen only on explicit request. Do not plan a sprint against it until the tag exists; pin a commit or wait.
  • You need normalized E.164 output out of the box. Not provided, by design. You own canonicalization.
  • You need multi-number extraction, TYPE-aware selection ("prefer mobile"), or X-TEL handling — not supported.
  • You need high-confidence international coverage. One country's format is empirically confirmed.
  • You use exhaustive match (ChatStatus) without a default. Adding ChatStatus::Suspended is the release's only behavioral change and will surface as an unhandled-match error at runtime. This is a small but real migration task — audit for match over ChatStatus and add default.
  • You are on PHP < 8.4, or you need a channel-agnostic contact parser (this is MAX-specific).
  • You require fully automated end-to-end verification. Contact events can only be produced by a live MAX user; the integration smoke group did not run this cycle (no MAX_API_TOKEN). Coverage is fixture + manual run — budget manual QA and a staged rollout.

How to Pitch It (Stakeholders)

To executives (one paragraph): A patch release to our MAX messenger client that fixes a customer-visible failure: contacts shared in chat were being rejected at webhook ingest with 400 and silently dropped, so operators never saw them and CRM never captured the number. It also removes our hand-written parsing code, which had been writing truncated phone numbers into the database — a data-integrity defect with direct CRM and lead-matching consequences. Alongside the fix we gain file names on attachments (operators were seeing getfile), video thumbnails/quality renditions, audio transcripts, and correct handling of suspended chats. There are no breaking API changes — all additions are optional trailing constructor parameters plus one enum value — and test coverage is essentially complete (99.8% of lines). Two things need explicit decisions from us rather than assumptions: whether unverified phone numbers may create leads, and who owns E.164 normalization. Note the release is staged but not yet tagged or published, so scheduling should follow the tag.

To engineering: New in v1.1.11, all additive in trailing constructor positions unless noted:

  • ContactAttachmentPayload::fromArray() now tolerates missing/null hash (?? ''); wrong type still throws InvalidResponseException. toArray() omits empty hash so round-trips don't emit hash: "". ContactVerifier::verify() with empty hash still returns false (fail-closed) — signature semantics unchanged; MaxContactService untouched.
  • Action required: ChatStatus::Suspended added. Audit every exhaustive match (ChatStatus) and add default. This is the only behavioral change in the release.
  • Attachment::$filename (new trailing optional ctor param): fromArray() reads top level first, then payload; toArray() writes top level, omits null. Wrong type throws. FileAttachmentPayload::$size added; legacy file_size retained.
  • Spec sync to max-openapi@9ef38a6 / official x-official-schema: v0.0.33: Subscription::$time; Callback::$timestamp/$user; Update::$user now also falls back to callback.user; VideoAttachmentPayload::$width/$height/$thumbnail and AudioAttachmentPayload::$transcription parsed from both top level and payload (top-level priority on read, written into payload); VideoUrls gains mp4_1080/720/480/360/240/144 and hls (legacy mp4/preview kept, removed in v2.0.0); FailedUserDetails parses both spec form {error_code, user_ids[]} and prod form {user_id, error} with (int $userId, string $error) ctor preserved and relaxed requiredness (0/'' on absence).
  • @deprecated removed from addChatMembers() / AddChatMembersResult — cancels the v1.1.6 deprecation list item. Don't schedule removal before v2.0.0.
  • Consumer pattern unchanged: $contact->vcfPhone ?? ContactPhoneExtractor::fromVcf((string) $contact->vcfInfo); inbound payloads omit vcf_phone. Extractor still logs nothing and throws nothing — vcf_info is PII; log in the caller.
  • Quality gate 2026-10-20: lint 0/112, PHPStan max 0 errors, 389 tests / 1007 assertions green, 99.82% line coverage (threshold 95%), composer audit 0 vulnerabilities. New regression tests in AttachmentTest, WebhookHandlerTest (full webhook request with hash-less contact decodes; toArray() emits no empty hash), DtoCoverageTest. Integration smoke group not run (no MAX_API_TOKEN) — cover with manual QA.
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.
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
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console