How to Set up Telesign for SMS in Appwrite
Tags: webdev, javascript, appwrite, nextjs
Published: 2023-09-12 13:25:11

Improving user engagement and interaction in web applications is crucial, and seamless communication is key. In today's interconnected digital world, SMS is still a powerful way to reach users quickly and efficiently. Incorporating this strong communication tool into a web application powered by Appwrite is easy.

In this article, we will discover the process of authenticating users through their phone numbers with the help of Appwrite's phone authentication APIs and Telesign. Find the project repository [here](https://github.com/Olanetsoft/setup-telesign-for-sms-in-appwrite).


## Technology Overview

[Telesign](https://www.telesign.com/?utm_source=hackmamba&utm_medium=hackmamba-blog) is an identity and customer engagement solution that provides sets of APIs for registering and verifying users using SMS, Voice, and phone number intelligence.


## Prerequisites

To fully grasp the concepts presented in this tutorial, the following are required:

- Basic understanding of JavaScript and React
- Docker installed
- Telesign [account](https://portal.telesign.com/signup?utm_source=hackmamba&utm_medium=hackmamba-blog)


## Getting started

To create a Next.js starter project, we should first navigate to the desired directory and run the command below in our terminal.

```bash
    npx create-next-app@latest setup-telesign-for-sms-in-appwrite && cd setup-telesign-for-sms-in-appwrite
```

After running the command, we will be prompted to answer sets of questions. We can do so as shown below:


    Would you like to use TypeScript? <No>
    Would you like to use ESLint? <No> 
    Would you like to use Tailwind CSS? <Yes>
    Would you like to use `src/` directory? <Yes>
    Would you like to use App Router? (recommended) <Yes>
    Would you like to customize the default import alias? <Yes>
    What import alias would you like configured? @/* <Press Enter>

The command creates a Next.js project called `next_telesign` and navigates into the project directory.

Next, we need to add Appwrite as a dependency. To do this, run the command below:

```bash
    npm install appwrite
```

## Set up Telesign as an SMS provider

Let's begin by logging in to our Telesign portal and making sure to save the `Customer ID` and `API Keys.`


![Copy customer ID and API key on Telesign dashboard](https://paper-attachments.dropboxusercontent.com/s_FB5164F66C28F1E6D20D2FD8A79E9914531452C73044C880AB9366151B6EBAF1_1691014986917_Screenshot+2023-07-28+at+21.45.43.png)


Lastly, we need to create and verify a test number. Any number we configure and verify here can receive SMS. To do this, we need to navigate to the `**Manage test numbers**` screen.


![Manage test numbers](https://paper-attachments.dropboxusercontent.com/s_5AE13241508A7E6925D3E7C46F98F97DA032E1B5D4814111659BD6450C922200_1691151291583_CDGHDA68.jpg)


Click the `**Add a Number**` button, input the required details, `**Submit**`, and `**Verify**`.

![Add a number](https://paper-attachments.dropboxusercontent.com/s_FB5164F66C28F1E6D20D2FD8A79E9914531452C73044C880AB9366151B6EBAF1_1691016119191_Screenshot+2023-07-30+at+15.47.47.png)



![Fill in the required information and verify](https://paper-attachments.dropboxusercontent.com/s_FB5164F66C28F1E6D20D2FD8A79E9914531452C73044C880AB9366151B6EBAF1_1691016119220_Screenshot+2023-07-30+at+15.49.44.png)



## Configure and create a project on Appwrite

To get started, first, we need to create an Appwrite instance in a preferred directory by running the command below:

```bash
    docker run -it --rm \
        --volume /var/run/docker.sock:/var/run/docker.sock \
        --volume "$(pwd)"/appwrite:/usr/src/code/appwrite:rw \
        --entrypoint="install" \
        appwrite/appwrite:latest
```

On creation, we should see an `appwrite` folder with two files.

![Appwrite folder](https://paper-attachments.dropboxusercontent.com/s_9813CFC6C5B2163D17C6B733CCD2F7F4E13D8D4D744ED2740D99BCB62D05C011_1690503400192_Screenshot+2023-07-27+at+00.19.24.png)


Secondly, we need to add Telesign as an SMS provider by modifying the environment variables in the `.env` file as shown below:

```bash
    _APP_SMS_PROVIDER=sms://<REPLACE WITH CREDENTIAL ID>:<REPLACE WITH API KEYS>@telesign
    _APP_SMS_FROM=<REPLACE WITH THE PHONE NUMBER WE USED IN WHEN VERIFYING TELESIGN>
```

We must also ensure that the API Key provided by Telesign is [URL encoded](https://developer.mozilla.org/en-US/docs/Glossary/Percent-encoding) because it contains non-alphanumeric characters. To do this, we can navigate to the [URLEncoder online platform](https://www.urlencoder.org/), paste our API key, click the **Encode** button, and then copy the resulting encoded format.

![Edited env variable](https://paper-attachments.dropboxusercontent.com/s_FB5164F66C28F1E6D20D2FD8A79E9914531452C73044C880AB9366151B6EBAF1_1691018362683_Screenshot+2023-07-30+at+15.18.07.png)


Lastly, we need to sync the changes we made on the `.env` file with our Appwrite server. To do this, we must run the command below inside the `appwrite` directory.

```bash
    docker-compose up -d
```

**Set up a project on Appwrite**
To get started, we need to navigate to the specified hostname and port `http://localhost:80`, log in, click the **Create project** button, input `next_telesign` as the name, and then click `**Create**`**.**


![Create project on Appwrite](https://paper-attachments.dropboxusercontent.com/s_C9210607DAFF6D80615947ED6BE237716E98BADEF0416B60FACF081B1CAEFB80_1687518026974_Screenshot+2023-06-23+at+11.38.55.png)



## Appwrite + Telesign in Next.js

Let's begin by going to our project's main directory and creating a new folder named `helper`. Inside this folder, create a file called `utils.js` and insert the code snippet provided below:

```javascript
import { Client, Account } from "appwrite";

//create client
const client = new Client();
client.setEndpoint("http://localhost/v1").setProject("REPLACE WITH PROJECT ID");

//create account
const account = new Account(client);

//authenticate user with phone number
export const phoneAuth = (phone_number) => {
  return account.createPhoneSession("unique()", phone_number);
};

//validate phone session
export const validateSMS = (userID, secret) => {
  return account.updatePhoneSession(userID, secret);
};
```

The snippet above does the following:

- Imports the required dependency.
- Uses the `Client` and `Account` class to set up an Appwrite instance by specifying the endpoint and corresponding project ID.
- Creates a `phoneAuth` and `validateSMS` function that uses the `createPhoneSession` and `updatePhoneSession` methods to create a user and validate the user using the code sent via SMS, respectively.

Secondly, we need to update the `page.js` file inside the  `app` directory to include states and methods required by our application.

```javascript
    "use client";
import Head from "next/head";
import { useState } from "react";
import { phoneAuth, validateSMS } from "../../helper/utils";

export default function Home() {
  const [value, setValue] = useState({
    phone: "",
    otp: "",
  });
  const [user, setUser] = useState(null);
  const [isPhoneVerify, setIsPhoneVerify] = useState(false);
  const [isLoading, setIsLoading] = useState(false);
  const handleChange = (e) => {
    setValue({ ...value, [e.target.name]: e.target.value });
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    setIsLoading(true);
    phoneAuth(value.phone)
      .then((res) => {
        setUser(res.userId);
        setIsPhoneVerify(true);
        setIsLoading(false);
      })
      .catch((e) => {
        alert("Error getting phone session!", e);
        setIsLoading(false);
      });
  };

  const handleValidatePhone = (e) => {
    e.preventDefault();
    setIsLoading(true);
    validateSMS(user, value.otp)
      .then((res) => {
        alert(
          `User successfully verified using for user with ID ${res.userId}, country Code ${res.countryCode}, and expires on ${res.expire}`,
        );
        setIsLoading(false);
      })
      .catch((e) => {
        alert("Error validating session!", e);
        setIsLoading(false);
      });
  };

  return (
    <div className="w-screen h-screen bg-white">
      //UI AND IMPLEMENTATION GOES HERE
    </div>
  );
}

```

The snippet above does the following:

- Imports the required dependencies
- Creates state properties to manage application state
- Creates a `handleChange` function to control inputs
- Creates a `handleSubmit` function that uses the `phoneAuth` function to create a user
- Creates a `handleValidatePhone` function that uses the `validateSMS` function to verify the created user using the secret key sent via SMS

Lastly, we need to update the UI to display forms for creating and verifying users dynamically.

```javascript
//IMPORTS GOES HERE

export default function Home() {
  //STATES AND METHOD GOES HERE

  return (
    <div className="w-screen h-screen bg-white">
      <Head>
        <title>Appwrite + Telesign </title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <main className="py-4 px-4 lg:py-10 lg:px-10 w-full">
        <div className="flex justify-center mb-8">
          <h1 className="text-2xl font-medium text-gray-700">
            Appwrite + Telesign
          </h1>
        </div>
        <section className="flex justify-center">
          {isPhoneVerify ? (
            <div className="px-4 py-2 border rounded-lg w-full lg:w-2/4">
              <div className="border-b h-8 mb-4">
                <h3 className="text-gray-700">Verify phone number</h3>
              </div>
              <form onSubmit={handleValidatePhone}>
                <fieldset>
                  <label className="text-sm text-gray-400 mb-4 block">
                    OTP
                  </label>
                  <input
                    name="otp"
                    className="border w-full rounded-sm mb-6 p-2"
                    required
                    value={value.otp}
                    onChange={handleChange}
                    type="tel"
                  />
                </fieldset>
                <button
                  className="text-sm text-white px-8 py-2 rounded-sm bg-blue-600 hover:bg-blue-700"
                  disabled={isLoading}
                >
                  Validate OTP
                </button>
              </form>
            </div>
          ) : (
            <div className="px-4 py-2 border rounded-lg w-full lg:w-2/4">
              <div className="border-b h-8 mb-4">
                <h3 className="text-gray-700">
                  Authenticate with your phone number
                </h3>
              </div>
              <form onSubmit={handleSubmit}>
                <fieldset>
                  <label className="text-sm text-gray-400 mb-4 block">
                    Phone number
                  </label>
                  <input
                    name="phone"
                    className="border w-full rounded-sm mb-6 p-2"
                    required
                    value={value.phone}
                    onChange={handleChange}
                    type="tel"
                  />
                </fieldset>
                <button
                  className="text-sm text-white px-8 py-2 rounded-sm bg-blue-600 hover:bg-blue-700"
                  disabled={isLoading}
                >
                  Submit
                </button>
              </form>
            </div>
          )}
        </section>
      </main>
    </div>
  );
}
```

Now that we have completed that task, we may begin running a development server using the following command:

```bash
    npm run dev
```
We should have something similar to what is shown below.


![How to set up Telesign for SMS in Appwrite](https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExYWI2ZmdldWY4dmlkY3VpaDBrZ2kzN3A5aTY1eTFjZnNxaHo0cTRlZSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/xpH3cBIwZgCK5i4dJE/giphy.gif)



## Conclusion

This post discussed how to set up phone authentication in Next.js using Appwrite and Telesign. With Appwrite, developers can save application development time by leveraging intuitive authentication APIs without the associated technical overheads.

These resources might also be helpful:

- [Appwrite Self-hosting configuration](https://appwrite.io/docs/configuration?utm_source=hackmamba&utm_medium=hackmamba-blog)
- [Appwrite official documentation](https://appwrite.io/docs?utm_source=hackmamba&utm_medium=hackmamba-blog)
- [Appwrite SMS provider support](https://appwrite.io/docs/sms-delivery?utm_source=hackmamba&utm_medium=hackmamba-blog)
- [Telesign official documentation](https://developer.telesign.com/enterprise/docs?utm_source=hackmamba&utm_medium=hackmamba-blog)
- [Cover image credit to iStockphoto](https://www.istockphoto.com/vector/social-media-and-digital-marketing-concept-speech-bubble-with-social-icons-vector-gm1445432493-483842928)