Forums

New here, new to python. Telegram bot - I need a lot of help with telepot - index out of range and more

First things first:

import sys
import time
import telepot
from telepot.loop import MessageLoop
from telepot.namedtuple import InlineKeyboardMarkup, InlineKeyboardButton

def on_chat_message(msg):
    content_type, chat_type, chat_id = telepot.glance(msg)

    keyboard = InlineKeyboardMarkup(inline_keyboard=[
                   [InlineKeyboardButton(text='Press me', callback_data='press')],
               ])

    bot.sendMessage(chat_id, 'Use inline keyboard', reply_markup=keyboard)

def on_callback_query(msg):
    query_id, from_id, query_data = telepot.glance(msg, flavor='callback_query')
    print('Callback Query:', query_id, from_id, query_data)

    bot.answerCallbackQuery(query_id, text='Got it')

TOKEN = sys.argv[1]  # get token from command-line

bot = telepot.Bot(TOKEN)
MessageLoop(bot, {'chat': on_chat_message,
                  'callback_query': on_callback_query}).run_as_thread()
print('Listening ...')

while 1:
    time.sleep(10)

This is coming from this website: https://telepot.readthedocs.io/en/latest/#custom-keyboard-and-inline-keyboard. I literally copied and pasted that into python anywhere. Whenever I run it, I get an error on TOKEN because sys is throwing some kind of error? I'm SO confused about all of this! Any help is appreciated. I want to continue building a bot on pythonanywhere! You'll notice that I have the free bot code not here - I tried it with and without it, still getting an error on TOKEN and sys. Please help! I want to learn! I want to build!

Could you post the exact exception trace that you're getting, and the command line you're using to run the script?

Yes! I will edit this reply in about one hour!

What do you mean by which command line? Like which version of Python? If so, it's 3.5.

giles: Could you post the exact exception trace that you're getting, and the command line you're using to run the script?

Traceback (most recent call last):
  File "/home/guapogi/acked_bot.py", line 22, in <module>
    TOKEN = sys.argv[1]  # get token from command-line
IndexError: list index out of range

All I do to run the code above is hit "run" in the upper right hand corner. What prints on the console before the traceback errors: Loading console...

Preparing execution environment... OK
Main screen turn on... OK
Loading Python3.5 interpreter...

I hope that's everything you needed to know! Thanks giles!

Ah, got it. That script expects to be passed command-line parameters -- that is, it expects you to start a Bash console, then run it by executing the command

python3.6 acked_bot.py SOMETHING

...where the "SOMETHING" is the API token you got from Telegram when you created your bot using the Botfather. Because you're running it from inside the editor, there's nothing passed in on the command line for the token, which means that the list sys.argv (which holds command line parameters) doesn't have an element at index 1 -- hence the error.

So, to run it, either start a bash console and run it as above, or modify the code to replace

TOKEN = sys.argv[1]  # get token from command-line

with this:

TOKEN = "API-TOKEN-VALUE"

...replacing API-TOKEN-VALUE with the real API token.

So, to run it, either start a bash console and run it as above, or modify the code to replace

TOKEN = sys.argv[1] # get token from command-line with this:

TOKEN = "API-TOKEN-VALUE" ...replacing API-TOKEN-VALUE with the real API token.

This is what I was missing! I knew I was close, haha. I took code from the flask example

bot = b.soemthing('token') but it wasn't working. Thanks a ton, giles!! You duh bomb!

New issue @giles!

import urllib3
import time
import telepot
from telepot.loop import MessageLoop
from telepot.namedtuple import InlineKeyboardMarkup, InlineKeyboardButton

# You can leave this bit out if you're using a paid PythonAnywhere account
proxy_url = "http://proxy.server:3128"
telepot.api._pools = {
    'default': urllib3.ProxyManager(proxy_url=proxy_url, num_pools=3, maxsize=10, retries=False, timeout=30),
}
telepot.api._onetime_pool_spec = (urllib3.ProxyManager, dict(proxy_url=proxy_url, num_pools=1, maxsize=1, retries=False, timeout=30))
# end of the stuff that's only needed for free accounts

