Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ The stable link follows the latest published release; it does not point to devel
Read the [release notes](https://github.com/andre487/AndroidMessage487/releases/latest) for supported features.
Release 0.0.1 predates Bearer authentication.

Guides: [Install from APK](docs/en/apk-installation.md) · [n8n webhook](docs/en/n8n-webhook.md) · [Telegram forwarding](docs/en/n8n-telegram.md).
На русском: [Установка из APK](docs/ru/apk-installation.md) · [n8n webhook](docs/ru/n8n-webhook.md) · [Пересылка в Telegram](docs/ru/n8n-telegram.md).
Guides: [Install from APK](docs/en/apk-installation.md) · [n8n Cloud](docs/en/n8n-cloud.md) · [Self-hosted n8n](docs/en/n8n-self-hosted.md) · [Telegram forwarding](docs/en/n8n-telegram.md).
На русском: [Установка из APK](docs/ru/apk-installation.md) · [n8n Cloud](docs/ru/n8n-cloud.md) · [Свой сервер n8n](docs/ru/n8n-self-hosted.md) · [Пересылка в Telegram](docs/ru/n8n-telegram.md).

1. Save the full published webhook URL, a Bearer token and a device code in **Connection**. Send a test event.
2. Check **Journal** and find the same event ID in n8n **Executions**.
Expand Down
143 changes: 143 additions & 0 deletions docs/en/n8n-cloud.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# Connect Message487 to n8n Cloud

[English](../en/n8n-cloud.md) | [Русский](../ru/n8n-cloud.md)

You need a browser, an n8n Cloud account and a phone with [Message487 installed](apk-installation.md).
Every step uses the interface: no server installation, terminal or coding is required.
It is easiest to open n8n on a computer and the app on your phone.

At the end, a test message from the app will appear in n8n's history. You can add
Telegram forwarding after checking the connection.

## 1. Open your n8n

Sign up for [n8n Cloud](https://docs.n8n.io/deploy/use-n8n-cloud/start-your-free-trial)
and open your instance's editor. If you already have an account, sign in.
Cloud provides an HTTPS address. Check [n8n pricing](https://n8n.io/pricing/)
for current trial conditions, prices and execution limits.

In n8n, an automation is called a **workflow** and its individual steps are called
**nodes**. We will import a ready-made workflow with two nodes.

## 2. Import the ready-made workflow

1. Use **Create Workflow** to create a new, empty workflow.
2. Open **⋯ → Import from URL** in the editor's upper-right corner.
3. Paste this address and confirm the import:

```text
https://raw.githubusercontent.com/andre487/AndroidMessage487/main/DevServer/workflows/receive.json
```

4. You should see two connected nodes: **Webhook → Respond**. The first receives
the message; the second confirms receipt to the phone.
5. Name the workflow, for example `Message487 — my phone`.

If URL import is unavailable, open the [workflow file](../../DevServer/workflows/receive.json)
on GitHub, download it using **Download raw file**, then select
**⋯ → Import from File** in n8n. You do not need to edit the file contents.
[Official import guide](https://docs.n8n.io/build/manage-workflows/export-and-import).

A warning about unconfigured credentials after import is expected: you will set
up your own secret next. The **Respond** node is already configured; leave it as it is.

## 3. Set a secret for your phone connection

The token is a separate secret password connecting the app to this workflow.
It is neither your n8n account password nor a Telegram bot token.

1. Open the password generator in your password manager. Generate at least 32
random letters and digits with no spaces. Save it as `Message487 webhook`
so you can copy it to your phone later.
2. Double-click **Webhook** and make sure **Authentication** is **Header Auth**.
3. Under **Credential for Header Auth**, select **Create new credential**.
Give the new record a recognizable name, such as `Message487 phone`.
Inside that record, fill in these two fields:

| n8n field | What to enter |
| --- | --- |
| **Name** | `Authorization` |
| **Value** | The word `Bearer`, one ordinary space, then your generated token |

4. Click **Save** and make sure the new credential is selected in Webhook.
5. Keep the imported Webhook settings: **HTTP Method → POST** and
**Respond → Using 'Respond to Webhook' Node**. If another published workflow
already uses the same **Path**, give this one a different path, such as `message487/second-phone`.

Spell it **`Bearer`**, not `Bearier`. Do not add quotes or angle brackets.
n8n needs the `Bearer ` prefix; the app's token field **does not**: the app adds it
for you. Do not select the public test credential `Message487 local webhook`.
[Official Header Auth guide](https://docs.n8n.io/integrations/builtin/credentials/webhook/).

## 4. Publish and copy the address

1. Return to the workflow canvas and click **Publish**. Confirm publication if prompted.
Older n8n versions use an **Active** switch instead.
2. Open **Webhook** again, select **Production URL** and copy the complete address.
3. Transfer that address to your phone, for example using a synced note.

Copy the address from the Webhook node, not the browser's address bar.
You do not need **Test URL** or **Listen for test event** for this setup.
Publish again after editing nodes.
[Official webhook URL guide](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.webhook/).

## 5. Connect the app and send a test

Open the **Connection** tab at the bottom of Message487 and fill in:

| App field | What to enter |
| --- | --- |
| **Webhook URL** | The complete **Production URL** copied from n8n |
| **Webhook token** | Your generated token **without `Bearer `** |
| **Device code** | A recognizable phone name, such as `my-phone` |
| **n8n confirmation** | Leave enabled |

Tap **Save and send test event**. Open **Journal**, then the new test event: success means
**Accepted by webhook** and **HTTP 200**. This test does not yet require notification
access or SMS permission.

## 6. Find the message in n8n

1. In your browser, open the workflow's **Executions** tab: this is its run history.
2. Select the latest execution after tapping the test button.
3. Select **Webhook**, open **Output** on the right, switch to **JSON** if needed,
then expand **body**. It contains the message text (`text`) and phone name
(`device_code`). Its `event_id` matches the event ID in the app journal.

The imported workflow already saves successful executions. If history is empty,
open **⋯ → Settings** and check **Save successful production executions**:
saving must be enabled. Then send a **new** test from the phone.
[Official workflow settings](https://docs.n8n.io/build/manage-workflows/configure-workflow-settings).

Message contents and headers containing the token may be stored in Cloud history.
Consider this when selecting apps to forward and granting access to your n8n.

## 7. Enable your sources

Open **Sources** in the app. For notifications, grant Android notification access
and select apps; for SMS, enable SMS capture and grant its permission.
Test with a new notification or SMS: old messages from your phone's history are not
forwarded retroactively. Selecting both SMS capture and your SMS app's notifications
can deliver the same SMS twice.

The ready-made workflow currently only receives messages and acknowledges them to
the phone. Continue with [Telegram forwarding](n8n-telegram.md) to send them to a chat.
“Accepted by webhook” alone does not confirm Telegram delivery.

## Troubleshooting

| What you see | What to do |
| --- | --- |
| **401/403** in the journal | Check `Authorization`, the spelling of `Bearer`, and one space before the token in n8n. The app needs the same token without the prefix. Make sure Webhook uses your new credential. |
| **404** | Publish the workflow and copy **Production URL** again. Do not use the editor page address or **Test URL**. |
| **HTTP 200** but invalid confirmation | Check the **Webhook → Respond** connection and Webhook response mode from step 3. Keep the imported Respond settings. |
| No message visible in the editor | Open **Executions**, not just the workflow canvas; check history settings in step 6. |
| Network error or waiting | Check the phone's internet access and your n8n Cloud availability. Ensure the instance is running and its plan limit has not been exhausted. |
| Tests arrive but notifications do not | Check **Sources**, selected apps, Android permissions and the forwarding pause state. Then create a new notification. |

After fixing the address or token, tap **Save and send test event** again. Existing events
keep their original connection settings; retrying them does not test the new address
or token. You can delete unwanted old records from the journal.

The app's [diagnostic log](diagnostics.md) can help with further troubleshooting.
See the [technical guide](n8n-self-hosted.md) for message formats and acknowledgement details.
209 changes: 209 additions & 0 deletions docs/en/n8n-self-hosted.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
# Connect Message487 to self-hosted n8n

[English](../en/n8n-self-hosted.md) | [Русский](../ru/n8n-self-hosted.md)

Installing on a phone? See [APK installation and Android restrictions](apk-installation.md).

This guide targets Message487 0.0.2 and later, with Bearer authentication. You need the n8n editor and an HTTPS endpoint
reachable from your phone. For a local Android emulator, use the debug build and
[DevServer](../../DevServer/README.md). Release APKs reject HTTP endpoints.

## Prepare your server

For the managed service, use the [n8n Cloud guide](n8n-cloud.md).
This guide is for the owner or administrator of a self-hosted n8n server.

Follow the official [Docker Compose guide](https://docs.n8n.io/deploy/host-n8n/install-options/install-using-docker-compose)
or choose another [installation option](https://docs.n8n.io/deploy/host-n8n/install-options).
Configure persistent storage, backups and a public HTTPS endpoint with a trusted
certificate. It must be reachable from your phone, including over mobile data if
forwarding should work outside your home network.

If someone else manages the server, ask them for editor access and the external
n8n address. The editor password and webhook token are separate settings.
[DevServer](../../DevServer/README.md) is for local development; do not expose it
publicly with its bundled test credentials.

## 1. Create a receiving workflow

Import [receive.json](../../DevServer/workflows/receive.json) using **Import from File**
in the editor menu. It validates basic fields and acknowledges the incoming `event_id`.
Import a separate workflow rather than replacing an existing production workflow.

```mermaid
flowchart LR
W[Webhook: POST] --> R[Respond to Webhook: JSON ACK]
```

To configure the same two nodes manually, set **Webhook** as follows:

| Field | Value |
| --- | --- |
| HTTP Method | `POST` |
| Path | A unique path such as `message487/receive-<random-string>` |
| Authentication | `Header Auth` |
| Respond | `Using 'Respond to Webhook' Node` |

Create a **Header Auth** credential: **Name** = `Authorization`, **Value** = `Bearer <token>`.
Generate a private token with `openssl rand -hex 32` and replace `<token>`. Select this
credential in Webhook, including after importing the fixture; do not use the bundled public
DevServer credential in production. The editor login is separate from webhook authentication.
See [official webhook credentials](https://docs.n8n.io/integrations/builtin/credentials/webhook/).

Set **Respond to Webhook → Respond With → JSON**, **Response Code → 200**, and use
this **Expression** in **Response Body**:

```javascript
{{ { status: 'accepted', event_id: $('Webhook').first().json.body.event_id } }}
```

`Webhook` is the trigger node's name; adjust the expression if you rename it.
This minimal manual example does not validate requests. The imported `receive.json`
also validates `schema_version`, `event_id`, `message_type` and `text`, returning
HTTP 400 for invalid input.

The client expects an object, not an array, JSON-encoded string or HTML:

```json
{"status":"accepted","event_id":"the-same-event_id-as-the-request"}
```

The status must be exactly `accepted` and the ID must match. The default n8n response
“Workflow got started” is not an ACK for this client. See the official
[Webhook](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.webhook/) and
[Respond to Webhook](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.respondtowebhook/) documentation.

## 2. Publish and copy the URL

Select **Publish** (or enable **Active** in older n8n versions), then copy the
Webhook node's **Production URL**, for example:

```text
https://n8n.example.org/webhook/message487/receive-<random-string>
```

The `/webhook-test/` **Test URL** is for temporary listening with **Listen for test event**.
Production requests use a published workflow and appear under **Executions**.
Publish again after editing the workflow.

If a reverse proxy causes n8n to display an internal URL, configure `WEBHOOK_URL`,
`N8N_PROXY_HOPS` and forwarded headers using the official
[reverse-proxy guide](https://docs.n8n.io/deploy/host-n8n/configure-n8n/basic-configuration/configuration-examples/configure-webhook-urls-with-reverse-proxy).
Use the final HTTPS URL with a trusted certificate: Message487 does not follow
HTTP redirects or disable TLS verification.

## 3. Configure the app

1. Open **Connection** and paste the complete Production URL.
2. Enter the same token in **Webhook token**, without `Bearer `.
3. Set a recognizable **Device code**, such as `personal-phone`.
4. Keep **n8n confirmation** enabled.
5. Save and send a test event.
6. Open the event in **Journal** and check its acknowledgement and HTTP 200.

After the test succeeds, enable your desired **Sources**. Notifications require
Android notification access and selected apps; SMS requires receive-SMS permission.
Enabling SMS and selecting your SMS app can produce two events for one message.

The bundled emulator endpoint is `http://10.0.2.2:5678/webhook/message487/receive`,
which requires a debug build. On a physical phone, `localhost` means the phone
itself, and `10.0.2.2` is not your computer's address.

## 4. Inspect received data

Open **Executions → execution → Webhook → Output → body** in n8n. Match its
`event_id` with the app journal. Enable saving successful execution data if needed;
DevServer already does this. Execution history contains complete messages, so
configure access and retention accordingly. Request headers may contain the token too.

Example notification body:

```json
{
"schema_version": 1,
"event_id": "5d8ee1a5-9360-4b0e-8412-942b2e1c99ab",
"device_id": "43b55766-95b6-40b8-8f4f-c0240f547914",
"device_code": "personal-phone",
"message_type": "notification",
"occurred_at": "2026-09-09T09:00:00Z",
"source": "org.example.chat",
"source_name": "Example Chat",
"title": "Test notification",
"text": "Connection check"
}
```

| Field | Meaning |
| --- | --- |
| `event_id` | Event ID, preserved across delivery retries |
| `device_id` | Installation ID |
| `device_code` | Editable device label |
| `message_type` | `test`, `notification` or `sms` |
| `occurred_at` | Event timestamp in ISO 8601 format |
| `source` / `source_name` | Source package / app name; SMS uses source `android` |
| `title` | Notification title; absent for SMS and tests |
| `sender` | SMS sender; absent for notifications and tests |
| `text` | Event text |

Directly after Webhook use `{{ $json.body.text }}` or `{{ $json.body.device_code }}`.
If intermediate nodes replace the data, reference the original node explicitly:
`{{ $('Webhook').first().json.body.text }}`.

## 5. Add message processing

For a complete example, see [forwarding to Telegram](n8n-telegram.md).

The bundled receiver only acknowledges requests; it does not send to Telegram,
store a separate durable queue or deduplicate. Put your actions before Respond to
Webhook, acknowledging only after the operation you consider acceptance succeeds.
For slow processing, persist the event to a durable queue/database first, ACK it,
and perform downstream work separately.

The client uses 10-second connection and read timeouts. A lost response can cause
an already processed request to be retried. Use `event_id` as a unique storage key;
already accepted duplicates must receive the same successful ACK. A separate
“check then insert” without a unique constraint does not prevent concurrent duplicates.

Acknowledging before processing removes the event body from the client's queue
once confirmed. A later n8n failure will not trigger a phone retry. Successful
n8n execution and successful client acknowledgement are different outcomes.

## Test without a phone

Use your actual Production URL and a new ID for each test. This request contains
synthetic data only:

Set `WEBHOOK_TOKEN` in your shell to the same private token before running the command.

```sh
curl --fail-with-body --max-time 10 \
-X POST 'https://n8n.example.org/webhook/message487/YOUR-PATH' \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer ${WEBHOOK_TOKEN:?Set WEBHOOK_TOKEN}" \
--data '{"schema_version":1,"event_id":"manual-check-001","device_id":"manual-test","device_code":"test-phone","message_type":"test","occurred_at":"2026-09-09T09:00:00Z","source":"life.andre.message487","source_name":"Message487","text":"Synthetic connection test"}'
```

Expect HTTP 200 and `{"status":"accepted","event_id":"manual-check-001"}`.
This checks the server contract; also test the Android connection button and a new
notification or SMS to exercise actual app delivery.

## Troubleshooting

| Symptom | Check |
| --- | --- |
| HTTP 404 | Production URL, publication, POST method and path |
| HTTP 401/403 | Authentication and proxy/n8n access restrictions |
| HTTP 301/302 | Supply the final URL; redirects are not followed |
| `INVALID_ACK` with HTTP 200 | JSON object, `status: accepted`, matching ID and Webhook response mode |
| Timeout/network error | Phone connectivity, TLS, firewall and time until response |
| No execution in the editor | Executions tab and successful execution retention |
| Tests arrive, messages do not | Sources, Android permissions, selected apps and pause state |

Network failures, timeouts, HTTP 408/425/429 and 5xx retry automatically. Invalid ACKs
and other HTTP errors require intervention and manual retry from the journal.
Changing the URL or token only affects new events; queued events retain both original values.
Old queued events created without authentication are blocked and cannot be sent anonymously.
After upgrading from 0.0.1, enter the token and send a new test; delete obsolete blocked events.
Send a new test after fixing configuration and delete old records separately if needed.
The top-bar bug icon opens [diagnostics](diagnostics.md), which records delivery
outcomes without message text.
4 changes: 2 additions & 2 deletions docs/en/n8n-telegram.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

[English](../en/n8n-telegram.md) | [Русский](../ru/n8n-telegram.md)

First configure the [n8n webhook](n8n-webhook.md) and confirm a test event. That guide
also links to official documentation, n8n Cloud and self-hosted installation options.
First follow the [n8n Cloud](n8n-cloud.md) or [self-hosted n8n](n8n-self-hosted.md)
guide and confirm a test event. The following steps are the same for both setups.
Keep the bot token in **n8n Credentials**; it is not needed in Android. Forwarded
messages are available to the selected Telegram chat and may remain in n8n history.

Expand Down
Loading
Loading