Imagine the convenience of having an intelligent, ever-evolving virtual assistant at your fingertips, designed to make your life easier and more efficient. Don’t miss out on this technological revolution – experience the power of ChatGPT and witness your daily routine transform like never before!

Today I will guide you through the process of creating a Telegram bot that harnesses the power of ChatGPT APIs to deliver impressive conversational capabilities. Whether you’re a developer looking to expand your chatbot’s functionalities or simply someone interested in exploring the potential of AI-assisted communication, this tutorial is perfect for you.

By the end of this post, you will have a thorough understanding of how to set up a ChatGPT-powered Telegram bot, enabling you to engage your users with more natural and human-like interactions. So, let’s dive in and start leveraging the capabilities of OpenAI’s ChatGPT and Telegram’s Bot API for an exceptional chatbot experience!

Before we start

Before we begin, we need to generate the necessary keys to be able to use OpenAI’s APIs, which will allow us to interact with ChatGPT, as well as those that will enable us to register our Telegram bot.

Generate an API Key on the OpenAI portal

OpenAI has created a platform that offers well-organized and succinct documentation for developers, covering the accessible APIs. The first step is to access the portal and create an account, which can be done at the following url: https://platform.openai.com/docs/api-reference.

Once we are logged in, we would need to go to our personal section and:

Create a new organization and obtain the organization ID

Generate an API Key for that organization

Now that you have your OpenAI API key and organization ID, you can start integrating it into your projects and explore the wide range of possibilities offered by OpenAI’s powerful platform.

Remember to store those values in a safe place and do not share them with anyone else.

Register your Telegram Bot using Bot Father

To utilize Telegram bots, a token is necessary. Acquiring a token is quite simple using the @BotFather bot. Begin by initiating a conversation with the bot and inputting the command /newbot. The BotFather will then prompt you with a series of questions, such as the name of your new bot. Upon completion, a token will be generated for you.

You can visit the official Telegram documentation for more detail about how to obtain a token.

Remember to keep your bot’s token secure and not to share it with anyone.

Let’s code!

It’s time to start building our bot. Since we want to be able to send messages to Chat-GPT and get the responses back in our Telegram conversation, first thing we have to do is to identify the endpoint that we should call.

If we review OpenAI official documentation, we will find the following endpoint:

#POST https://api.openai.com/v1/chat/completions

Request:
{
  "model": "gpt-3.5-turbo",
  "messages": [{"role": "user", "content": "Hello!"}]
}

Response:
{
  "id": "chatcmpl-123",
  "object": "chat.completion",
  "created": 1677652288,
  "choices": [{
    "index": 0,
    "message": {
      "role": "assistant",
      "content": "\n\nHello there, how may I assist you today?",
    },
    "finish_reason": "stop"
  }],
  "usage": {
    "prompt_tokens": 9,
    "completion_tokens": 12,
    "total_tokens": 21
  }
}

This looks like the right one to use the chat, so let’s code it. We can perform http requests as in the example above, but OpenAI provides a library written in Python that we can install and will make this much easier:

pip install openai

Now, the Python code to perform this call will look like this:

import openai

# Do not forget to configure your keys
openai.organization = YOUR_OPENAI_ORG
openai.api_key = YOUR_OPENAI_KEY

def send_message(message):
    """Send a message to Chat-GPT for completion

        This is the basic functionality that sends a message to Chat-GPT and 
        expects a response to start a new conversation

        Args:
            message (srt): The message to send

        Returns:
            str: The completion message returned by Chat-GPT
    """
    response = openai.ChatCompletion.create(
        #model="gpt-4",
        model="gpt-3.5-turbo",
        temperature=0.8,
        messages=[
            {"role": "user", "content": message}
        ]
    )
    return response['choices'][0]['message']['content']

This function receives the message that we want to send, sends it to ChatGPT and returns the answer.

Next step is to use Telegram APIs so that we connect our chat with this function. For this, I’m using the library python-telegram-bot as in my opinion it’s one of the easiest ones and it’s very good documented, but there are many more!

pip install python-telegram-bot --upgrade

Telegram bots use handlers to trigger actions and we can basically differentiate between two types:

  • CommandHandler: Actions defined by the programmer that will be available for end users. These are the ones that are triggered with «/», for instance /say-hello.
  • MessageHandler: Actions defined by the programmer to react based on the message sent by the user. For instance, we can tell the bot to do a different action if the user sends a message or if the user sends a picture. These MessageHandler will filter the messages and detect what action should be triggered.

