mirror of
https://github.com/opensourcepos/opensourcepos.git
synced 2026-09-13 13:57:34 -04:00
Add three missing plugin hook points for sale documents so plugins can
inject buttons into invoice, quote, and work order views alongside the
existing receipt hook. All four pass ['saleId' => $sale_id_num] and
follow the same naming pattern (view:sales_{type}_buttons).
Exempt plugins/*/webhook from CSRF filtering to support server-to-server
provider callbacks. Also convert the CSRF except list from a string to an
array — the previous 'login|migrate' string produced a single unanchored
pattern, making login/anything CSRF-exempt. Separate array entries anchor
each one individually. Plugin webhook handlers are responsible for their
own authentication.
Add WhatsApp Business Cloud API plugin (app/Plugins/WhatsAppPlugin/):
- Free-form messaging page registered as the 'whatsapp' office module
with its own permission, plus per-customer modal and thread view
- "Send via WhatsApp" button on all four sale document types via the new
hooks; renders only when the customer has a phone number
- PDF delivery using the same sales/{type}_email view core uses for email
- Inbound webhook at plugins/whatsapp/webhook authenticated by
X-Hub-Signature-256 HMAC; fails closed on missing/bad signature;
always returns 200 to suppress Meta retries
- Out-of-order status callbacks cannot downgrade sent → delivered → read
- Conversation log table via plugin migration; dropped on uninstall with
version reset so re-install recreates it cleanly
- Access token and app secret encrypted at rest in plugin_config; no
writes to app_config or initial_schema.sql
- utf8mb4_unicode_520_ci collation throughout (MySQL and MariaDB compat)
- Language file stubs for all existing locales; English strings complete
- README covering credentials, install, webhook setup, and uninstall
50 lines
1.5 KiB
PHP
50 lines
1.5 KiB
PHP
<?php
|
|
|
|
namespace App\Plugins\WhatsAppPlugin\Libraries;
|
|
|
|
/**
|
|
* One outbound WhatsApp message as it is recorded in the conversation log.
|
|
*
|
|
* The send methods build this up as the send progresses — a media id once the
|
|
* document is uploaded, a message id and status once Meta has answered — so the
|
|
* log write takes a single argument instead of a long positional parameter list.
|
|
*
|
|
* Status defaults to 'failed': every early return is a failure, and only a
|
|
* successful send has to say otherwise.
|
|
*/
|
|
class OutboundMessage
|
|
{
|
|
public ?string $mediaId = null;
|
|
public ?string $filename = null;
|
|
public ?string $waMessageId = null;
|
|
public string $status = 'failed';
|
|
public ?string $error = null;
|
|
|
|
public function __construct(
|
|
public string $phone,
|
|
public string $type,
|
|
public ?string $body = null,
|
|
public ?int $personId = null,
|
|
) {
|
|
}
|
|
|
|
/**
|
|
* @return array The row shape WhatsAppMessage::storeWhatsAppMessage() expects.
|
|
*/
|
|
public function toArray(): array
|
|
{
|
|
return [
|
|
'person_id' => $this->personId,
|
|
'phone' => $this->phone,
|
|
'direction' => 'out',
|
|
'type' => $this->type,
|
|
'body' => $this->body,
|
|
'media_id' => $this->mediaId,
|
|
'filename' => $this->filename,
|
|
'wa_message_id' => $this->waMessageId,
|
|
'status' => $this->status,
|
|
'error' => $this->error,
|
|
];
|
|
}
|
|
}
|