Message487 connects selected Android notifications and incoming SMS to your n8n workflows. A custom webhook is also supported. Telegram forwarding is one possible workflow; the Android app does not depend on Telegram.
Status: development preview with notification/SMS capture, a persistent private outbox, background delivery, automatic retries and a delivery journal. Webhook requests require a Bearer token, stored encrypted on the device. Signed APK release automation is configured; see Releases and release automation, and release testing.
Choose an English guide or инструкцию на русском. Every workflow is self-contained, inactive on import and contains placeholders rather than personal data.
| Level | Importable workflow |
|---|---|
| Text webhook, no Telegram | 01 · Webhook text |
| Text + images webhook, no Telegram | 02 · Webhook images |
| Telegram text | 03 · Telegram text |
| Telegram images, built-in nodes | 04 · Telegram images standard |
| Telegram Rich Messages, all media + retry progress | 05 · Telegram advanced |
Level 5 uses the MIT-licensed N8nTelegramNode487 and a Data Table; it includes an optional sent-key cleanup workflow. Levels 1–4 require only built-in n8n nodes. Import instructions include synthetic payloads and setup steps.
Download the latest signed APK
Message487 is also available from F-Droid. Open App updates using the update icon in the top bar. The source follows the installer: F-Droid clients use F-Droid, other named installers use GitHub. Unknown installers require a manual choice. Daily checks can be disabled; downloads and installation require separate actions.
The stable link follows the latest published release; it does not point to development builds. Read the release notes for supported features. Release 0.0.1 predates Bearer authentication.
Guides: Install from APK · n8n Cloud · Self-hosted n8n · Telegram forwarding. На русском: Установка из APK · n8n Cloud · Свой сервер n8n · Пересылка в Telegram.
- Save the full published webhook URL, a Bearer token and a device code in Connection. Send a test event.
- Check Journal and find the same event ID in n8n Executions.
- In Sources, enable notification forwarding, grant notification access in Android settings, and select applications. Add a package manually if it has no launcher icon. Select all applications selects the entire available list, regardless of the search filter; manually added selections are preserved. Newly installed apps must be selected separately unless you enable Automatically select new apps (off by default). It selects newly detected launcher apps when you open or return to Message487, preserving existing choices and manual exclusions. Apps without a launcher icon still require manual selection.
- Enable SMS forwarding separately and grant SMS permission. Only new incoming SMS are read; existing history is not imported. Multipart SMS are combined into one event.
Both capture sources are off by default, and no applications are selected. Message487 excludes its own notifications, ongoing notifications and group summaries. An unchanged update of the same notification is suppressed; changed content creates another event. Existing notifications are not replayed when access is enabled. Avoid selecting applications that receive the forwarded messages, or the workflow can create a feedback loop. Selecting your SMS app as a notification source may forward the same message as both SMS and a notification.
Pause forwarding stops capture and queued delivery. A request already running may finish. Events arriving while capture is disabled or paused are not saved for later. Background delivery uses Android WorkManager: Doze, battery restrictions and network availability can delay it. After a force-stop, open the app again. Android may hide sensitive notification content; Message487 forwards only the content the system exposes.
Skip duplicate SMS and Skip duplicate notifications in Sources are independently
enabled by default and share the time window. SMS and notifications are
compared by source package, exact text (including whitespace) and an order-independent SHA-256
checksum of the image collection (including image roles and repeated entries), with original timestamps
inside the configured ± time window. Set the window in seconds in Sources; 0 requires exact timestamps.
Titles and SMS senders are not part of this key. SMS uses the system source android.
Messages outside the inclusive window count as new. Identical genuine messages inside it are also skipped. Turn the corresponding switch off
to forward repeated captures. Manual connection tests are exempt; network retries keep their event ID.
Deduplication hashes and original timestamps survive restarts, delivery and journal deletion until app data is cleared.
They are recorded even while the corresponding switch is off so re-enabling it covers those captures too.
Existing queued events are preserved on upgrade. Older exact-timestamp hashes still suppress exact matches;
time-window matching applies to captures recorded by the new filter.
The n8n confirmation mode requires JSON with status: "accepted" and the matching event_id.
This is our fixture contract, not a built-in n8n response. Turn off n8n confirmation for a
custom webhook that acknowledges with HTTP 2xx. Neither response proves delivery to a downstream
service such as Telegram.
Events are saved locally before transmission. Retries preserve the event ID and body. Timeouts,
connection failures and transient HTTP errors retry with backoff; other HTTP failures and invalid
confirmations need a manual retry from Journal after fixing the server. A lost response can
cause duplicate delivery: downstream workflows should deduplicate using event_id.
Queued events retain the URL, token and confirmation mode from capture time. Changing the connection does not reroute them. Undelivered events remain until confirmed or explicitly deleted. The journal persists across restarts and hides message contents. Tap an event for its ID, HTTP result, retry and deletion controls. Confirmed payloads are removed; only a bounded recent history of delivery metadata remains. See PRIVACY.md.
The JSON event carries schema_version, event_id, device_id, device_code, message_type,
occurred_at, source, source_name and text. Notifications also carry title; SMS carry
sender. device_id is a random installation identity; device_code is your editable label.
source is the originating package, with SMS using android for the system SMS broadcast.
source_name is its PackageManager display label, falling back to the package when unavailable.
Labels can change with language or app version; use source for matching rules.
Notification image attachments are forwarded as an optional images array in the same JSON
(schema_version: 1). Each image has mime_type (image/jpeg or image/png), width, height,
kind (attachment, avatar, or app_icon), and data_base64 (standard Base64 without a data-URL prefix). presentation (big_picture, gallery, or file) preserves the notification image presentation. Text-only events omit images.
Choose JPEG or PNG in Sources → Graphics; defaults are JPEG and quality 80%.
JPEG quality is adjustable from 0 to 100; PNG ignores that setting and preserves transparency.
Transparent areas become white in JPEG. Settings changes apply only to new captures; queued
images retain their original bytes across retries. The overview test button sends text only. Connection → Test message independently selects
Big Picture, a two-image gallery, avatar and app icon. These test-only selections do not change
notification capture settings; image format, quality and limits still apply. Avatar and app-icon
test images use the Message487 logo.
The app reads BigPicture content and image attachments in MessagingStyle. Avatars and app
icons have independent switches in Sources, both off by default. When enabled, one latest
available sender avatar (falling back to the notification large icon) and one source app icon
are included, using the same format and quality. Image-only notifications can be forwarded.
In Sources → Graphics, configure the attachment count, maximum side length, per-image size,
and combined size before Base64. Defaults are 3 attachments, 1024 pixels, 256 KiB per image,
and 512 KiB combined. The count excludes the optional avatar and app icon; all images share
the size budget. Attachments prioritize the big picture and then the latest messaging images,
with a stable content-hash tie-breaker. Duplicates within a role are removed before applying limits.
Turn off Limit images to send all available attachments without output size limits or
resizing. Saved limits are retained for re-enabling. Format conversion and JPEG quality still apply.
Input decoding safeguards remain in both modes: content URI input is at most 8 MiB and decoded
bitmaps at most 16 megapixels, with a lower working-memory ceiling on smaller heaps.
EXIF rotations and mirrors are applied before encoding. URI inputs must be readable content:// URIs;
remote URLs and private file paths are not fetched. Unreadable/invalid images are skipped and
reported as capture errors; available text and other readable images still proceed.
Images are private files under noBackupFilesDir, without additional app-level encryption.
The request description, text and token are AES-GCM encrypted in a separate file; SQLite holds
queue metadata and a file reference. Base64 JSON is streamed over HTTP using chunked transfer
for image-bearing events, so proxies must accept chunked request bodies. Retries keep the same
files and bytes. Successful delivery or deletion removes the files; recovery cleans abandoned
temporary files. Older database payloads migrate on their next attempt.
Image capture has its own bounded queue and a 10-second deadline; queued tasks retain only
notification metadata and fetch the current notification when processing starts. Superseded,
expired or overflowed image jobs still forward available text. SMS uses a separate executor.
The existing JSON webhook accepts the added field; downstream workflows must explicitly
convert/process images to display or forward photos. Use the importable example levels
for webhook binary files, standard Telegram images or Rich Messages with all attachments.
The manifest declares launcher-app visibility rather than QUERY_ALL_PACKAGES. The app requests
notification listener access and RECEIVE_SMS only for the features you enable. It does not request
SMS history access or become the default SMS app.
Start the development server, which provisions n8n and published test workflows:
docker compose -f DevServer/compose.yaml up -d --wait
bundle exec fastlane android server_testsBuild with JDK 21, Ruby/Bundler and the Android SDK; the emulator launcher also uses Python 3.
Use ANDROID_HOME or an untracked
local.properties file to point Gradle to your SDK. SDK and library versions are in the Gradle
build files; Ruby dependencies are pinned by Gemfile.lock.
bundle install
bundle exec fastlane android checks
scripts/run-without-debugging.shThe run script starts the development emulator if necessary, waits for Android, builds and installs
the debug APK, then launches the app without waiting for a debugger. Existing app data is preserved.
In VS Code, select Run Message487 on Emulator and Run Without Debugging, or run the task
Android: Run on emulator. To start only the emulator, use scripts/emulator.sh.
The debug app starts with the local n8n receive endpoint configured. Follow the capture checks in DevServer/README.md using synthetic data only. Release builds require HTTPS. UI strings are supplied in English and Russian. The interface supports light/dark themes, bottom navigation on phones and rail navigation on wider windows. See the design notes for the visual conventions and references.
Fastlane's debug_artifact lane builds only the debug APK. checks runs JVM/Robolectric tests,
debug/release lint, and builds debug and unsigned release APKs under app/build/outputs/apk/.
PR CI has no release signing credentials. It runs JVM/lint checks and instrumentation tests on disposable API 26 and API 35 emulators. JUnit results appear in GitHub Checks; debug and unsigned release APK links are kept in the PR description. See testing. For signed APK releases, see Releases and release automation, and release testing. Store graphics and their provenance are documented in Branding.
See the project context for remaining product decisions. This project succeeds sms487. AndroidMegaProxy is the reference for project conventions.
Licensed under the MIT License.
Open the bug icon in the top bar to view or clear local diagnostic logs and prepare an email to
der-morgenstern@yandex.ru. A ZIP contains rotating logs, the last crash and device/app information;
message content and connection secrets are excluded. Sending requires action in your email app.
After an unhandled crash the next launch offers to review the report.
See diagnostic behavior and development checks and privacy details.
Test categories, local commands, CI jobs and device-only limitations: Testing.