Create Simple Crypto Bot with Twilio
Tags: twilio, cryptocurrency, python, poetry
Published: 2021-05-28 12:38:08

In this post, I'll show you how to create a super simple crypto bot with Twilio API and cryptocompare python package.

I'm using `poetry` for a python project but it's not necessary to use it. What you need is to have python3 and pip.

[Requirements]
- Twilio developer account and active phone number
- python3
- pip
- ngrok (https://ngrok.com/download)
- mobile phone to send a message


### Step 1 Get a phone number
When you login and access to console page(https://console.twilio.com/?frameUrl=/console), you will see the side menu on the page.

Then click `Active numbers`. If you have a phone number/phone numbers, the page shows a number/numbers you have.
If you don't have a number, you will need to get one number.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sy3tgbia6jqo25oj97so.png)

### Step 2 Create a project
As I mentioned, I use `Poetry` to create a python project because it allows us to manage a python project as well as a project that is made by `yarn` or `npm` (like js project).

https://python-poetry.org/

```zsh
$poetry new twilio_crypto_bot
$cd twilio_crypto_bot
# install packages like yarn add packageName
$poetry add twilio flask requests cryptocompare 
```

without `Poetry`
```zsh
$mkdir twilio_crypto_bot
$cd twilio_crypto_bot
$pip install twilio flask requests cryptocompare
```

app.py: main python script
CryptoPrice.py: get cryptocurrency price via cryptocompare pypi package  

```zsh
$ touch app.py CryptoPrice.py
```


### Step 3 Write code
Finally, it's time to code to build a simple bot with Twilio API.

The codes are very simple.
Create a router with Flask. In this case, the path is `/sms` and it will be used for `Webhook`.

When a user sends a message to the active number, `sms_reply` function is called.
For example, the user send `price btc`
First, the function receives 'price btc' as `incoming_msg`.
If incoming_message includes `price`, the function convert it into `BTC` then create a CryptoPrice instance with `BTC` to get the current price.
Before sending back the message check the return from CryptoPrice's method. If the return is only numeric(technically type is str but the return includes only numbers + .), return True which means the method returns the current price. Otherwise, the bot will send an error message.

`app.py`
```python
from flask import Flask, request, redirect
from twilio.twiml.messaging_response import MessagingResponse
import CryptoPrice
import requests
import re

app = Flask(__name__)


def check_numeric(s: str):
    pattern = r"^[+-]?[0-9]*[.]?[0-9]+$"
    return (re.match(pattern, s) is not None)


@app.route('/sms', methods=['GET', 'POST'])
def sms_reply():
    incoming_msg = request.values.get('Body', '').lower()
    resp = MessagingResponse()
    msg = resp.message()
    responded = False
    # print(incoming_msg)

    if 'price' in incoming_msg:
        # return cryptocurrency price
        crypto = incoming_msg.replace('price', '').strip().upper()
        cc = CryptoPrice.Crypto(crypto)
        crypto_price = str(cc.get_crypto_price())
        # print(crypto_price)

        if not check_numeric(crypto_price):
            response = crypto_price
        else:
            response = f"the current price of {crypto} is ${crypto_price} from cryptocompare"
        print(response)
        msg.body(response)
        responded = True

    if not responded:
        msg.body('what do you want to know about cryptocurrencies?')

    # print(str(resp))
    return str(resp)


if __name__ == '__main__':
    app.run(debug=True)
```

`CryptoPrice.py`
```python
import cryptocompare


class Crypto():
    def __init__(self, crypto_symbol):
        self.crypto_symbol = crypto_symbol

    def get_crypto_price(self):
        result = cryptocompare.get_price(self.crypto_symbol, currency='USD')
        try:
            return result[self.crypto_symbol]['USD']
        except TypeError as error:
            return 'There is not a coin pair for {}-USD.'.format(self.crypto_symbol)


def main():
    test = 'KOJI'
    cc = Crypto(test)

    val = cc.get_crypto_price()
    print(val)


if __name__ == '__main__':
    main()
```

### Step 4 Set Webhook
We are almost there. But need one more step to make the bot work since currently the bot cannot recognize that a user sends a message or not. To solve this, we need to set Webhook.

There are 3 steps to finish this.
First step is to run `app.py`.

```zsh
# with poetry
$ poetry run python app.py

# without poetry
$ python app.py
```
Then we need to use ngrok which we stored in the project folder.

```zsh
$./ngrok http 5000
```

If your app.py and ngrok work properly, you will see something like this.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/icmgic3imgyv1b4xqa21.png)

Then copy `https` address that ngrok shows you.
Access your Twilio console and Phone Numbers > Manage > Active Numbers and click a number you want to user for this bot.

If the console page is switched, scroll down and find out `Webhook`(placed the bottom)

Fill out your `https` url like below and click `Save` botton.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ftm8h8t8xahyqzo069pq.png)


### Step 5 Send a message to a bot
Now we are good to go.
Open sms application on your smartphone and send a message to the active number. As you notice, this is very simple bot, so the message must be the following.

[Format]
`price cryptocurrency_symbol`
`cryptocurrency_symbol price`

Example
`price btc`
`eth price`

If you send a message without `price`, the bot returns `what do you want to know about cryptocurrencies?`

Also if you pass non-existing crypto symbol, the bot returns `There is not a coin pair for crypto_symbol-USD.`

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8lk02e1h7wy4fiotnsj7.jpeg)



What you can do may be the followings.
- add a new commands For example, alert functionality
If you send `alert eth > 3000`, the bot will send an alert when the price reaches the range.

- introduce NLP functionality which means your bot can understand natural message from you. For instance, `hey I want to know the current bitcoin price.`

- Use another API and check up/down then send a funny image/gif. Twilio supports .gif, .jpg, and .png as media.

- Also you can set scheduled messages with crypto_symbol.


#### repo for this
{% github koji/Cryptocurrency_Twilio_Bot %}


#### Hopefully, you like this!

Another Twilio Bot
{%link https://dev.to/kojikanao/build-a-birthday-bot-with-twilio-and-spreadsheet-33a6 %}

<a href="https://www.buymeacoffee.com/koji"><img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kA3wM6t6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.buymeacoffee.com/buttons/default-red.png" alt="Buy Me A Coffee" height="41" width="174" loading="lazy"></a>