2
\$\begingroup\$

Telegram Bot that retrieves book information from GoodReads

I've created a Telegram bot that implements the inline/offline modes to get the brief info about a book, searched by title(inline mode) or with command /random. The data is retrieved from GoodReads. I was wondering how can I modify the body of 'description', so that I would be able to add here that rating info and name of the author? The "idea" of the interpretation is as an example of IMDB's bot

enter image description here

The GoodReads client

import goodreads
from goodreads import client
import random

client_key = '[redacted']
client_secret = '[redacted']

gc = client.GoodreadsClient(client_key, client_secret)

def parse_book(book):
    return {
        'title': book_data.title,
        'author': book_data.authors[0],
        'rating': book_data.rating,
        'review': book_data.review,
        'cover': book_data.image_url,
        'link': book_data.link
    }

  def book_info(title):
      books = gc.search_books(str(title), page=1, search_field='all')

      return map(parse_book, books)

  def random_book():
      index = random.randint(1, 1000000)
      book = gc.book(index)

      return parse_book(book)

The Telegram Bot implementation

import telebot
from telebot import types
import gd

token = '[redacted']
bot = telebot.TeleBot(token)


@bot.message_handler(commands=['start'])  # greeting
def send_welcome(message):
    bot.reply_to(message.chat.id, "Hi! How are you?")

@bot.message_handler(commands=['help'])  # command list
def send_welcome(message):
    bot.reply_to(message.chat.id, "This bot can do: ")

@bot.message_handler(commands=['random']) # /random
def random(message):
    book = random_book()
    text = "Some text"
    bot.send_message(message.chat.id, text, disable_web_page_preview=False) 

@bot.inline_handler(lambda query: query.query == 'text')  # inline session
def query_text(query):
    raise Http404("Poll does not exist")
    book_req = book_info(query)
    try:
        result = []
        i = 0
        for book in book_req:
            result.append(types.InlineQueryResultArticle(id=i, 
                title=book[i]['title'],
                url=book[i]['link'],
                hide_url=True,
                description=book[i]['review'],
                thumb_url=book[i]['cover'], thumb_width=48, thumb_height=48
                ))
            i += 1
        bot.answer_inline_query(query.id, result)
    except Exception as e:
        print("{!s}\n{!s}".format(type(e), str(e)))

def main_loop():
    bot.polling(True)
    while 1:
        time.sleep(3)

if __name__ == '__main__':
    try:
        main_loop()
    except KeyboardInterrupt:
        print >> sys.stderr, '\nExiting by user request.\n'
        sys.exit(0)
\$\endgroup\$
  • 2
    \$\begingroup\$ this seems to be a follow up to your previous question, you should have a link to the previous question. You still put your client secret and key. \$\endgroup\$ – Bruno Costa Oct 26 '16 at 7:54
  • 4
    \$\begingroup\$ I edited them out, but just as with your previous question, they are still visible in the revision history, so you should immediately change them (again?)!!! \$\endgroup\$ – Graipher Oct 26 '16 at 8:06
  • \$\begingroup\$ I have requested redaction of the revision history. Awaiting another moderator's approval. \$\endgroup\$ – Simon Forsberg Oct 26 '16 at 12:46
1
\$\begingroup\$

gc is the name of the Garbage Collection interface module. It shouldn't matter too much, but, when reading your code, it feels like that you are asking the garbage collector to find books and then I remind myself that it isn't actually the garbage collector.

index = random.randint(1, 1000000)

This was mentioned in the last post. Even if you can't find the specific number you need, you should at least assign 1000000 to some variable something like MAX_BOOK_NO so the meaning of such a number is more obvious.

    i = 0
    for book in book_req:
    ...
        i += 1

This is simplified with enumerate:

    for i, book in enumerate(book_req):
    ...
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.