Пример #1
0
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)
Пример #2
0
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)
Пример #3
0
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
Пример #4
0
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