---
title: "Notifikasi Telepon Alarm CloudWatch Tanpa Lambda/Twilio"
description: "SNS tidak bisa menelepon, dan payload-nya sulit diurai. Alirkan alarm CloudWatch lewat EventBridge ke webhook panggilan: setup, filter, jebakan."
date: 2026-10-16
author: Nooc
authorAvatarLink: /images/avatars/nooc.webp
authorLink: https://nooc.me
tags:
  - AWS
  - CloudWatch
  - EventBridge
  - notifikasi telepon
  - webhook
  - on-call
---

# Notifikasi telepon alarm CloudWatch: dari EventBridge ke ponsel Anda, tanpa Lambda

Alarm CloudWatch tidak bisa menelepon ponsel Anda. Aksi bawaannya hanya SNS, Auto Scaling, EC2, dan Systems Manager, sementara SNS berujung di email, SMS, atau antrean yang harus sedang Anda pantau. Tutorial yang berhasil membuat ponsel berdering biasanya memasang fungsi Lambda dan akun Twilio. Keduanya bisa dilewati: biarkan EventBridge menerima perubahan status alarm, bentuk ulang menjadi body JSON kecil, lalu kirim lewat POST ke kanal panggilan Echobell.

Panduan ini membahas seluruh jalurnya — kanal, aturan EventBridge, input transformer, filter yang menjaga dering tetap bermakna, dan alasan mengarahkan SNS langsung ke webhook tampak seharusnya berhasil padahal sebagian besar tidak.

## Mengapa jalur SNS yang biasa jadi merepotkan

Saran standarnya adalah "alarm → topik SNS → subscriber". Untuk panggilan telepon, ada tiga masalah:

- **SNS tidak punya protokol suara.** Tipe subscriber-nya email, SMS, push seluler, SQS, Lambda, Firehose, dan HTTP(S). SMS mudah terlewat dan diblokir oleh Jangan Ganggu; panggilan suara butuh sesuatu yang Anda bangun sendiri.
- **Pesan HTTPS-nya berupa string di dalam string.** SNS mengirim amplopnya dengan `Content-Type: text/plain`, dan alarmnya sendiri adalah dokumen JSON yang diserialisasi ke dalam field `Message` amplop itu. Penerima webhook yang membaca field — `AlarmName`, `NewStateValue` — hanya menemukan satu gumpalan buram.
- **Amplopnya besar.** Dengan tanda tangan, URL sertifikat penanda tangan, dan tautan berhenti berlangganan, amplop menambah jauh lebih dari satu kilobyte sebelum teks alarm Anda dimulai. Echobell memotong isi notifikasi pada 1500 byte, sehingga template "tumpahkan seluruh body" terpotong tepat di tempat bagian yang berguna dimulai.

SNS bisa dibuat berfungsi dengan Lambda yang membuka pesan lalu meneruskannya. Tetapi CloudWatch sudah menerbitkan setiap perubahan status alarm ke EventBridge sebagai event JSON yang bersih — tanpa aksi yang perlu dikonfigurasi — dan EventBridge bisa membentuk ulang serta memanggil endpoint HTTPS sendiri.

## Yang Anda butuhkan

- Akun AWS dan izin untuk membuat aturan EventBridge, connection, dan API destination
- Echobell terpasang ([App Store](https://apps.apple.com/app/apple-store/id6743597198?pt=128151925&ct=blog-cloudwatch-alarm-phone-call-alerts-id&mt=8) / [Google Play](https://play.google.com/store/apps/details?id=one.echobell.echobellandroid))
- Minimal satu alarm CloudWatch yang sudah ada
- Sepuluh menit

Tidak ada apa pun di sisi Anda yang perlu menerima lalu lintas masuk. EventBridge yang membuat permintaan keluar.

## Langkah 1 — Buat kanal yang berdering

Di Echobell, buat kanal dan setel tipe notifikasinya ke **Panggilan**. Kanal panggilan berperilaku seperti telepon masuk, bukan push, sehingga menembus Mode Fokus iOS dan Jangan Ganggu.

Transformer di Langkah 3 mengirim body datar dengan field `alarm`, `state`, `reason`, `region`, dan `link`, sehingga template tetap pendek:

```
Judul: {{state}}: {{alarm}}
Isi: {{reason}}
```

Setel **template tautan** di pengaturan lanjutan agar mengetuk notifikasi membuka alarm di konsol:

```
{{link}}
```

Salin URL webhook kanal dari tampilan detail kanal:

```
https://hook.echobell.one/t/<channel-token>
```

## Langkah 2 — Buat connection dan API destination

EventBridge memanggil endpoint HTTPS eksternal lewat **API destination**, yang membutuhkan **connection** pembawa autentikasi. Echobell mengautentikasi lewat token rahasia di URL, jadi connection hanya formalitas — tetapi EventBridge tidak mau membuat destination tanpanya.

1. Buka **EventBridge → Integration → API destinations → Connections → Create connection**
2. **Name**: `echobell`
3. **Authorization type**: **API key**
4. **API key name**: `x-source`, **Value**: `eventbridge`
5. Buat, lalu buka **API destinations → Create API destination**
6. **Name**: `echobell-calling`
7. **API destination endpoint**: URL kanal Echobell Anda dari Langkah 1
8. **HTTP method**: `POST`
9. **Invocation rate limit**: `1` per detik sudah lebih dari cukup dan berfungsi sebagai katup pengaman
10. **Connection**: `echobell`

Header API key dikirim pada setiap permintaan. Anda bisa memeriksanya di kondisi kanal Echobell jika ingin gerbang kedua di depan token:

```
header["x-source"] == "eventbridge"
```

## Langkah 3 — Buat aturan dan input transformer

Buka **EventBridge → Rules → Create rule** di region yang sama dengan alarm Anda. Aturan bersifat regional; alarm di `eu-west-1` tidak terlihat oleh aturan di `us-east-1`.

Gunakan event bus **default** dan aturan **event pattern**. Pola ini cocok dengan setiap alarm yang berpindah ke `ALARM`:

```json
{
  "source": ["aws.cloudwatch"],
  "detail-type": ["CloudWatch Alarm State Change"],
  "detail": {
    "state": { "value": ["ALARM"] }
  }
}
```

Untuk target, pilih **EventBridge API destination** dan pilih `echobell-calling`. Biarkan konsol membuat execution role baru — role itu memberi `events:InvokeApiDestination` untuk destination ini dan tidak lebih.

Lalu buka **Additional settings → Configure target input → Input transformer**:

**Input path**

```json
{
  "alarm": "$.detail.alarmName",
  "state": "$.detail.state.value",
  "reason": "$.detail.state.reason",
  "region": "$.region",
  "time": "$.time"
}
```

**Template**

```json
{
  "alarm": "<alarm>",
  "state": "<state>",
  "reason": "<reason>",
  "region": "<region>",
  "time": "<time>",
  "link": "https://console.aws.amazon.com/cloudwatch/home?region=<region>#alarmsV2:alarm/<alarm>"
}
```

EventBridge mengirim hasilnya sebagai `application/json`, dan itulah yang membuat Echobell bisa membaca `{{alarm}}` dan `{{state}}` secara langsung.

## Langkah 4 — Ketahui seperti apa event sebenarnya

Input path membaca dari event yang diterbitkan CloudWatch. Setelah dipangkas, bentuknya:

```json
{
  "version": "0",
  "id": "c4c1c1c9-6542-e61b-6ef0-8c4d36933a92",
  "detail-type": "CloudWatch Alarm State Change",
  "source": "aws.cloudwatch",
  "account": "123456789012",
  "time": "2026-10-16T03:12:44Z",
  "region": "us-east-1",
  "resources": ["arn:aws:cloudwatch:us-east-1:123456789012:alarm:prod-api-5xx"],
  "detail": {
    "alarmName": "prod-api-5xx",
    "state": {
      "value": "ALARM",
      "reason": "Threshold Crossed: 1 out of the last 1 datapoints [42.0] was greater than the threshold (10.0).",
      "timestamp": "2026-10-16T03:12:44.000+0000"
    },
    "previousState": { "value": "OK" },
    "configuration": { "description": "API 5xx errors on the prod load balancer" }
  }
}
```

Hal yang perlu diketahui sebelum mengubah template:

- **Alarm berada di bawah `detail`.** `$.alarmName` tidak cocok dengan apa pun; `$.detail.alarmName` cocok.
- **`state.reason` adalah teks buatan sistem.** Isinya menyebut datapoint dan ambang batas, persis yang ingin Anda dengar pukul 3 pagi.
- **Nama alarm disisipkan apa adanya.** Tanda kutip ganda di dalam nama alarm atau reason akan merusak JSON yang dihasilkan transformer. Gunakan huruf, angka, tanda hubung, dan garis bawah saja pada nama alarm — yang memang praktik baik — atau panggilan akan gagal dengan 400.
- **Tautan butuh nama yang polos.** Nama dengan spasi atau `#` tidak akan menautkan langsung dengan benar; pencarian di konsol tetap menemukannya.

## Langkah 5 — Saring sampai yang pantas ditelepon

Kanal alarm yang berdering untuk setiap `ALARM` adalah cara tercepat untuk melatih diri mengabaikannya. Saring di dua tempat.

**Di pola EventBridge**, yang berjalan sebelum apa pun dikirim:

| Tujuan | Perubahan pola |
| --- | --- |
| Hanya alarm produksi | `"alarmName": [{ "prefix": "prod-" }]` di dalam `detail` |
| Lewati yang ditandai tidak mendesak | Beri nama `warn-…` dan gunakan `"alarmName": [{ "anything-but": { "prefix": "warn-" } }]` |
| Hanya alarm tertentu | `"alarmName": ["prod-api-5xx", "prod-db-cpu"]` |
| Hanya alarm sungguhan, bukan status uji | Pertahankan `"state": { "value": ["ALARM"] }` — event `INSUFFICIENT_DATA` tidak pernah cocok |
| Hanya satu akun atau region | Tambahkan `"account": ["123456789012"]` atau `"region": ["us-east-1"]` di tingkat atas |

**Di Echobell**, gunakan kondisi kanal untuk hal yang tidak bisa diungkapkan pola, seperti jendela waktu:

```
state == "ALARM" && (hour >= 17 || hour < 9)
```

Variabel waktu Echobell memakai UTC, jadi konversikan dulu dari zona waktu Anda. [Referensi kondisi](/id/docs/conditions) memuat daftar variabel lengkapnya.

## Langkah 6 — Beri pemulihan pintu yang lebih sunyi

Aturan kedua dengan `"value": ["OK"]` bisa memberi tahu bahwa masalah sudah teratasi, tanpa berdering. Buat kanal Echobell kedua bertipe **Sensitif Waktu (Time Sensitive)** (atau normal), API destination kedua yang mengarah ke sana, dan pakai ulang input transformer yang sama. Template judul `{{state}}: {{alarm}}` sudah terbaca "OK: prod-api-5xx".

| Aturan | Status | Tipe kanal | Perilaku |
| --- | --- | --- | --- |
| `alarms-to-call` | `ALARM`, prefiks `prod-` | Panggilan | Berdering menembus Mode Fokus |
| `alarms-warn` | `ALARM`, prefiks `warn-` | Sensitif Waktu | Layar kunci, tanpa dering |
| `alarms-recovered` | `OK` | Normal | Push biasa |

## Uji sebelum Anda percaya

Jangan menunggu produksi rusak. Paksa sebuah alarm ke status yang Anda inginkan:

```bash
aws cloudwatch set-alarm-state \
  --alarm-name prod-api-5xx \
  --state-value ALARM \
  --state-reason "Manual test of the Echobell path"
```

Alarm kembali ke status sebenarnya pada evaluasi berikutnya, tetapi event perubahan statusnya nyata dan melewati aturan Anda. Untuk menguji sisi Echobell saja, picu kanal secara langsung:

```bash
curl -X POST https://hook.echobell.one/t/<channel-token> \
  -H 'Content-Type: application/json' \
  -d '{"alarm":"prod-api-5xx","state":"ALARM","reason":"Manual test","region":"us-east-1","link":"https://console.aws.amazon.com/cloudwatch/"}'
```

Kalau `curl` berdering sementara tes alarm tidak, masalahnya ada di aturan, transformer, atau destination — bukan di kanal.

## Bagaimana dengan SNS dan email-ke-panggilan?

Kalau Anda sudah punya topik SNS di mana-mana dan tidak ingin menyentuh EventBridge, ada dua jalur lain:

- **SNS → Lambda → webhook.** Beberapa baris kode mengurai `Message`, lalu mengirim POST dengan body datar ke URL Echobell yang sama. Berfungsi, tetapi sekarang Anda memiliki sebuah fungsi, sebuah role, dan lognya.
- **SNS → email → pemicu email Echobell.** Langganankan [alamat pemicu email](/id/docs/email-trigger) kanal ke topik tersebut. Alarm tiba sebagai email, dan `{{subject}}` serta `{{text}}` di template Anda menjadi notifikasinya. Ini konfigurasi paling sedikit dari semuanya, dengan catatan bahwa langganan email SNS butuh satu kali klik konfirmasi dan teksnya tidak dibentuk ulang.

Melanggankan URL webhook Echobell langsung ke topik sebagai endpoint HTTPS adalah jalur yang sebaiknya dihindari: permintaan konfirmasinya tiba sebagai notifikasi, dan setiap alarm sesudahnya berupa amplop panjang yang dijelaskan di atas.

## Batas yang penting saat insiden

- **Body 1 MiB.** Echobell menolak body pemicu di atas 1 MiB dengan HTTP 413. Alarm yang sudah ditransformasi hanya beberapa ratus byte, jadi Anda tidak akan menemuinya di sini.
- **120 permintaan per menit per token.** Di atas itu pemicu menjawab `429` dengan `RATE_LIMIT_EXCEEDED` dan sebuah `Retry-After`. Batas 1 per detik pada destination menjaga Anda di bawahnya, dan EventBridge mengulang event yang gagal terkirim.
- **1500 byte isi notifikasi.** Hasil render yang lebih panjang dipotong. `state.reason` hanya satu-dua kalimat dan muat.

## Yang tidak diberikan setup ini

- **Tanpa pengakuan (ack).** Mengangkat telepon tidak memberi tahu CloudWatch apa pun dan tidak membisukan subscriber lain.
- **Tanpa eskalasi atau rotasi.** Semua yang berlangganan kanal ditelepon; tidak ada yang ditelepon berikutnya.
- **Tanpa deduplikasi di luar alarm.** Alarm yang berkedip dan berpindah `OK → ALARM` setiap beberapa menit akan berdering setiap kali. Atasi dengan periode evaluasi yang lebih panjang atau `DatapointsToAlarm` pada alarm itu sendiri.
- **Tanpa sinkronisasi dua arah.** Memperbaiki penyebabnya tidak membersihkan apa pun di ponsel Anda.

Kalau itu semua penghalang, Anda butuh platform on-call lengkap. Kalau yang Anda perlukan adalah "telepon saya saat alarm produksi menyala", ini hanya beberapa layar konsol.

## Pemecahan masalah

**Alarm menyala tapi tidak ada yang datang.** Buka tab **Monitoring** pada aturan: `Invocations` menunjukkan apakah pola cocok, `FailedInvocations` apakah pengiriman gagal. Aturan di region yang berbeda dari alarm tidak pernah cocok.

**Aturan cocok tapi panggilan gagal dengan 400.** Transformer menghasilkan JSON yang tidak valid. Cari tanda kutip atau backslash di nama alarm atau reason.

**Notifikasi kosong.** Template membaca field yang tidak dikirim transformer. Body-nya datar: `{{alarm}}`, bukan `{{detail.alarmName}}`.

**Berdering berulang untuk satu alarm.** Alarmnya berkedip. Perpanjang periode evaluasi atau minta lebih banyak datapoint; ini pengaturan CloudWatch, bukan Echobell.

**Berdering untuk alarm yang tak terduga.** Periksa pola apakah ada filter `prefix` yang terlewat, dan ingat bahwa alarm komposit dan alarm yang dibuat alat lain (misalnya kebijakan Auto Scaling) juga memancarkan perubahan status.

## Pertanyaan yang sering diajukan

### Bisakah CloudWatch menelepon nomor telepon secara bawaan?

Tidak. Aksi alarm CloudWatch adalah notifikasi SNS, Auto Scaling, aksi EC2, dan Systems Manager. Panggilan suara memerlukan layanan eksternal: Lambda yang menelepon lewat penyedia, platform on-call, atau webhook panggilan seperti Echobell.

### Perlukah topik SNS?

Tidak. CloudWatch memancarkan event perubahan status alarm ke EventBridge sendiri, entah alarm punya aksi atau tidak. Anda boleh membiarkan daftar aksi alarm kosong.

### Apakah alarm CloudWatch menembus Jangan Ganggu?

Hanya jika tiba sebagai alert bergaya panggilan. Kanal Echobell bertipe panggilan berperilaku seperti telepon masuk, yang dilewatkan oleh Mode Fokus dan Jangan Ganggu di iOS. SMS atau push biasa tidak.

### Kenapa tidak langsung melanggankan URL webhook ke SNS?

SNS mengirim `text/plain` dengan alarm diserialisasi di dalam string `Message`, sehingga template tidak bisa membaca field satu per satu, dan amplopnya cukup panjang untuk terpotong. SNS juga mengirim konfirmasi langganan lebih dulu, yang akan tiba sebagai notifikasi.

### Apakah ini berbiaya di AWS?

Event perubahan status alarm masuk ke event bus default tanpa biaya; pemanggilan API destination ditagih per permintaan. Pada volume kumpulan alarm yang sehat, jumlahnya dapat diabaikan, tetapi periksa harga EventBridge terkini untuk region Anda.

### Bisakah saya menelepon orang berbeda untuk alarm berbeda?

Bisa. Buat satu kanal per audiens, satu aturan per kanal, dan biarkan tiap orang berlangganan dengan tipe notifikasi yang diinginkan. Tidak ada pengakuan, jadi semua yang berlangganan dengan "panggilan" akan ditelepon.

### Bagaimana dengan alarm di beberapa region atau akun?

Aturan bersifat per region, jadi buat aturan di setiap region yang Anda pakai (definisi API destination yang sama diulang per region). Untuk beberapa akun, kirim event ke bus pusat di satu akun dan letakkan aturannya di sana.

## Penutup

Jalurnya terdiri dari lima bagian: kanal panggilan, connection dan API destination yang mengarah ke sana, aturan yang hanya cocok dengan alarm yang pantas membangunkan seseorang, input transformer yang meratakan event, dan tes `set-alarm-state` paksa sebelum Anda mengandalkan semuanya. Sisanya di sini adalah soal menjaganya cukup sempit agar sebulan dari sekarang deringnya masih berarti sesuatu.

[Unduh Echobell untuk iPhone](https://apps.apple.com/app/apple-store/id6743597198?pt=128151925&ct=blog-cloudwatch-alarm-phone-call-alerts-id&mt=8) atau [dapatkan di Google Play](https://play.google.com/store/apps/details?id=one.echobell.echobellandroid), lalu jalankan tes `set-alarm-state`.

## Artikel terkait

- [Referensi kondisi kanal](/id/docs/conditions)
- [Panduan integrasi webhook](/id/docs/webhook)
- [Panduan pemicu email](/id/docs/email-trigger)
- [Notifikasi telepon Sentry](/id/blog/sentry-phone-call-alerts)
- [Notifikasi telepon untuk downtime API](/id/blog/phone-call-alerts-api-downtime)
- [Panduan developer mengatasi kelelahan alert](/id/blog/fix-alert-fatigue-developer-guide)
- [Menembus Mode Fokus iOS untuk alert kritis](/id/blog/how-to-bypass-ios-focus-mode-for-critical-alerts)
