class SlackBot: def __init__(self): self.slack_client = SlackClient(SLACK_API_TOKEN) self.bot_commands = { '!help': { 'desc': 'Commands list', 'callback': self.help_callback }, '!itunes': { 'desc': 'iTunes info', 'callback': self.itunes_info_callback }, '!track': { 'desc': 'Current track info', 'callback': self.track_info_callback }, '!volume': { 'desc': 'Set volume [0-100]', 'callback': self.change_volume_callback }, '!next': { 'desc': 'Next track', 'callback': self.next_track_callback }, '!previous': {'desc': 'Previous track', 'callback': self.previous_track}, '!startplay' : { 'desc': 'Start playing', 'callback': self.start_play_callback }, '!pauseplay' : { 'desc': 'Pause playing', 'callback': self.pause_play_callback }, } #region Command Callback's def help_callback(self): output = '\n*Bot Commands:*\n' for command, command_info in self.bot_commands.iteritems(): output += '*{0}* - {1}\n'.format(command, command_info['desc']) self.send_message(output) def itunes_info_callback(self): self.send_message(itunes.get_itunes_info()) def track_info_callback(self): self.send_message(itunes.get_track_info()) def change_volume_callback(self, value): itunes.set_volume(value) def start_play_callback(self): itunes.start_play() def pause_play_callback(self): itunes.pause_play() def next_track_callback(self): itunes.next_track() def previous_track(self): itunes.previous_track() #endregion def exec_bot_command(self, command, command_arg=None): if command in self.bot_commands: command_callback = self.bot_commands[command]['callback'] if not command_arg: command_callback() else: command_callback(command_arg) def parse_message(self, message): if message and message[0] == '!': command_data = message.split(' ', 1) if len(command_data) == 1: self.exec_bot_command(command_data[0]) else: self.exec_bot_command(command_data[0], command_data[1]) def send_message(self, message): if message: self.slack_client.send_message(BOT_CHANNEL, message, BOT_NAME) def read_messages_while(self): while True: try: event_data = self.slack_client.rtm_read() if len(event_data) == 1: if event_data[0]['type'] == 'message' and event_data[0]['channel'] == BOT_CHANNEL: self.parse_message(event_data[0]['text']) except Exception as e: logging.error(e) finally: time.sleep(MESSAGE_READ_TIMEOUT)
class Bot(object): def __init__(self, active_plugins): self.twi = Twi( settings.TWITTER_APP_KEY, settings.TWITTER_APP_SECRET, settings.TWITTER_OAUTH_TOKEN, settings.TWITTER_OAUTH_TOKEN_SECRET, settings.SLACK_CHANNEL, settings.SEARCH_TERM, ) self.rss = Rss( settings.FEEDS, settings.SLACK_CHANNEL, ) self.flickr = Flickr( settings.FLICKR_TAGS, settings.SLACK_CHANNEL, ) self.client = SlackClient(settings.SLACK_API_TOKEN, bot_icon=settings.SLACK_BOT_ICON, bot_emoji=settings.SLACK_BOT_EMOJI) self.selected_chanel = self.client.find_channel_by_name( settings.SLACK_CHANNEL) self.active_plugins = active_plugins def run(self): self.client.rtm_connect() _thread.start_new_thread(self.keepactive, tuple()) self.loop() def keepactive(self): while True: time.sleep(30 * 60) self.client.ping() def loop(self): while True: events = self.client.rtm_read() # for event in events: # if event.get('type') != 'message': # continue if self.active_plugins['twitter']: tweets = self.twi.get_next_tweets() for tweet in tweets: self.client.send_message( self.selected_chanel, tweet['text'], tweet['attachments'], ) if self.active_plugins['rss']: entries = self.rss.get_next_entries() for entry in entries: self.client.send_message( self.selected_chanel, entry['text'], entry['attachments'], ) if self.active_plugins['flickr']: photos = self.flickr.get_next_photos() for photo in photos: self.client.send_message( self.selected_chanel, photo['text'], photo['attachments'], ) time.sleep(10)
class Bot(threading.Thread): def __init__(self, token): threading.Thread.__init__(self) self._client = SlackClient(token) def run(self): self._client.rtm_connect() logger.info('connected to slack RTM api') self.loop() def loop(self): while True: events = self._client.rtm_read() logger.debug(events) for event in events: if event.get('type') != 'message': continue self._on_new_message(event) time.sleep(1) def _on_new_message(self, msg): # ignore edits subtype = msg.get('subtype', '') if subtype == u'message_changed': return # BOT自身の投稿かチェック botname = self._client.username try: msguser = self._client.users.get(msg['user']) username = msguser['name'] except (KeyError, TypeError): if 'username' in msg: username = msg['username'] else: return if username == botname or username == u'slackbot': return msg_respond_to = self.filter_text(msg) if msg_respond_to: self.check_respond_command(msg_respond_to) else: self.check_listen_command(msg) def filter_text(self, msg): text = msg.get('text', '') channel = msg['channel'] # TODO:このチャンネルの頭文字の意味が謎 CはチャンネルだがG?DMはDから始まる if channel[0] == 'C' or channel[0] == 'G': m = AT_MESSAGE_MATCHER.match(text) if not m: return atuser, text = m.groups() if atuser != self._client.id: # a channel message at other user return logger.debug('got an AT message: %s', text) msg['text'] = text else: m = AT_MESSAGE_MATCHER.match(text) if m: msg['text'] = m.group(2) return msg def check_respond_command(self, data): if "占い" in data['text']: text = tell.getUranai(data['text']) self.send_webapi(data, text, True) elif "beluga" in data['text']: b = beluga.Beluga() text = "" tws = b.get_public() for t in tws: text += "\n{} \n{}".format(t.screen_name, t.text) self.send_webapi(data, text, True) elif "log" in data['text']: self.send_dm_with_log(data) else: self.send_webapi(data, "かわいい~", True) def check_listen_command(self, data): if "勃起" in data['text']: self.send_webapi(data, "いいね~") def send_webapi(self, data, text, replyflg=False): send_text = "" if replyflg: send_text = u'<@{}>: {}'.format(data['user'], text) else: send_text = text self._client.send_message( data['channel'], send_text) def send_dm_with_log(self, msg): if msg['channel'][0] != 'C' and msg['channel'][0] != 'G': return try: msguser = self._client.users.get(msg['user']) username = msguser['name'] except (KeyError, TypeError): if 'username' in msg: username = msg['username'] else: return # TODO:oldest指定 text = self.__make_log_text(msg['channel'], 100) if len(text) > 0: LOG_FILE_NAME = "log.txt" with open(LOG_FILE_NAME, "w", encoding="utf-8") as f: f.write(text) self._client.upload_file(os.path.abspath(LOG_FILE_NAME), LOG_FILE_NAME, "log" , msg['channel']) os.remove(LOG_FILE_NAME) else: self.send_webapi(msg, "ログがないよ~") def __make_log_text(self, channel_id, days_before): today = datetime.now() oldest = datetime(today.year, today.month, today.day, 0,0,0,0) - timedelta(days=days_before) oldest = time.mktime(oldest.timetuple()) msg = "" readingflg = True while readingflg: data = self._client.get_history(channel_id, oldest=oldest, count=1000) if len(data['messages']) == 1000: oldest = data['messages'][0]['ts'] else: readingflg = False for m in reversed(data['messages']): if m['type'] == "message": name = 'no name' try: name = self._client.users.get(m['user'])['name'] except (KeyError, TypeError): if 'username' in m: # 'bot_message' name = m['username'] else: continue ts = datetime.fromtimestamp(float(m['ts'])) text = m['text'] # TODO:attachments pending #attachments = m['attachments'] msg += "\n{0}:{1}\n{2}\n".format(name, ts, text) return msg
class Bot(threading.Thread): def __init__(self, token): threading.Thread.__init__(self) self._client = SlackClient(token) def run(self): self._client.rtm_connect() logger.info('connected to slack RTM api') self.loop() def loop(self): while True: events = self._client.rtm_read() logger.debug(events) for event in events: if event.get('type') != 'message': continue self._on_new_message(event) time.sleep(1) def _on_new_message(self, msg): # ignore edits subtype = msg.get('subtype', '') if subtype == u'message_changed': return # BOT自身の投稿かチェック botname = self._client.username try: msguser = self._client.users.get(msg['user']) username = msguser['name'] except (KeyError, TypeError): if 'username' in msg: username = msg['username'] else: return if username == botname or username == u'slackbot': return msg_respond_to = self.filter_text(msg) if msg_respond_to: self.check_respond_command(msg_respond_to) else: self.check_listen_command(msg) def filter_text(self, msg): text = msg.get('text', '') channel = msg['channel'] # TODO:このチャンネルの頭文字の意味が謎 CはチャンネルだがG?DMはDから始まる if channel[0] == 'C' or channel[0] == 'G': m = AT_MESSAGE_MATCHER.match(text) if not m: return atuser, text = m.groups() if atuser != self._client.id: # a channel message at other user return logger.debug('got an AT message: %s', text) msg['text'] = text else: m = AT_MESSAGE_MATCHER.match(text) if m: msg['text'] = m.group(2) return msg def check_respond_command(self, data): if "占い" in data['text']: text = tell.getUranai(data['text']) self.send_webapi(data, text, True) elif "beluga" in data['text']: b = beluga.Beluga() text = "" tws = b.get_public() for t in tws: text += "\n{} \n{}".format(t.screen_name, t.text) self.send_webapi(data, text, True) elif "log" in data['text']: self.send_dm_with_log(data) else: self.send_webapi(data, "かわいい~", True) def check_listen_command(self, data): if "勃起" in data['text']: self.send_webapi(data, "いいね~") def send_webapi(self, data, text, replyflg=False): send_text = "" if replyflg: send_text = u'<@{}>: {}'.format(data['user'], text) else: send_text = text self._client.send_message(data['channel'], send_text) def send_dm_with_log(self, msg): if msg['channel'][0] != 'C' and msg['channel'][0] != 'G': return try: msguser = self._client.users.get(msg['user']) username = msguser['name'] except (KeyError, TypeError): if 'username' in msg: username = msg['username'] else: return # TODO:oldest指定 text = self.__make_log_text(msg['channel'], 100) if len(text) > 0: LOG_FILE_NAME = "log.txt" with open(LOG_FILE_NAME, "w", encoding="utf-8") as f: f.write(text) self._client.upload_file(os.path.abspath(LOG_FILE_NAME), LOG_FILE_NAME, "log", msg['channel']) os.remove(LOG_FILE_NAME) else: self.send_webapi(msg, "ログがないよ~") def __make_log_text(self, channel_id, days_before): today = datetime.now() oldest = datetime(today.year, today.month, today.day, 0, 0, 0, 0) - timedelta(days=days_before) oldest = time.mktime(oldest.timetuple()) msg = "" readingflg = True while readingflg: data = self._client.get_history(channel_id, oldest=oldest, count=1000) if len(data['messages']) == 1000: oldest = data['messages'][0]['ts'] else: readingflg = False for m in reversed(data['messages']): if m['type'] == "message": name = 'no name' try: name = self._client.users.get(m['user'])['name'] except (KeyError, TypeError): if 'username' in m: # 'bot_message' name = m['username'] else: continue ts = datetime.fromtimestamp(float(m['ts'])) text = m['text'] # TODO:attachments pending #attachments = m['attachments'] msg += "\n{0}:{1}\n{2}\n".format(name, ts, text) return msg