def on_chat_message(msg):
    content_type, chat_type, chat_id = telepot.glance(msg)

    keyboard = InlineKeyboardMarkup(inline_keyboard=[
                   [InlineKeyboardButton(text='Press me', callback_data='press')],
               ])

    bot.sendMessage(chat_id, 'Use inline keyboard', reply_markup=keyboard)

def on_callback_query(msg):
    query_id, from_id, query_data = telepot.glance(msg, flavor='callback_query')
    print('Callback Query:', query_id, from_id, query_data)

    bot.answerCallbackQuery(query_id, text='Got it')

TOKEN = "token from botfather"  # get token from command-line

bot = telepot.Bot(TOKEN)
MessageLoop(bot, {'chat': on_chat_message,
                  'callback_query': on_callback_query}).run_as_thread()
print('Listening ...')

while 1:
    time.sleep(10)

I run this now and I get these errors before I even get to do anything in Telegram:

Listening ...
Traceback (most recent call last):
  File "/home/guapogi/.local/lib/python3.5/site-packages/telepot/loop.py", line 54, in run_forever
    allowed_updates=allowed_upd)
  File "/home/guapogi/.local/lib/python3.5/site-packages/telepot/__init__.py", line 876, in getUpdates
    return self._api_request('getUpdates', _rectify(p))
  File "/home/guapogi/.local/lib/python3.5/site-packages/telepot/__init__.py", line 434, in _api_request
    return api.request((self._token, method, params, files), **kwargs)
  File "/home/guapogi/.local/lib/python3.5/site-packages/telepot/api.py", line 131, in request
    return _parse(r)
  File "/home/guapogi/.local/lib/python3.5/site-packages/telepot/api.py", line 126, in _parse
    raise exception.TelegramError(description, error_code, data)
