def __init__(self):
    self.postillon_crawler = PostillonCrawler(verbosity = BE_VERBOSE)
    self.data_manager = DataManager()
    self.last_request_id = 0

    self.start_polling_loop()
class TelegramPostillonBot:
  def __init__(self):
    self.postillon_crawler = PostillonCrawler(verbosity = BE_VERBOSE)
    self.data_manager = DataManager()
    self.last_request_id = 0

    self.start_polling_loop()

  def cleanup(self):
    self.data_manager.cleanup()

  def start_polling_loop(self):
    if BE_VERBOSE: print('start polling loop...')
    while True:
      try:
        parameters = {
          'offset': self.last_request_id + 1,
          'timeout': 1
        }
        requests = self.perform_api_call(API_CALL_GET_UPDATES, parameters)

        if (requests != False):
          for request in requests:
            chat_id, command = self.parse_message_object(request['message'])

            if command in KNOWN_COMMANDS:
              if BE_VERBOSE:
                print('received "', command, '" from chat_id ', chat_id)
              self.respond_to_request(chat_id, command)

            if request['update_id'] > self.last_request_id:
              self.last_request_id = request['update_id']

        else:
          if BE_VERBOSE:
            print('no requests, wait for ' + str(API_POLL_INTERVAL) + 's')
          sleep(API_POLL_INTERVAL)

      except KeyboardInterrupt:
        if BE_VERBOSE: print('Terminate bot because of keyboard interruption')
        self.cleanup()
        sys.exit(0)

      except:
        print('Uncatched error in run loop; terminating bot!')
        self.cleanup()
        sys.exit(0)

  def perform_api_call(self, function, parameters={}):
    parsed_parameters = urllib.parse.urlencode(parameters)
    encoded_parameters = parsed_parameters.encode('utf-8')

    try:
      # if BE_VERBOSE:
      #   print('requesting API with parameters: ' + parsed_parameters)

      request = urllib.request.Request(
        API_URL + '/' + function, encoded_parameters)

      response = urllib.request.urlopen(request).read()
      decoded_response = json.loads(response.decode('utf-8'))

      if decoded_response['ok'] == True:
        return decoded_response['result']
      else:
        if BE_VERBOSE: print('API error, bad respond code')

    except:
      if BE_VERBOSE: print('Uncatched error while requesting the bot API')

    return False

  def parse_message_object(self, message):
    chat_id = -1
    command = ''

    # save the received message to the DB
    self.data_manager.new_message(message)

    if 'chat' in message:
      chat_id = message['chat']['id']
    elif BE_VERBOSE:
      print('no chat object in responded message. \
        Unable to identify user or group to respond to.')

    if 'text' in message:
      command = message['text']

    return chat_id, command

  def respond_to_request(self, chat_id, command):
    data = {'chat_id': chat_id}
    if command == KNOWN_COMMANDS[0]:
      if BE_VERBOSE: print('responding with newsticker')
      self.postillon_crawler.check_for_updates()
      data['text'] = self.data_manager.get_newsticker_for_chat(chat_id)
      data['text'] += ORIGINATOR_REFERENCE
    elif command == KNOWN_COMMANDS[1]:
      if BE_VERBOSE: print('responding with statistics')
      chats, newsticker, requests = self.data_manager.get_stistic()
      data['text'] = 'I answered ' + str(requests) + ' requests from '
      data['text'] += str(chats) + ' people and I know '
      data['text'] += str(newsticker) + ' headlines!'
    else:
      if BE_VERBOSE: print('responding with help text')
      data['text'] = self.create_information_respnse()

    self.perform_api_call(API_CALL_SEND_MESSAGE, data)

  def create_information_respnse(self):
    return '++++ Unofficial Postillon bot: \