From 2c81773d01094be3e4fbe10add54c166469acb37 Mon Sep 17 00:00:00 2001
From: binwiederhier <philipp.heckel@gmail.com>
Date: Tue, 16 May 2023 22:27:48 -0400
Subject: [PATCH] Add call verification

---
 docs/config.md                       |   4 +--
 docs/publish.md                      |  48 ++++++++++++++++----------
 docs/static/img/web-phone-verify.png | Bin 0 -> 22959 bytes
 go.sum                               |  18 ----------
 server/errors.go                     |   1 +
 server/server_account.go             |  13 +++----
 server/server_twilio.go              |  13 +++----
 server/types.go                      |   9 +++--
 web/public/static/langs/en.json      |   7 ++--
 web/src/app/AccountApi.js            |   5 +--
 web/src/components/Account.js        |  49 +++++++++++++++++----------
 11 files changed, 93 insertions(+), 74 deletions(-)
 create mode 100644 docs/static/img/web-phone-verify.png

diff --git a/docs/config.md b/docs/config.md
index 353a9d03..d6f6e408 100644
--- a/docs/config.md
+++ b/docs/config.md
@@ -868,8 +868,8 @@ are the easiest), and then configure the following options:
 * `twilio-from-number` is the outgoing phone number you purchased, e.g. +18775132586 
 * `twilio-verify-service` is the Twilio Verify service SID, e.g. VA12345beefbeef67890beefbeef122586
 
