Ilustrasi ponsel Android mengirim notifikasi ke backend cloud

Notification Listener

Postingan ini membahas Notification Listener, aplikasi Android yang menangkap notifikasi sistem dan meneruskannya sebagai payload JSON ke endpoint HTTP. Anda akan mempelajari pengenalan fitur, cara deploy backend (Express lokal atau Cloudflare Workers), serta langkah cara menggunakan aplikasinya.

Daftar Isi

  1. Pengenalan Aplikasi
  2. Deploy Backend
    1. Express (Lokal/Server)
    2. Cloudflare Workers
    3. Setting Database D1
  3. Setup Aplikasi Android
  4. Cara Menggunakan
  5. Uji dan Verifikasi
  6. Tips Produksi

Pengenalan Aplikasi

Diagram arsitektur Android ke Workers, WordPress, dan D1
  • Tangkap Notifikasi: memantau notifikasi dari aplikasi yang dipilih atau semua aplikasi.
  • Forward ke Webhook: kirim JSON via POST ke endpoint /webhook.
  • Reliabilitas: antrean + retry saat offline menggunakan WorkManager.
  • Keamanan: dukungan header X-API-Key, penyimpanan terenkripsi untuk API key.
  • Deteksi Rupiah: field amountDetected untuk nominal yang terdeteksi.
  • Log: tampilan log ringkas di aplikasi untuk debug cepat.

Deploy Backend

A. Express (Lokal/Server Anda)

Backend bawaan berada di folder backend/. Cocok untuk pengujian lokal atau server sendiri.

Bash
cd backend
npm install

# Konfigurasi environment
cat > .env << 'EOF'
PORT=3000
API_KEY=your-secret-api-key
EOF

# Jalankan server
npm run dev   # mode development
# atau
npm start     # mode production

# Endpoint:
# http://localhost:3000/health
# http://localhost:3000/webhook

B. Cloudflare Workers (Tanpa Server)

Ilustrasi terminal untuk deploy Cloudflare Workers

Alternatif tanpa server dengan latensi rendah. Butuh akun Cloudflare dan Wrangler CLI (npm i -g wrangler).

1) Prasyarat

  • Akun Cloudflare aktif.
  • Node.js LTS terpasang.
  • Wrangler CLI: npm i -g wrangler kemudian wrangler login.

2) Siapkan Proyek Worker

Bash
# Inisialisasi proyek Worker (ES Modules)
mkdir notification-worker && cd notification-worker
wrangler init --yes --type=javascript
mkdir -p src && touch src/worker.js
Bash
export default {
  async fetch(request, env) {
    const url = new URL(request.url);
    const cors = {
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Headers": "Content-Type, X-API-Key",
      "Access-Control-Allow-Methods": "POST, OPTIONS"
    };
    if (request.method === "OPTIONS") return new Response(null, { headers: cors });

    if (request.method === "POST" && url.pathname === "/webhook") {
      const apiKey = request.headers.get("X-API-Key");
      if (!apiKey || apiKey !== env.API_KEY) {
        return new Response(JSON.stringify({ ok:false, error:"Unauthorized" }), { status:401, headers:{ "Content-Type":"application/json", ...cors }});
      }
      let body;
      try { body = await request.json(); }
      catch { return new Response(JSON.stringify({ ok:false, error:"Invalid JSON" }), { status:400, headers:{ "Content-Type":"application/json", ...cors }}); }

      const { deviceId, packageName, text, amountDetected } = body || {};
      if (!deviceId || !packageName || !text) {
        return new Response(JSON.stringify({ ok:false, error:"Missing fields" }), { status:422, headers:{ "Content-Type":"application/json", ...cors }});
      }

      console.log("Notif:", packageName, amountDetected);
      return new Response(JSON.stringify({ ok:true }), { status:200, headers:{ "Content-Type":"application/json", ...cors }});
    }

    if (url.pathname === "/") return new Response("Notification Worker OK", { headers: cors });
    return new Response("Not Found", { status:404, headers: cors });
  }
};

3) Konfigurasi wrangler.toml

Bash
name = "notification-listener-webhook"
main = "src/worker.js"
compatibility_date = "2024-12-01"
workers_dev = true

[vars]
# Tambahan variabel non-rahasia jika diperlukan

# (Opsional) Custom domain
# routes = [{ pattern = "webhook.domain-anda.com/*", custom_domain = true }]

# (Opsional) Binding D1/KV/Queues
# [[d1_databases]]
# binding = "DB"
# database_name = "notification-listener-db"
# database_id = "<id-d1-anda>"

# [[queues.producers]]
# binding = "NOTIF_QUEUE"
# queue = "notification-queue"

4) Set Secret & Deploy

Bash
# Set secret API_KEY yang akan dibaca di env.API_KEY
wrangler secret put API_KEY

# Deploy ke Cloudflare Workers
wrangler deploy

# Lihat URL hasil deploy (workers.dev)
# Contoh: https://notification-listener-webhook.<akun>.workers.dev/webhook

# Pantau log realtime
wrangler tail

5) Uji Endpoint

Bash
curl -X POST "https://notification-listener-webhook.<akun>.workers.dev/webhook" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-secret-api-key" \
  -d '{
    "deviceId":"550e8400-e29b-41d4-a716-446655440000",
    "packageName":"id.dana",
    "text":"Anda menerima Rp 100.000",
    "amountDetected":"100000"
  }'

Catatan produksi: batasi CORS ke domain Anda (ganti * dengan domain), gunakan custom domain + HTTPS bila perlu, dan pertimbangkan D1/KV/Queues untuk penyimpanan/antrian.

