From a61a81acd670797794261cb58aaf88f7ab946c91 Mon Sep 17 00:00:00 2001 From: Aleksandr Soloshenko Date: Wed, 14 May 2025 07:00:09 +0700 Subject: [PATCH] [features] add webhooks UI docs entry --- docs/assets/webhooks-list.png | Bin 0 -> 6325 bytes docs/features/webhooks.md | 95 ++++++++++++++++++++-------------- 2 files changed, 57 insertions(+), 38 deletions(-) create mode 100644 docs/assets/webhooks-list.png diff --git a/docs/assets/webhooks-list.png b/docs/assets/webhooks-list.png new file mode 100644 index 0000000000000000000000000000000000000000..b00de13f7d9c180bf86ac4b1b9de6a8715b956e8 GIT binary patch literal 6325 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 literal 0 HcmV?d00001 diff --git a/docs/features/webhooks.md b/docs/features/webhooks.md index 5270705..a2857bd 100644 --- a/docs/features/webhooks.md +++ b/docs/features/webhooks.md @@ -4,32 +4,38 @@ Webhooks offer a powerful mechanism to receive real-time notifications of events ## Supported Events 📩 -Currently, the following events are supported: - -- `sms:received` - 📨 Triggered when an SMS is received by the device. The payload for this event includes: - * `messageId`: The ID of the SMS message. **Note**: This ID is generated based on the message content and is not guaranteed to be unique. Do not rely on it as a unique identifier. - * `message`: The content of the SMS message. - * `phoneNumber`: The phone number that sent the SMS. - * `simNumber`: The SIM card number that received the SMS. **May be `null`** on some Android devices. - * `receivedAt`: The timestamp (in the device’s local timezone) when the message was received. -- `sms:sent` - ✉️ Triggered when an SMS is sent by the device. The payload includes: - * `messageId`: The ID of the SMS message. - * `phoneNumber`: The recipient's phone number. - * `simNumber`: The SIM card number that sent the SMS. **May be `null`** if the default SIM is used. - * `sentAt`: The timestamp (device’s local timezone) when the message was sent. -- `sms:delivered` - ✅ Triggered when an SMS is delivered to the recipient. The payload includes: - * `messageId`: The ID of the SMS message. - * `phoneNumber`: The recipient's phone number. - * `simNumber`: The SIM card number that sent the SMS. **May be `null`** if the default SIM is used. - * `deliveredAt`: The timestamp (device’s local timezone) when the message was delivered. -- `sms:failed` - ❌ Triggered when an SMS fails to send or is not delivered. The payload includes: - * `messageId`: The ID of the SMS message. - * `phoneNumber`: The recipient's phone number. - * `simNumber`: The SIM card number that sent the SMS. **May be `null`** if the default SIM is used. - * `failedAt`: The timestamp (device’s local timezone) when the failure occurred. - * `reason`: The failure reason. -- `system:ping` - 🏓 Triggered when the device pings the server. The payload includes: - * `health`: The healthcheck response, as described in the [Healthcheck documentation](./health.md). +
+ +- :incoming_envelope: **sms:received** + - `messageId`: Content-based ID + - `message`: SMS content + - `phoneNumber`: Sender's number + - `simNumber`: SIM index (nullable) + - `receivedAt`: Local timestamp + +- :outbox_tray: **sms:sent** + - `messageId`: Unique ID + - `phoneNumber`: Recipient + - `simNumber`: SIM index (nullable) + - `sentAt`: Local timestamp + +- :white_check_mark: **sms:delivered** + - `messageId`: Unique ID + - `phoneNumber`: Recipient + - `simNumber`: SIM index (nullable) + - `deliveredAt`: Local timestamp + +- :x: **sms:failed** + - `messageId`: Unique ID + - `phoneNumber`: Recipient + - `simNumber`: SIM index (nullable) + - `reason`: Error details + - `failedAt`: Local timestamp + +- :ping_pong: **system:ping** + - `health`: [Healthcheck status](./health.md) + +
## Prerequisites ✅ @@ -64,6 +70,7 @@ curl -X POST -u : \ ``` Replace: + - `:`: Credentials from the Home tab of the app. - `https://your-server.com/webhook`: The URL of your webhook endpoint. - `https://api.sms-gate.app/3rdparty/v1/webhooks`: The appropriate URL for your mode. @@ -75,14 +82,31 @@ In Cloud and Private modes, please allow some time for the webhooks list to sync ### Step 3: Verify Your Webhook ✔️ -You can verify that it has been successfully registered by executing the following `curl` command: +=== "Via API Method :material-api:" -```sh title="Cloud mode example" -curl -X GET -u : \ - https://api.sms-gate.app/3rdparty/v1/webhooks -``` + You can verify that it has been successfully registered by executing the following `curl` command: + + ```sh title="Cloud mode example" + curl -X GET -u : \ + https://api.sms-gate.app/3rdparty/v1/webhooks + ``` -**Local mode** and **Cloud/Private mode** maintain separate webhook lists. Use the corresponding API URL to view registrations. + !!! note "Separate Lists" + **Local mode** and **Cloud/Private mode** maintain separate webhook lists. Use the corresponding API URL to view registrations. + +=== "Via App Interface :material-cellphone:" + + 1. Open the SMS Gateway app 📱 + 2. Navigate to **Settings** > **Webhooks** > **Registered webhooks** + 3. The list shows all configured webhooks with: + - Endpoint URL + - Webhook ID + - Event type + - Source (Local/Cloud) +
+ ![Webhooks List](../assets/webhooks-list.png) +
+ You can copy the webhook ID by clicking on the row. ### Step 4: Test the Webhook 🧪 @@ -128,6 +152,7 @@ curl -X DELETE -u : \ ## Security Considerations 🔐 +- **Review Registered Webhooks Periodically**: Regularly audit your webhooks to verify URLs are valid and guard against unauthorized or stale endpoints. - **Use HTTPS**: Encrypts data in transit. - **Secure Your Endpoint**: Protect your webhook endpoint against unauthorized access. For example, you can specify authorization key as query-parameter when registering the webhook. - **Rotate Credentials**: Regularly update passwords. @@ -234,12 +259,6 @@ The signing key is randomly generated at first request and can be changed in **S - Ensure timestamp is UTC Unix time in seconds - Use raw body before JSON decoding -## Conclusion 🎉 - -By following these steps, you've successfully integrated webhooks into your system to receive real-time notifications for incoming SMS messages. This setup enables you to respond to messages promptly and automate workflows based on SMS content. - -Remember to adhere to best practices for security and perform thorough testing to ensure reliable webhook delivery. - ## References 📚 - [FAQ](../faq/webhooks.md)