-After you have configured phone calls, create a [tier](#tiers) with a call limit, and then assign it to a user.
-Users may then use the `X-Call` header to receive a phone call when publishing a message.
+After you have configured phone calls, create a [tier](#tiers) with a call limit (e.g. `ntfy tier create --call-limit=10 ...`),
+and then assign it to a user. Users may then use the `X-Call` header to receive a phone call when publishing a message.
 
 ## Rate limiting
 !!! info
diff --git a/docs/publish.md b/docs/publish.md
index 98f3e876..3cca6fc6 100644
--- a/docs/publish.md
+++ b/docs/publish.md
@@ -2702,16 +2702,26 @@ You can use ntfy to call a phone and **read the message out loud using text-to-s
 Similar to email notifications, this can be useful to blast-notify yourself on all possible channels, or to notify people that do not have 
 the ntfy app installed on their phone.
 
-**Phone numbers have to be previously verified** (via the web app), so this feature is **only available to authenticated users**. 
-To forward a message as a voice call, pass a phone number in the `X-Call` header (or its alias: `Call`), prefixed with a
-plus sign and the country code, e.g. `+12223334444`. You may also simply pass `yes` as a value to pick the first of your 
-verified phone numbers.
+**Phone numbers have to be previously verified** (via the [web app](https://ntfy.sh/account)), so this feature is 
+**only available to authenticated users** (no anonymous phone calls). To forward a message as a voice call, pass a phone
+number in the `X-Call` header (or its alias: `Call`), prefixed with a plus sign and the country code, e.g. `+12223334444`. 
+You may also simply pass `yes` as a value to pick the first of your verified phone numbers. 
+On ntfy.sh, this feature is only supported to [ntfy Pro](https://ntfy.sh/app) plans.
+
+<figure markdown>
+  ![e-mail publishing](static/img/web-phone-verify.png)
+  <figcaption>Phone number verification in the <a href="https://ntfy.sh/account">web app</a></figcaption>
+</figure>
+
+As of today, the text-to-speed voice used will only support English. If there is demand for other languages, we'll
+be happy to add support for that. Please [open an issue on GitHub](https://github.com/binwiederhier/ntfy/issues).
 
 !!! info
-    As of today, the text-to-speed voice used will only support English. If there is demand for other languages, we'll
-    be happy to add support for that. Please [open an issue on GitHub](https://github.com/binwiederhier/ntfy/issues).
+    You are responsible for the message content, and **you must abide by the [Twilio Acceptable Use Policy](https://www.twilio.com/en-us/legal/aup)**.
+    This particularly means that you must not use this feature to send unsolicited messages, or messages that are illegal or
+    violate the rights of others. Please read the policy for details. Failure to do so may result in your account being suspended or terminated.
 
-On ntfy.sh, this feature is only supported to [ntfy Pro](https://ntfy.sh/app) plans.
+Here's how you use it:
 
 === "Command line (curl)"
     ```
@@ -3431,17 +3441,18 @@ There are a few limitations to the API to prevent abuse and to keep the server h
 are configurable via the server side [rate limiting settings](config.md#rate-limiting). Most of these limits you won't run into,
 but just in case, let's list them all:
 
-| Limit                           | Description                                                                                                                                                                                                             |
-|---------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| **Message length**              | Each message can be up to 4,096 bytes long. Longer messages are treated as [attachments](#attachments).                                                                                                                 |
-| **Requests**                    | By default, the server is configured to allow 60 requests per visitor at once, and then refills the your allowed requests bucket at a rate of one request per 5 seconds.                                                |
-| **Daily messages**              | By default, the number of messages is governed by the request limits. This can be overridden. On ntfy.sh, the daily message limit is 250.                                                                               |
-| **E-mails**                     | By default, the server is configured to allow sending 16 e-mails per visitor at once, and then refills the your allowed e-mail bucket at a rate of one per hour. On ntfy.sh, the daily limit is 5.                      |
-| **Subscription limit**          | By default, the server allows each visitor to keep 30 connections to the server open.                                                                                                                                   |
-| **Attachment size limit**       | By default, the server allows attachments up to 15 MB in size, up to 100 MB in total per visitor and up to 5 GB across all visitors. On ntfy.sh, the attachment size limit is 2 MB, and the per-visitor total is 20 MB. |
-| **Attachment expiry**           | By default, the server deletes attachments after 3 hours and thereby frees up space from the total visitor attachment limit.                                                                                            |
-| **Attachment bandwidth**        | By default, the server allows 500 MB of GET/PUT/POST traffic for attachments per visitor in a 24 hour period. Traffic exceeding that is rejected. On ntfy.sh, the daily bandwidth limit is 200 MB.                      |
-| **Total number of topics**      | By default, the server is configured to allow 15,000 topics. The ntfy.sh server has higher limits though.                                                                                                               |
+| Limit                      | Description                                                                                                                                                                                                             |
+|----------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| **Message length**         | Each message can be up to 4,096 bytes long. Longer messages are treated as [attachments](#attachments).                                                                                                                 |
+| **Requests**               | By default, the server is configured to allow 60 requests per visitor at once, and then refills the your allowed requests bucket at a rate of one request per 5 seconds.                                                |
+| **Daily messages**         | By default, the number of messages is governed by the request limits. This can be overridden. On ntfy.sh, the daily message limit is 250.                                                                               |
+| **E-mails**                | By default, the server is configured to allow sending 16 e-mails per visitor at once, and then refills the your allowed e-mail bucket at a rate of one per hour. On ntfy.sh, the daily limit is 5.                      |
+| **Phone calls**            | By default, the server does not allow any phone calls, except for users with a tier that has a call limit.                                                                                                              |
+| **Subscription limit**     | By default, the server allows each visitor to keep 30 connections to the server open.                                                                                                                                   |
+| **Attachment size limit**  | By default, the server allows attachments up to 15 MB in size, up to 100 MB in total per visitor and up to 5 GB across all visitors. On ntfy.sh, the attachment size limit is 2 MB, and the per-visitor total is 20 MB. |
+| **Attachment expiry**      | By default, the server deletes attachments after 3 hours and thereby frees up space from the total visitor attachment limit.                                                                                            |
+| **Attachment bandwidth**   | By default, the server allows 500 MB of GET/PUT/POST traffic for attachments per visitor in a 24 hour period. Traffic exceeding that is rejected. On ntfy.sh, the daily bandwidth limit is 200 MB.                      |
+| **Total number of topics** | By default, the server is configured to allow 15,000 topics. The ntfy.sh server has higher limits though.                                                                                                               |
 
 These limits can be changed on a per-user basis using [tiers](config.md#tiers). If [payments](config.md#payments) are enabled, a user tier can be changed by purchasing
 a higher tier. ntfy.sh offers multiple paid tiers, which allows for much hier limits than the ones listed above. 
@@ -3470,6 +3481,7 @@ table in their canonical form.
 | `X-Icon`        | `Icon`                                     | URL to use as notification [icon](#icons)                                                     |
 | `X-Filename`    | `Filename`, `file`, `f`                    | Optional [attachment](#attachments) filename, as it appears in the client                     |
 | `X-Email`       | `X-E-Mail`, `Email`, `E-Mail`, `mail`, `e` | E-mail address for [e-mail notifications](#e-mail-notifications)                              |
+| `X-Call`        | `Call`                                     | Phone number for [phone calls](#phone-calls)                                                  |
 | `X-Cache`       | `Cache`                                    | Allows disabling [message caching](#message-caching)                                          |
 | `X-Firebase`    | `Firebase`                                 | Allows disabling [sending to Firebase](#disable-firebase)                                     |
 | `X-UnifiedPush` | `UnifiedPush`, `up`                        | [UnifiedPush](#unifiedpush) publish option, only to be used by UnifiedPush apps               |
diff --git a/docs/static/img/web-phone-verify.png b/docs/static/img/web-phone-verify.png
new file mode 100644
index 0000000000000000000000000000000000000000..335aeef13848541002456ebbf93ebb17669d04e9
GIT binary patch
literal 22959
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

literal 0
HcmV?d00001

diff --git a/go.sum b/go.sum
index ccb1ae4d..ff2d580f 100644
--- a/go.sum
+++ b/go.sum
@@ -1,23 +1,15 @@
 cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
 cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
-cloud.google.com/go v0.110.1 h1:oDJ19Fu9TX9Xs06iyCw4yifSqZ7JQ8BeuVHcTmWQlOA=
-cloud.google.com/go v0.110.1/go.mod h1:uc+V/WjzxQ7vpkxfJhgW4Q4axWXyfAerpQOuSNDZyFw=
 cloud.google.com/go v0.110.2 h1:sdFPBr6xG9/wkBbfhmUz/JmZC7X6LavQgcrVINrKiVA=
 cloud.google.com/go v0.110.2/go.mod h1:k04UEeEtb6ZBRTv3dZz4CeJC3jKGxyhl0sAiVVquxiw=
-cloud.google.com/go/compute v1.19.1 h1:am86mquDUgjGNWxiGn+5PGLbmgiWXlE/yNWpIpNvuXY=
-cloud.google.com/go/compute v1.19.1/go.mod h1:6ylj3a05WF8leseCdIf77NK0g1ey+nj5IKd5/kvShxE=
 cloud.google.com/go/compute v1.19.2 h1:GbJtPo8OKVHbVep8jvM57KidbYHxeE68LOVqouNLrDY=
 cloud.google.com/go/compute v1.19.2/go.mod h1:5f5a+iC1IriXYauaQ0EyQmEAEq9CGRnV5xJSQSlTV08=
 cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
 cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
 cloud.google.com/go/firestore v1.9.0 h1:IBlRyxgGySXu5VuW0RgGFlTtLukSnNkpDiEOMkQkmpA=
 cloud.google.com/go/firestore v1.9.0/go.mod h1:HMkjKHNTtRyZNiMzu7YAsLr9K3X2udY2AMwDaMEQiiE=
-cloud.google.com/go/iam v1.0.0 h1:hlQJMovyJJwYjZcTohUH4o1L8Z8kYz+E+W/zktiLCBc=
-cloud.google.com/go/iam v1.0.0/go.mod h1:ikbQ4f1r91wTmBmmOtBCOtuEOei6taatNXytzB7Cxew=
 cloud.google.com/go/iam v1.0.1 h1:lyeCAU6jpnVNrE9zGQkTl3WgNgK/X+uWwaw0kynZJMU=
 cloud.google.com/go/iam v1.0.1/go.mod h1:yR3tmSL8BcZB4bxByRv2jkSIahVmCtfKZwLYGBalRE8=
-cloud.google.com/go/longrunning v0.4.1 h1:v+yFJOfKC3yZdY6ZUI933pIYdhyhV8S3NpWrXWmg7jM=
-cloud.google.com/go/longrunning v0.4.1/go.mod h1:4iWDqhBZ70CvZ6BfETbvam3T8FMvLK+eFj0E6AaRQTo=
 cloud.google.com/go/longrunning v0.4.2 h1:WDKiiNXFTaQ6qz/G8FCOkuY9kJmOJGY67wPUC1M2RbE=
 cloud.google.com/go/longrunning v0.4.2/go.mod h1:OHrnaYyLUV6oqwh0xiS7e5sLQhP1m0QU9R+WhGDMgIQ=
 cloud.google.com/go/storage v1.30.1 h1:uOdMxAs8HExqBlnLtnQyP0YkvbiDpdGShGKtx6U/oNM=
@@ -147,8 +139,6 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
 github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
 github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
 github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
-github.com/stripe/stripe-go/v74 v74.17.0 h1:qVWSzmADr6gudznuAcPjB9ewzgxfyIhBCkyTbkxJcCw=
-github.com/stripe/stripe-go/v74 v74.17.0/go.mod h1:f9L6LvaXa35ja7eyvP6GQswoaIPaBRvGAimAO+udbBw=
 github.com/stripe/stripe-go/v74 v74.18.0 h1:ImSIoaVkTUozHxa21AhwHYBjwc8fVSJJJB1Q7oaXzIw=
 github.com/stripe/stripe-go/v74 v74.18.0/go.mod h1:f9L6LvaXa35ja7eyvP6GQswoaIPaBRvGAimAO+udbBw=
 github.com/urfave/cli/v2 v2.25.3 h1:VJkt6wvEBOoSjPFQvOkv6iWIrsJyCrKGtCtxXWwmGeY=
@@ -163,8 +153,6 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
-golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ=
-golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
 golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
 golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -186,14 +174,10 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
 golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
-golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
-golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
 golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
 golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g=
-golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4=
 golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8=
 golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -241,8 +225,6 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
 golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
-google.golang.org/api v0.121.0 h1:8Oopoo8Vavxx6gt+sgs8s8/X60WBAtKQq6JqnkF+xow=
-google.golang.org/api v0.121.0/go.mod h1:gcitW0lvnyWjSp9nKxAbdHKIZ6vF4aajGueeslZOyms=
 google.golang.org/api v0.122.0 h1:zDobeejm3E7pEG1mNHvdxvjs5XJoCMzyNH+CmwL94Es=
 google.golang.org/api v0.122.0/go.mod h1:gcitW0lvnyWjSp9nKxAbdHKIZ6vF4aajGueeslZOyms=
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
diff --git a/server/errors.go b/server/errors.go
index a42641b4..b67558db 100644
--- a/server/errors.go
+++ b/server/errors.go
@@ -112,6 +112,7 @@ var (
 	errHTTPBadRequestPhoneNumberInvalid              = &errHTTP{40033, http.StatusBadRequest, "invalid request: phone number invalid", "https://ntfy.sh/docs/publish/#phone-calls", nil}
 	errHTTPBadRequestPhoneNumberNotVerified          = &errHTTP{40034, http.StatusBadRequest, "invalid request: phone number not verified, or no matching verified numbers found", "https://ntfy.sh/docs/publish/#phone-calls", nil}
 	errHTTPBadRequestAnonymousCallsNotAllowed        = &errHTTP{40035, http.StatusBadRequest, "invalid request: anonymous phone calls are not allowed", "https://ntfy.sh/docs/publish/#phone-calls", nil}
+	errHTTPBadRequestPhoneNumberVerifyChannelInvalid = &errHTTP{40036, http.StatusBadRequest, "invalid request: verification channel must be 'sms' or 'call'", "https://ntfy.sh/docs/publish/#phone-calls", nil}
 	errHTTPNotFound                                  = &errHTTP{40401, http.StatusNotFound, "page not found", "", nil}
 	errHTTPUnauthorized                              = &errHTTP{40101, http.StatusUnauthorized, "unauthorized", "https://ntfy.sh/docs/publish/#authentication", nil}
 	errHTTPForbidden                                 = &errHTTP{40301, http.StatusForbidden, "forbidden", "https://ntfy.sh/docs/publish/#authentication", nil}
diff --git a/server/server_account.go b/server/server_account.go
index 2330eab8..b9997ef3 100644
--- a/server/server_account.go
+++ b/server/server_account.go
@@ -523,12 +523,13 @@ func (s *Server) maybeRemoveMessagesAndExcessReservations(r *http.Request, v *vi
 
 func (s *Server) handleAccountPhoneNumberVerify(w http.ResponseWriter, r *http.Request, v *visitor) error {
 	u := v.User()
-	req, err := readJSONWithLimit[apiAccountPhoneNumberRequest](r.Body, jsonBodyBytesLimit, false)
+	req, err := readJSONWithLimit[apiAccountPhoneNumberVerifyRequest](r.Body, jsonBodyBytesLimit, false)
 	if err != nil {
 		return err
-	}
-	if !phoneNumberRegex.MatchString(req.Number) {
+	} else if !phoneNumberRegex.MatchString(req.Number) {
 		return errHTTPBadRequestPhoneNumberInvalid
+	} else if req.Channel != "sms" && req.Channel != "call" {
+		return errHTTPBadRequestPhoneNumberVerifyChannelInvalid
 	}
 	// Check user is allowed to add phone numbers
 	if u == nil || (u.IsUser() && u.Tier == nil) {
@@ -545,7 +546,7 @@ func (s *Server) handleAccountPhoneNumberVerify(w http.ResponseWriter, r *http.R
 	}
 	// Actually add the unverified number, and send verification
 	logvr(v, r).Tag(tagAccount).Field("phone_number", req.Number).Debug("Sending phone number verification")
-	if err := s.verifyPhoneNumber(v, r, req.Number); err != nil {
+	if err := s.verifyPhoneNumber(v, r, req.Number, req.Channel); err != nil {
 		return err
 	}
 	return s.writeJSON(w, newSuccessResponse())
@@ -553,7 +554,7 @@ func (s *Server) handleAccountPhoneNumberVerify(w http.ResponseWriter, r *http.R
 
 func (s *Server) handleAccountPhoneNumberAdd(w http.ResponseWriter, r *http.Request, v *visitor) error {
 	u := v.User()
-	req, err := readJSONWithLimit[apiAccountPhoneNumberRequest](r.Body, jsonBodyBytesLimit, false)
+	req, err := readJSONWithLimit[apiAccountPhoneNumberAddRequest](r.Body, jsonBodyBytesLimit, false)
 	if err != nil {
 		return err
 	}
@@ -572,7 +573,7 @@ func (s *Server) handleAccountPhoneNumberAdd(w http.ResponseWriter, r *http.Requ
 
 func (s *Server) handleAccountPhoneNumberDelete(w http.ResponseWriter, r *http.Request, v *visitor) error {
 	u := v.User()
-	req, err := readJSONWithLimit[apiAccountPhoneNumberRequest](r.Body, jsonBodyBytesLimit, false)
+	req, err := readJSONWithLimit[apiAccountPhoneNumberAddRequest](r.Body, jsonBodyBytesLimit, false)
 	if err != nil {
 		return err
 	}
diff --git a/server/server_twilio.go b/server/server_twilio.go
index f8067490..11f58aa7 100644
--- a/server/server_twilio.go
+++ b/server/server_twilio.go
@@ -18,13 +18,14 @@ const (
 <Response>
 	<Pause length="1"/>
 	<Say loop="3">
-		You have a notification from notify on topic %s. Message:
+		You have a message from notify on topic %s. Message:
 		<break time="1s"/>
 		%s
 		<break time="1s"/>
-		End message.
+		End of message.
 		<break time="1s"/>
-		This message was sent by user %s. It will be repeated up to three times.
+		This message was sent by user %s. It will be repeated three times.
+		To unsubscribe from calls like this, remove your phone number in the notify web app.
 		<break time="3s"/>
 	</Say>
 	<Say>Goodbye.</Say>
@@ -97,11 +98,11 @@ func (s *Server) callPhoneInternal(data url.Values) (string, error) {
 	return string(response), nil
 }
 
-func (s *Server) verifyPhoneNumber(v *visitor, r *http.Request, phoneNumber string) error {
-	ev := logvr(v, r).Tag(tagTwilio).Field("twilio_to", phoneNumber).Debug("Sending phone verification")
+func (s *Server) verifyPhoneNumber(v *visitor, r *http.Request, phoneNumber, channel string) error {
+	ev := logvr(v, r).Tag(tagTwilio).Field("twilio_to", phoneNumber).Field("twilio_channel", channel).Debug("Sending phone verification")
 	data := url.Values{}
 	data.Set("To", phoneNumber)
-	data.Set("Channel", "sms")
+	data.Set("Channel", channel)
 	requestURL := fmt.Sprintf("%s/v2/Services/%s/Verifications", s.config.TwilioVerifyBaseURL, s.config.TwilioVerifyService)
 	req, err := http.NewRequest(http.MethodPost, requestURL, strings.NewReader(data.Encode()))
 	if err != nil {
diff --git a/server/types.go b/server/types.go
index a1d18926..3b733678 100644
--- a/server/types.go
+++ b/server/types.go
@@ -311,9 +311,14 @@ type apiAccountTokenResponse struct {
 	Expires    int64  `json:"expires,omitempty"` // Unix timestamp
 }
 
-type apiAccountPhoneNumberRequest struct {
+type apiAccountPhoneNumberVerifyRequest struct {
+	Number  string `json:"number"`
+	Channel string `json:"channel"`
+}
+
+type apiAccountPhoneNumberAddRequest struct {
 	Number string `json:"number"`
-	Code   string `json:"code,omitempty"` // Only supplied in "verify" call
+	Code   string `json:"code,omitempty"`
 }
 
 type apiAccountTier struct {
diff --git a/web/public/static/langs/en.json b/web/public/static/langs/en.json
index f2120e5f..588a1f9f 100644
--- a/web/public/static/langs/en.json
+++ b/web/public/static/langs/en.json
@@ -188,17 +188,20 @@
   "account_basics_password_dialog_button_submit": "Change password",
   "account_basics_password_dialog_current_password_incorrect": "Password incorrect",
   "account_basics_phone_numbers_title": "Phone numbers",
-  "account_basics_phone_numbers_dialog_description": "To use the call notification feature, you need to add and verify at least one phone number. Adding it will send a verification SMS to your phone.",
+  "account_basics_phone_numbers_dialog_description": "To use the call notification feature, you need to add and verify at least one phone number. Verification can be done via SMS or a phone call.",
   "account_basics_phone_numbers_description": "For phone call notifications",
   "account_basics_phone_numbers_no_phone_numbers_yet": "No phone numbers yet",
   "account_basics_phone_numbers_copied_to_clipboard": "Phone number copied to clipboard",
   "account_basics_phone_numbers_dialog_title": "Add phone number",
   "account_basics_phone_numbers_dialog_number_label": "Phone number",
   "account_basics_phone_numbers_dialog_number_placeholder": "e.g. +1222333444",
-  "account_basics_phone_numbers_dialog_send_verification_button": "Send verification",
+  "account_basics_phone_numbers_dialog_verify_button_sms": "Send SMS",
+  "account_basics_phone_numbers_dialog_verify_button_call": "Call me",
   "account_basics_phone_numbers_dialog_code_label": "Verification code",
   "account_basics_phone_numbers_dialog_code_placeholder": "e.g. 123456",
   "account_basics_phone_numbers_dialog_check_verification_button": "Confirm code",
+  "account_basics_phone_numbers_dialog_channel_sms": "SMS",
+  "account_basics_phone_numbers_dialog_channel_call": "Call",
   "account_usage_title": "Usage",
   "account_usage_of_limit": "of {{limit}}",
   "account_usage_unlimited": "Unlimited",
diff --git a/web/src/app/AccountApi.js b/web/src/app/AccountApi.js
index b5bfcd29..8908f306 100644
--- a/web/src/app/AccountApi.js
+++ b/web/src/app/AccountApi.js
@@ -299,14 +299,15 @@ class AccountApi {
         return await response.json(); // May throw SyntaxError
     }
 
-    async verifyPhoneNumber(phoneNumber) {
+    async verifyPhoneNumber(phoneNumber, channel) {
         const url = accountPhoneVerifyUrl(config.base_url);
         console.log(`[AccountApi] Sending phone verification ${url}`);
         await fetchOrThrow(url, {
             method: "PUT",
             headers: withBearerAuth({}, session.token()),
             body: JSON.stringify({
-                number: phoneNumber
+                number: phoneNumber,
+                channel: channel
             })
         });
     }
diff --git a/web/src/components/Account.js b/web/src/components/Account.js
index b4a378e6..b480ea6b 100644
--- a/web/src/components/Account.js
+++ b/web/src/components/Account.js
@@ -1,13 +1,13 @@
 import * as React from 'react';
 import {useContext, useState} from 'react';
 import {
-    Alert,
+    Alert, ButtonGroup,
     CardActions,
     CardContent, Chip,
-    FormControl,
+    FormControl, FormControlLabel, InputLabel,
     LinearProgress,
     Link,
-    Portal,
+    Portal, Radio, RadioGroup,
     Select,
     Snackbar,
     Stack,
@@ -47,12 +47,14 @@ import {AccountContext} from "./App";
 import DialogFooter from "./DialogFooter";
 import {Paragraph} from "./styles";
 import CloseIcon from "@mui/icons-material/Close";
-import {ContentCopy, Public} from "@mui/icons-material";
+import {Check, ContentCopy, DeleteForever, Public} from "@mui/icons-material";
 import MenuItem from "@mui/material/MenuItem";
 import DialogContentText from "@mui/material/DialogContentText";
 import {IncorrectPasswordError, UnauthorizedError} from "../app/errors";
 import {ProChip} from "./SubscriptionPopup";
 import AddIcon from "@mui/icons-material/Add";
+import ListItemIcon from "@mui/material/ListItemIcon";
+import ListItemText from "@mui/material/ListItemText";
 
 const Account = () => {
     if (!session.exists()) {
@@ -408,6 +410,7 @@ const AddPhoneNumberDialog = (props) => {
     const { t } = useTranslation();
     const [error, setError] = useState("");
     const [phoneNumber, setPhoneNumber] = useState("");
+    const [channel, setChannel] = useState("sms");
     const [code, setCode] = useState("");
     const [sending, setSending] = useState(false);
     const [verificationCodeSent, setVerificationCodeSent] = useState(false);
@@ -432,7 +435,7 @@ const AddPhoneNumberDialog = (props) => {
     const verifyPhone = async () => {
         try {
             setSending(true);
-            await accountApi.verifyPhoneNumber(phoneNumber);
+            await accountApi.verifyPhoneNumber(phoneNumber, channel);
             setVerificationCodeSent(true);
         } catch (e) {
             console.log(`[Account] Error sending verification`, e);
@@ -471,18 +474,26 @@ const AddPhoneNumberDialog = (props) => {
                     {t("account_basics_phone_numbers_dialog_description")}
                 </DialogContentText>
                 {!verificationCodeSent &&
-                    <TextField
-                        margin="dense"
-                        label={t("account_basics_phone_numbers_dialog_number_label")}
-                        aria-label={t("account_basics_phone_numbers_dialog_number_label")}
-                        placeholder={t("account_basics_phone_numbers_dialog_number_placeholder")}
-                        type="tel"
-                        value={phoneNumber}
-                        onChange={ev => setPhoneNumber(ev.target.value)}
-                        fullWidth
-                        inputProps={{ inputMode: 'tel', pattern: '\+[0-9]*' }}
-                        variant="standard"
-                    />
+                    <div style={{display: "flex"}}>
+                        <TextField
+                            margin="dense"
+                            label={t("account_basics_phone_numbers_dialog_number_label")}
+                            aria-label={t("account_basics_phone_numbers_dialog_number_label")}
+                            placeholder={t("account_basics_phone_numbers_dialog_number_placeholder")}
+                            type="tel"
+                            value={phoneNumber}
+                            onChange={ev => setPhoneNumber(ev.target.value)}
+                            inputProps={{ inputMode: 'tel', pattern: '\+[0-9]*' }}
+                            variant="standard"
+                            sx={{ flexGrow: 1 }}
+                        />
+                        <FormControl sx={{ flexWrap: "nowrap" }}>
+                            <RadioGroup row sx={{ flexGrow: 1, marginTop: "8px", marginLeft: "5px" }}>
+                                <FormControlLabel value="sms" control={<Radio checked={channel === "sms"} onChange={(e) => setChannel(e.target.value)} />} label={t("account_basics_phone_numbers_dialog_channel_sms")} />
+                                <FormControlLabel value="call" control={<Radio checked={channel === "call"} onChange={(e) => setChannel(e.target.value)} />} label={t("account_basics_phone_numbers_dialog_channel_call")} sx={{ marginRight: 0 }} />
+                            </RadioGroup>
+                        </FormControl>
+                    </div>
                 }
                 {verificationCodeSent &&
                     <TextField
@@ -502,7 +513,9 @@ const AddPhoneNumberDialog = (props) => {
             <DialogFooter status={error}>
                 <Button onClick={handleCancel}>{verificationCodeSent ? t("common_back") : t("common_cancel")}</Button>
                 <Button onClick={handleDialogSubmit} disabled={sending || !/^\+\d+$/.test(phoneNumber)}>
-                    {verificationCodeSent ?t("account_basics_phone_numbers_dialog_check_verification_button")  : t("account_basics_phone_numbers_dialog_send_verification_button")}
+                    {!verificationCodeSent && channel === "sms" && t("account_basics_phone_numbers_dialog_verify_button_sms")}
+                    {!verificationCodeSent && channel === "call" && t("account_basics_phone_numbers_dialog_verify_button_call")}
+                    {verificationCodeSent && t("account_basics_phone_numbers_dialog_check_verification_button")}
                 </Button>
             </DialogFooter>
         </Dialog>