6) Setting Database D1 (Lengkap)

Opsional tetapi direkomendasikan jika ingin menyimpan histori notifikasi. Langkah-langkah berikut mencakup pembuatan database, binding di wrangler.toml, inisialisasi schema, verifikasi, dan tips pengembangan lokal.

A) Buat Database & Binding
Bash
# Login Cloudflare dan buat D1
wrangler login
wrangler d1 create notification-listener-db
# Salin database_id dari output perintah ini

Buka wrangler.toml dan tambahkan binding berikut menggunakan database_id milik Anda:

Bash
[[d1_databases]]
binding = "DB"
database_name = "notification-listener-db"
database_id = "<id-d1-anda>"
B) Inisialisasi Schema
Bash
-- schema.sql (minimal)
CREATE TABLE IF NOT EXISTS notifications (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  device_id TEXT NOT NULL,
  package_name TEXT NOT NULL,
  text TEXT,
  amount_detected TEXT,
  created_at TEXT DEFAULT (datetime('now'))
);

CREATE TABLE IF NOT EXISTS devices (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  device_id TEXT UNIQUE NOT NULL,
  last_seen TEXT DEFAULT (datetime('now'))
);
Bash
# Terapkan schema (pilih salah satu cara)
# 1) Menggunakan file
printf "%s" "CREATE TABLE IF NOT EXISTS notifications (id INTEGER PRIMARY KEY AUTOINCREMENT, device_id TEXT NOT NULL, package_name TEXT NOT NULL, text TEXT, amount_detected TEXT, created_at TEXT DEFAULT (datetime('now')));
CREATE TABLE IF NOT EXISTS devices (id INTEGER PRIMARY KEY AUTOINCREMENT, device_id TEXT UNIQUE NOT NULL, last_seen TEXT DEFAULT (datetime('now')));" > schema.sql
wrangler d1 execute notification-listener-db --file=schema.sql

# 2) Jalankan per perintah
wrangler d1 execute notification-listener-db --command="CREATE TABLE IF NOT EXISTS notifications (id INTEGER PRIMARY KEY AUTOINCREMENT, device_id TEXT NOT NULL, package_name TEXT NOT NULL, text TEXT, amount_detected TEXT, created_at TEXT DEFAULT (datetime('now')));"
wrangler d1 execute notification-listener-db --command="CREATE TABLE IF NOT EXISTS devices (id INTEGER PRIMARY KEY AUTOINCREMENT, device_id TEXT UNIQUE NOT NULL, last_seen TEXT DEFAULT (datetime('now')));"
C) Verifikasi & Query Contoh
Bash
# Lihat daftar tabel
wrangler d1 execute notification-listener-db --command="SELECT name FROM sqlite_master WHERE type='table' ORDER BY name;"

# Ambil 10 notif terakhir
wrangler d1 execute notification-listener-db --command="SELECT id, package_name, amount_detected, created_at FROM notifications ORDER BY id DESC LIMIT 10;"
D) Catatan Dev Lokal
  • Remote binding: gunakan wrangler dev --remote agar Worker lokal memakai D1 cloud Anda.
  • Migrasi: Anda juga dapat memakai wrangler d1 migrations untuk mengelola perubahan schema secara bertahap.

Setup Aplikasi Android

Ilustrasi izin akses notifikasi dan pengaturan endpoint di Android
  1. Build APK: ./gradlew assembleDebug lalu install: adb install app/build/outputs/apk/debug/app-debug.apk.
  2. Buka aplikasi, aktifkan Akses Notifikasi hingga status “Granted”.
  3. Isi Endpoint URL: http://<host>:3000/webhook (Express) atau https://<subdomain>.workers.dev/webhook (Workers).
  4. Opsional: isi API Key untuk dikirim sebagai header X-API-Key.
  5. Opsional: atur Filter Package (mis. id.dana, com.whatsapp) atau aktifkan “Forward semua aplikasi”.
  6. Simpan pengaturan dan kecualikan dari optimasi baterai agar layanan berjalan stabil.

Cara Menggunakan

  1. Pastikan backend aktif dan dapat diakses publik.
  2. Jalankan aplikasi dan gunakan fitur uji kirim atau tunggu notifikasi nyata.
  3. Periksa log di aplikasi untuk status terkini pengiriman.
  4. Validasi di backend apakah menerima 200 OK dan payload sesuai.

Uji dan Verifikasi

Bash
# Uji ke Express lokal
curl -X POST "http://localhost:3000/webhook" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-secret-api-key" \
  -d '{
    "deviceId":"550e8400-e29b-41d4-a716-446655440000",
    "packageName":"id.dana",
    "text":"Anda menerima Rp 100.000",
    "amountDetected":"100000"
  }'

# Uji ke Cloudflare Workers
curl -X POST "https://notification-listener-webhook.<akun>.workers.dev/webhook" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-secret-api-key" \
  -d '{
    "deviceId":"550e8400-e29b-41d4-a716-446655440000",
    "packageName":"id.dana",
    "text":"Anda menerima Rp 100.000",
    "amountDetected":"100000"
  }'

Tips Produksi

  • CORS: batasi Access-Control-Allow-Origin ke domain Anda.
  • Custom Domain: gunakan HTTPS di server sendiri atau routes untuk Workers.
  • Reliabilitas: pantau log backend, gunakan antrian/penyimpanan sesuai kebutuhan.
  • Performa Perangkat: kecualikan dari optimasi baterai agar layanan foreground stabil.

Repository: github.com/Wimboro/NotificationListener

By admin

Tinggalkan Balasan

Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai *