class MrTeaBot(object): def __init__(self, token, uid): self.bot = Bot(token) self.bot.notifyOnMessage(self.handle_message) self.uid = uid self.name = None self.waiting_for_rank = False def ask(self, name, rebrew): self.name = name self.rebrew = rebrew r = ' (rebrewed)' if rebrew else '' self.bot.sendMessage( self.uid, 'please rate {}{}'.format(name, r) ) self.waiting_for_rank = True def log_rank(self, rank): doc = { 'name': self.name, 'rebrew': self.rebrew, 'rank': rank, '@timestamp': datetime.utcnow(), } es.index(index="mr_tea", doc_type='tea_rank', body=doc) def get_rank(self, msg): rank = int(msg['text']) if rank < 1 or rank > 5: raise ValueError('rank should be between 1 and 5') return rank def handle_message(self, msg): if not self.waiting_for_rank: self.bot.sendMessage(self.uid, 'not waiting for rank') return try: self.log_rank(self.get_rank(msg)) except Exception as e: self.bot.sendMessage(self.uid, 'failed to log rank: {}'.format(e)) return self.bot.sendMessage( self.uid, 'your review of {} tea was logged'.format(self.name) ) self.waiting_for_rank = False
class BubbyBot(object): def __init__(self, token): self.token = token self.valid_answers = [str(x) for x in xrange(0, 11)] self.question = 'How much does it hurt from 1 to 10?' self.message_hours = [9, 12, 17, 20, 23] def get_next_message_time(self): d = datetime.now().replace(minute=0) for h in self.message_hours: if h > d.hour: d = d.replace(hour=h) break else: d = d.replace(hour=self.message_hours[0]) + timedelta(days=1) return d def subscribe(self): self.bot = Bot(self.token) self.bot.notifyOnMessage(self.handle_message) while 1: for user in get_all_users(): self.handle_user(user) time.sleep(1) def set_next_msg_time(self, user): user.next_msg_time = self.get_next_message_time() user.save() def handle_user(self, user): logging.info(user.next_msg_time) if user.next_msg_time is None or user.next_msg_time <= datetime.now(): self.ask_if_head_hurts(user) self.set_next_msg_time(user) def greet(self, user): self.bot.sendMessage(user['id'], STRINGS.greeting) def goodbye(self, user_id): self.bot.sendMessage(user_id, STRINGS.goodbye) def register_user(self, user): add_to_database(user) self.greet(user) def unregister_user(self, user_id): remove_from_database(user_id) self.goodbye(user_id) def ask_if_head_hurts(self, user): show_keyboard = { 'keyboard': [self.valid_answers], 'force_reply': True } try: self.bot.sendMessage(user.id, self.question, reply_markup=show_keyboard) except TelegramError as e: logging.exception('ask if head hurts') if e.error_code == 403: remove_from_database(user.id) def register_answer(self, user, answer): logging.info('got answer %d', answer) if answer == 0: self.bot.sendMessage(user['id'], 'I\'m happy your head doesn\'t hurt!') elif answer < 4: self.bot.sendMessage(user['id'], 'Are you drinking water?? please drink water!') elif answer < 6: self.bot.sendMessage(user['id'], 'Drink more water and maybe take a pill? :(') elif answer < 9: self.bot.sendMessage(user['id'], 'Poor little bubby, take another pill') else: self.bot.sendMessage(user['id'], 'It\'s time to hit the hospital') self.commit_answer_to_database(user, answer) def get_stastd_key_for_user(self, user): return 'bubby_bot.{}'.format(user['id']) def commit_answer_to_database(self, user, answer): key = self.get_stastd_key_for_user(user) logging.info('statsd %s - %d', key, answer) statsd_client.gauge(key, answer) def invalid_answer(self, user): self.bot.sendMessage(user['id'], STRINGS.invalid_answer) def send_stats(self, user, text): days = text[6:] if not days: days = 1 try: days = int(days) except ValueError: days = 1 key = self.get_stastd_key_for_user(user) r = requests.get(graphite_url.format(user['id'], '-{}days'.format(days))) with tempfile.NamedTemporaryFile(suffix='.png') as f: f.write(r.content) f.flush() f.seek(0) if days == 1: last_msg_part = '24 hours' else: last_msg_part = '{} days'.format(days) self.bot.sendMessage(user['id'], 'here you go, last ' + last_msg_part) r = self.bot.sendPhoto(user['id'], f) print(r) def handle_message(self, msg): if msg['text'] == '/start': self.register_user(msg['from']) elif msg['text'] == '/stop': self.unregister_user(msg['from']['id']) elif msg['text'].startswith('/stats'): self.send_stats(msg['from'], msg['text']) elif msg['text'] in self.valid_answers: self.register_answer(msg['from'], int(msg['text'])) else: self.invalid_answer(msg['from'])