DEV Community

Cover image for Sending Dollar Quotes via a Telegram Bot
Everton Tenorio
Everton Tenorio

Posted on • Edited on

Sending Dollar Quotes via a Telegram Bot

Objective: Demonstrate the possibility of automating tasks that generate information using APIs and Shell Script.

Recently, I saw someone comment about a quotation API that does not require authentication and returns real-time data for free.

An API like this greatly facilitates the work of those who need these values for a project. Here, I easily demonstrate how to get the current dollar exchange rate via Telegram by requesting the quotation API.


Bot Configurations

The first step is to have the bot configurations, the TOKEN, and the chat ID (chat_id) where the interaction will take place. The Telegram bot API documentation provides more details explaining how to perform this step. Basically, you need the bot's TOKEN created in BotFather and the chat_id, which can be found by accessing https://api.telegram.org/bot<TOKEN>/getUpdates.


Function to Send Messages

In the documentation, methods of the Telegram API that can be used are listed, such as sendMessage(). In the script, it is a function that will send messages to the user using HTML formatting.

%20 (space) and %0A (\n) are escape sequences used to represent special characters in URLs.

Check Messages Received by the User

jq is a command-line tool used to process, analyze, and manipulate JSON data. We can filter, map, reduce, transform, and format JSON data in the terminal.

apt-get install -y jq
Enter fullscreen mode Exit fullscreen mode

It will be used to filter the JSON structure for the last message sent by the user, and if that message is "dollar" the current value of the dollar in reais will be returned via sendMessage.

The function getLastUserMessageId() will have the ID of the last message sent by the user to differentiate the moment when the user sent the word "dollar" to the bot.


Code

#!/bin/bash

echo "Cotação do Dólar americano para Real Brasileiro"

# Bot Configs.
TOKEN=''
CHAT_ID=''

# Variable to store the ID of the user's last message
last_user_message_id=""

# Function that sends a message to Telegram
sendMessage() {
    curl -s -X POST \
        https://api.telegram.org/bot$TKN/sendMessage \
        -d chat_id=$CHAT_ID \
        -d text="$1" \
        -d parse_mode=HTML
}

# Function to get the ID of the last user message
getLastUserMessageId() {
    echo "$1" | jq -r '.result[-1].message.message_id'
}

# Loop to receive bot updates
while true; do
    # Getting updates
    UPDATES=$(curl -s "https://api.telegram.org/bot$TKN/getUpdates")

    # Check the JSON for received messages
    MESSAGE=$(echo "$UPDATES" | jq -r '.result[-1].message.text')
    USER_ID=$(echo "$UPDATES" | jq -r '.result[-1].message.from.id')
    MESSAGE_ID=$(getLastUserMessageId "$UPDATES")

    # If the last message is "dólar" and it's a new interaction from the user...
    if [[ "$MESSAGE" == "dólar" ]] && [[ "$MESSAGE_ID" != "$last_user_message_id" ]]; then
        response=$(curl -s "https://economia.awesomeapi.com.br/json/last/USD-BRL")

        # Translate the keys to Portuguese
        declare -A traducoes=(
          ["bid"]="Compra"
          ["ask"]="Venda"
          ["varBid"]="Variação"
          ["pctChange"]="Porcentagem de Variação"
          ["high"]="Máximo"
          ["low"]="Mínimo"
        )

        # Display the values for each translated key
        valores=()
        for chave in "${!traducoes[@]}"; do
            valor=$(echo "$response" | jq -r ".USDBRL[\"$chave\"]")
            valores+=("<b>${traducoes[$chave]}</b>:  $valor bn")
        done

        # Using sed to replace characters that are not interpreted in the message (POST) sent to the user
        sendMessage $(echo -e "💵 DÓLAR - REAL%0A${valores[@]}" | sed 's/ /%20/g; s/bn%20/%0A/g; s/bn//g')

        # Store the ID of the user's last message
        last_user_message_id="$MESSAGE_ID"
    fi

    # Wait 5 seconds before checking again
    sleep 5

done
Enter fullscreen mode Exit fullscreen mode

Result

real_dolar

Top comments (0)