SMS Receiver API January 2, 2020

Many applications use an OTP(One Time Password) based login flow these days. Native apps can automatically retrieve OTP values from text messages. This translates to a better user experience since manually entering or copy pasting the OTP is a big hassle. Sadly web browsers don’t have access to text messages, until now. The experimental SMS Receiver API which is under Origin trial provides a way for Chrome browsers on Android (version 78 onwards) to automatically retrieve OTP values from text messages with a few limitations. The feature needs to be explicitly enabled by setting the relevant flags or used under Origin Trial. The API is still experimental and hence is subject to change. But that does not mean you can’t play around with it.

Lets look at how we can use the SMS Receiver API.

if ("sms" in navigator) {
  const sms = await navigator.sms.receive();
  // sms.content gives us the body of the text message
  const otp = sms.content.match(/^[\s\S]*otp=([0-9]{6})[\s\S]*$/m)[1];
}

When the browser detects the message(currently it imposes a few restrictions on the message format), it displays a bottom sheet with the OTP and verify button as shown in the video below.

This is based on the demo which the Chrome team has published on Glitch

This feature is currently under Origin Trial but you can test it locally by enabling the relevant flags in Chrome Beta.

Limitations

Since navigator.sms.receive() returns a promise there is no way to abort/cancel the request. If the user navigates away from the login page, then he might see the bottomsheet. There is no way to set a message timeout either. There is an open github issue for this and I think they are planning to resolve this soon.

The text message format is kind of restrictive at the moment, but they are working on it. Here is an example message

Your OTP is: 123456. This is only valid for 10 minutes. Do not share it with anybody else

For: https://sms-receiver-demo.glitch.me/?otp=123456&xFJnfg75+8v

The message should include a line just like the last line in the example message. It should contain

  1. The origin of URL of the website which invoked the API, preceded by For :. There is no localization support at this point.
  2. URL must contain the hash of the user’s chrome instance as a query parameter. This is a static string, xFJnfg75+8v for Chrome Beta and EvsSSj4C6vl for Chrome Beta. The web.dev article mentions that this is just for the time being.
  3. The URL must contain otp query parameter with its value being the OTP value.

Final thoughts

It was lot of fun experimenting with this API. The inability to abort is a major limitation, but this seems to be in the pipeline. I think this API certainly improves user experience for OTP based login flows. I am excited to see how this evolves. Kudos to the Chrome team for coming up with this.