telepot.exception.TelegramError: ("Conflict: can't use getUpdates method while webhook is active", 409, {'description': "Conflict: can't use getUpdates method while webhook is activ
e", 'error_code': 409, 'ok': False})
Traceback (most recent call last):

These errors just continue on and on and on. Any ideas?

That error is caused if you try to start a non-webhook-based Telegram bot while you have a webhook-based one running. Do you have one set up (perhaps one on the "Web" tab, created from our tutorial)? If so, you need to delete it first. Or, alternatively, if you want to keep that one, you need to create a new bot using the Botfather, and use one for the webhook-based bot, and one for the console-based one.

A quick word of warning about using non-webhook bots on PythonAnywhere, though -- when you run something from a console, it's not guaranteed to keep running forever. So your bot won't necessarily stay up and running all the time if you don't use a webhook-based one.

So in your opinion - I should have it be webhook based if I want it to be running permanently? I'm willing to start at least the lowest tier payment account. You have been so nice and helpful, that alone is convincing enough for me to go back to a paying account and to keep on developing.

Do I need to change the code at all or just delete my console based bot code/file and focus all the code into the webhook/web directory files?

As always, thanks giles.

BIG Edit: I deleted my console based bot files and moved soley to the web directory. I'm still getting a webhook error with getupdates even though I have no consoles open for a console based bot. I also got rid of the free account code with the proxy server or whatever since I have the low tier paid account now. Here is my current code:

from flask import Flask, request
import time
import telepot
from telepot.loop import MessageLoop
from telepot.namedtuple import InlineKeyboardMarkup, InlineKeyboardButton

secret = "8008"
bot = telepot.Bot('botfather token')
bot.setWebhook("https://guapogi.pythonanywhere.com/{}".format(secret), max_connections=1)

app = Flask(__name__)

@app.route('/{}'.format(secret), methods=["POST"])
def telegram_webhook():
    update = request.get_json()
    if "message" in update:
        text = update["message"]["text"]
        chat_id = update["message"]["chat"]["id"]
        bot.sendMessage(chat_id, "From the web: you said '{}'".format(text))
    return "OK"

def on_chat_message(msg):
    content_type, chat_type, chat_id = telepot.glance(msg)

    keyboard = InlineKeyboardMarkup(inline_keyboard=[
                   [InlineKeyboardButton(text='Press me', callback_data='press')],
               ])

    bot.sendMessage(chat_id, 'Use inline keyboard', reply_markup=keyboard)

def on_callback_query(msg):
    query_id, from_id, query_data = telepot.glance(msg, flavor='callback_query')
    print('Callback Query:', query_id, from_id, query_data)

    bot.answerCallbackQuery(query_id, text='Got it')

TOKEN = "botfather token" #set token to botfather token

bot = telepot.Bot(TOKEN)
MessageLoop(bot, {'chat': on_chat_message,
                  'callback_query': on_callback_query}).run_as_thread()
print('Listening ...')

while 1:
    time.sleep(10)

I thought I needed to add a Flask app to run it on the website or something. Mind you I don't know what I was doing or if this stuff will even work together. facepalm

Big edit #2:

Current code. No errors, but this doesn't even return a message when I talk to the bot anymore:

from flask import Flask, request
import time
import telepot
#from telepot.loop import MessageLoop
#from telepot.namedtuple import InlineKeyboardMarkup, InlineKeyboardButton

secret = "8008"
bot = telepot.Bot('botfather token')
bot.setWebhook("https://guapogi.pythonanywhere.com/{}".format(secret), max_connections=1)

app = Flask(__name__)

@app.route('/{}'.format(secret), methods=["POST"])
def telegram_webhook():
    update = request.get_json()
    if "message" in update:
        text = update["message"]["text"]
        chat_id = update["message"]["chat"]["id"]
        bot.sendMessage(chat_id, "From the web: you said '{}'".format(text))
    return "OK"
"""
def on_chat_message(msg):
    content_type, chat_type, chat_id = telepot.glance(msg)

    keyboard = InlineKeyboardMarkup(inline_keyboard=[
                   [InlineKeyboardButton(text='Press me', callback_data='press')],
               ])

    bot.sendMessage(chat_id, 'Use inline keyboard', reply_markup=keyboard)

def on_callback_query(msg):
    query_id, from_id, query_data = telepot.glance(msg, flavor='callback_query')
    print('Callback Query:', query_id, from_id, query_data)

    bot.answerCallbackQuery(query_id, text='Got it')

TOKEN = "botfather token" #set token to botfather token

bot = telepot.Bot(TOKEN)
MessageLoop(bot, {'chat': on_chat_message,
                  'callback_query': on_callback_query}).run_as_thread()
                  """
print('Listening ...')

while 1:
    time.sleep(10)

Apologies for being such a bother. Just want it to work lol

I can't see the usefulness of the while loop at the end and it certainly can't be helping. See the tutorial here: https://blog.pythonanywhere.com/148/ for a fully working bot (particularly the section about moving to webhooks)

It's funny that you mention that! I actually took everything out last night and copy + pasted JUST the webhook code. I tried commenting out the "free account code" and I'm about to try leaving it in. Will update in a sec.

Edit: Still not working :(

I tried what I mentioned above, with and without the free account code to run things on the web. I saved, reloaded my web app, tried sending a message and no reply. I tried hitting "run" and still nothing.

My last attempt will be to delete this bot and start over. Maybe something got messed up down the road. Dang it.

Maybe it's worth starting from scratch and just going through the tutorial step-by-step so that you get something that definitely works, then adding any extra features you like onto that one-by-one?

Maybe it's worth starting from scratch and just going through the tutorial step-by-step so that you get something that definitely works, then adding any extra features you like onto that one-by-one?

That's my plan today. Thanks as always, giles.

Sweet! Redid everything and I have a working bot right now. I don't know how to implement a keyboard. Is this a good place to start? http://telepot.readthedocs.io/en/latest/#id12

If that's the telepot documentation on how to implement a keyboard, then I guess it's a good place.