Once said this, to start with a first version of our bot, we will need a CommandHandler with he command /start that usually starts the bot and sends a welcome message to the user, and a MessageHandler that sends every text message sent by the user to Chat GPT using the function we developed before.

  def start_bot():
      application = ApplicationBuilder().token(YOUR_TOKEN).build()

      application.add_handler(CommandHandler('start', start))
      application.add_handler(MessageHandler(filters.TEXT & (~filters.COMMAND), echo))

      application.run_polling()
  
  async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
    user = update.message.from_user
    await context.bot.send_message(
        chat_id=update.effective_chat.id,
        text="""
            Hey {}, this is Chat GPT! \n\nI'm a bot powered with the most advanced artificial intelligence available. \n\nHow can I help you?
        """.format(user.first_name)
    )
            
  async def echo(update: Update, context: ContextTypes.DEFAULT_TYPE):
      response = send_message(message=update.message.text)
      await context.bot.send_message(chat_id=update.effective_chat.id, text=response)

Now let’s start the program and see if it’s working:

This looks amazing! Our bot is already sending our text messages to Chat GPT and receiving its responses successfully.

Little improvements that make the difference

So far, we have the ability to transmit messages to Chat GPT and receive replies straight from our Telegram conversation, awesome! The higher the quality of our prompts, the more impressive the response will turn out.

Speech to text

Now we can combine the features offered by Telegram chats with the capabilities of Chat GPT. Wouldn’t it be wonderful to be able to send voice audios, and have Chat GPT respond as if it were a text message? Well, this is possible thanks to its speechToText capability, so let’s get to work and give our bot this ability!

Telegram’s voice messages have the *.ogg extension, which is not supported by OpenAI APIs. However, this is not a concern since Python offers various libraries to handle audio format conversions. To accomplish this, we will use AudioSegment to convert the voice note to mp3 and store it temporarily in a local folder before we send it to Chat GPT.

Finally, the code will appear as follows:

from pydub import AudioSegment

async def speech_to_text(update: Update, context: CallbackContext):
    voice_file = await context.bot.getFile(update.message.voice.file_id)
    voice_file_mp3 = await _read_and_convert_voice_message(voice_file, 'mp3')
    transcript = openai.speech_to_text(voice_file_mp3)
    answer_chat_gpt = openai.send_message(transcript)
    await context.bot.send_message(chat_id=update.effective_chat.id, text=answer_chat_gpt)
    
async def _read_and_convert_voice_message(self, voice_file_id: str, dest_format: str):
    try:
        os.makedirs("./tmp")
    except FileExistsError:
        # directory already exists
        pass
    await voice_file_id.download_to_drive('./tmp/voice_message.ogg')
    voice_file_ogg = AudioSegment.from_ogg('./tmp/voice_message.ogg')
    voice_file_ogg.export(
        './tmp/voice_message.{}'.format(dest_format), format=dest_format)
    return open('./tmp/voice_message.{}'.format(dest_format), 'rb')

Improving feedback

Before we test this, there is another feature we could implement very easily. If you have used Chat GPT previously, you probably have noticed that depending on the prompt, sometimes it takes a few seconds to answer. In this project, we will be waiting looking at our telegram chat and it would be nice to get some feedback while we are waiting for the response.

Chats usually provide a function that allow the user to see if the person/bot on the other side is typing, sending pictures, voice messages etc… We can implement it to simulate that Chat GPT is typing while we wait for the answer.

@send_action(ChatAction.TYPING)
async def echo(update: Update, context: ContextTypes.DEFAULT_TYPE):
    response = openai.send_message(message=update.message.text)
    await context.bot.send_message(chat_id=update.effective_chat.id, text=response)
    
def send_action(action):
    """Sends typing action while processing func command."""
    def decorator(func):
        @wraps(func)
        async def command_func(update, context, *args, **kwargs):
            await context.bot.send_chat_action(chat_id=update.effective_message.chat_id, action=action)
            return await func(update, context,  *args, **kwargs)
        return command_func

    return decorator

As you can see I created my own decorator for this, as I think this is a very clean way to reuse this functionality in our bot.

Now, let’s put all pieces together and test it! When we send a voice note to our bot, it should first display that it’s typing and then answer to our question or messages:

And that’s it! Now we will receive instant feedback from our bot when we send messages and we will know if it is still «thinking» or if an error has occurred in the process.

Summary

In this blog post, I walked through the process of creating a Telegram bot in Python that interacts with chat GPT using OpenAI APIs. I provided step-by-step instructions and code snippets to help readers follow along. The bot allows users to have conversations with the chat GPT AI, who responds in a natural language format. This is just the beginning of what we can do with chatbots and AI, and I can’t wait to share more in my upcoming blog posts.

This has been a basic demonstration of the functionalities that we can implement. In my Github repository, you will see a better-structured example source code with some surprises implemented, such as generating images based on input text using Dall-E!! I would appreciate it if you could follow me and give the repository a like if you stop by 🙂.

Stay tuned for more exciting developments!