Example #1
0
def itb_get_balance(message: Message):

    # DBセッションを開く
    db_context = DBContext()

    # ユーザーを取得する
    slack_uid = message.user["id"]
    user = User.get_user_from_slack_uid(db_context, slack_uid)

    # ユーザー登録されていない場合
    if user is None:

        response_txt = "ITBコンシェルジュサービスを利用するには入会する必要があります。"
        message.reply(response_txt)

    # ユーザー登録されている場合
    else:

        user_wallet = WalletController(user.eth_address, user.eth_privkey)
        itb_balance = user_wallet.get_balance(Symbol.ITB)

        response_txt = "ITBトークンの残高は「{} ITB」です。"
        response_txt = response_txt.format(itb_balance)
        message.reply(response_txt)

    # DBセッションを閉じる
    db_context.session.close()
def any_message(message: Message):
    try:
        logging.info(message.body)
        slack_client = message._client
        if message.body['type'] == 'message':
            channel_name = get_channel_name(message)
            username = get_message_username(message)
            logging.info("%s, %s", channel_name, username)
            if channel_name and channel_name in config.slack_wechat_map:
                group_name = config.slack_wechat_map[channel_name]
                group = get_group_by_name(group_name)
                send_wechat_text(slack_client, group, message.body['text'],
                                 username)
                if 'subtype' in message.body and message.body[
                        'subtype'] == 'file_share':
                    download_and_send_wechat_file(message, group)
                if 'attachments' in message.body:
                    for att in message.body['attachments']:
                        send_attachment(slack_client, group, username, att)
        else:
            logging.warning('unable to process the message type %s',
                            message.body['type'])
    except Exception as e:
        message.reply(
            'failed to sync to wechat. check #wechat-bot-support for details')
        raise
Example #3
0
def hello_send(message: Message):
    import shlex

    text = message.body["text"]
    parser = Parser(prog="$hello")
    Injector(hello).inject(parser)

    argv = shlex.split(text.split("$hello", 1)[1], posix=True)
    try:
        args = parser.parse_args(argv)
    except Exit as e:
        texts = []
        if e.args[0]:
            texts.append(e.args[0])
        texts.append(parser.format_help())
        new_line = "\n"
        message.send(f"""\
```
{new_line.join(texts).strip(new_line)}
```""")
        return

    params = vars(args).copy()
    with contextlib.redirect_stdout(StringIO()) as o:
        hello(**params)
    output = o.getvalue()
    if output.strip():
        message.send(output)
Example #4
0
def app(message: Message):
    global DRIVER
    text = message.body["text"]
    argv = shlex.split(text.split("$app", 1)[1], posix=True)

    output_list = []
    with contextlib.redirect_stdout(StringIO()) as o:
        with contextlib.redirect_stderr(o):
            try:
                if DRIVER is None:
                    parser = Parser(prog="$app")
                    DRIVER = runtime.Driver(parser=parser)
                    DRIVER.run(argv, module=sys.modules[__name__], debug=True)
                else:
                    DRIVER._run(argv, debug=True)
            except Exit as e:
                logger.debug("exit: %r", e)

    output = o.getvalue()
    if output.strip():
        output_list.append(output)

    new_line = "\n"
    if output_list:
        message.send(f"""\
```
{new_line.join(output_list).strip(new_line)}
```""")
Example #5
0
def describe_handler(message: Message, command, entry_no):
    logging.info(message.body)

    if entry_no is None or entry_no == '':
        message.send(f"{command} のあとに登録番号(半角数字のみ)を入力してください")
        return

    Describe().specified_entry_no(message, entry_no)
Example #6
0
def command_sync(msg: Message, group_name):
    channel_name = get_channel_name(msg)
    if not channel_name:
        msg.reply('use this command in a channel')
    else:
        config.set_mapping(group_name=group_name, channel_name=channel_name)
        reply_content = 'mapping established between %s <> %s"' % (group_name, channel_name)
        msg.reply(reply_content)
        send_wechat_text(group_name, reply_content, msg)
def command_disable(msg: Message, group_name):
    group_name = group_name.strip()
    channel_name = get_channel_name(msg)
    if not channel_name:
        msg.reply('use this command in a channel')
    else:
        config.del_mapping(group_name=group_name, channel_name=channel_name)
        reply_content = "mapping disabled between %s <> %s" % (group_name,
                                                               channel_name)
        msg.reply(reply_content)
        send_wechat_text(msg._client, group_name, reply_content)
Example #8
0
    def __validate_book_price(self, book_price: str, message: Message) -> bool:
        """
        立替金額のバリデーション
        :param book_price: 立替金額
        :return:
        """
        if not book_price.isdecimal():
            message.send("立替金額は数字で入力してください", thread_ts=message.body['ts'])
            return False

        return True
Example #9
0
def _react(message: Message, emojis: list[str]) -> None:
    """
    指定された emoji を reaction で返す
    """
    for emoji in emojis:
        try:
            message.react(emoji)
        except Error as error:
            # 同じリアクションをすると例外が発生するので、無視する
            if error.args[0] == "already_reacted":
                pass
            else:
                raise
Example #10
0
def botsend(message: Message, text: str) -> None:
    """
    スレッドの親かどうかで応答先を切り替える message.send() の代わりの関数

    :param messsage: slackbotのmessageオブジェクト
    :param text: 送信するテキストメッセージ
    """
    if "thread_ts" in message.body:
        # スレッド内のメッセージの場合
        message.send(text, thread_ts=message.thread_ts)
    else:
        # 親メッセージの場合
        message.send(text, thread_ts=None)
Example #11
0
def botreply(message: Message, text: str) -> None:
    """
    スレッドの親かどうかで応答先を切り替える message.reply() の代わりの関数

    :param messsage: slackbotのmessageオブジェクト
    :param text: 送信するテキストメッセージ
    """
    if "thread_ts" in message.body:
        # スレッド内のメッセージの場合
        message.reply(text, in_thread=True)
    else:
        # 親メッセージの場合
        message.reply(text)
Example #12
0
def hello(msg: Message, number_of_die: str, side_of_die: str):
    #
    roll_result = [
        random.randrange(1, int(side_of_die), 1)
        for i in range(int(number_of_die))
    ]

    # 주사위를 던진 횟수만큼 나온 숫자를 모두 더합니다.
    roll_sum = sum(roll_result)

    # 주사위를 던져서 나온 숫자와 합을 메시지로 출력합니다.
    msg.send(str(roll_result))
    msg.send(str(roll_sum))
Example #13
0
def hello(msg: Message, number_of_die: str, side_of_die: str):

    # 'roll 던지는횟수d숫자면체' 로
    # '던지는횟수'를 number_of_die
    # '숫자면체'를 side_of_die
    # '
    roll_result = [
        random.randrange(1, int(side_of_die), 1)
        for i in range(int(number_of_die))
    ]
    roll_sum = sum(roll_result)

    msg.send(str(roll_result))
    msg.send(str(roll_sum))
Example #14
0
def delete_handler(message: Message, command, entry_no):
    logging.info(message.body)

    if message.body['channel'] != settings.DEFAULT_CHANNEL_ID:
        slack = Slack()
        text = f"公式チャンネル #{slack.get_channel_name(message, channel_id=settings.DEFAULT_CHANNEL_ID)} で実行してください!"
        slack.send_message_with_link_names(message, message.body['channel'],
                                           text)
        return

    if entry_no is None or entry_no == '':
        message.send(f"{command} のあとに登録番号(半角数字のみ)を入力してください")
        return

    Delete().specified_entry_no(message, entry_no)
Example #15
0
def dispatch_msg_handler_with_bot_message(self, category, msg):
    responded = False
    if 'text' in msg:
        text = msg['text']
    else:
        text = msg['attachments'][0]['text']
    for func, args in self._plugins.get_plugins(category, text):
        if func:
            responded = True
            try:
                func(Message(self._client, msg), *args)
            except Exception:
                logger.exception(
                    'failed to handle message %s with plugin "%s"', text,
                    func.__name__)
                reply = u'[{}] I had a problem handling "{}"\n'.format(
                    func.__name__, text)
                tb = u'```\n{}\n```'.format(traceback.format_exc())
                if self._errors_to:
                    self._client.rtm_send_message(msg['channel'], reply)
                    self._client.rtm_send_message(self._errors_to,
                                                  u'{}\n{}'.format(reply, tb))
                else:
                    self._client.rtm_send_message(msg['channel'],
                                                  u'{}\n{}'.format(reply, tb))
    return responded
Example #16
0
def botwebapi(message: Message, attachments: list[dict] | str) -> None:
    """
    スレッドの親かどうかで応答先を切り替える message.send_webapi() の代わりの関数

    :param messsage: slackbotのmessageオブジェクト
    :param attachments: 送信するAttachments(JSON)
    """
    # 文字列じゃないときはJSON文字列にする
    if not isinstance(attachments, str):
        attachments = json.dumps(attachments)

    if "thread_ts" in message.body:
        # スレッド内のメッセージの場合
        message.send_webapi("", attachments, thread_ts=message.thread_ts)
    else:
        # 親メッセージの場合
        message.send_webapi("", attachments)
Example #17
0
def plusplus_delete(message: Message, subcommand: str, name: str) -> None:
    """
    指定された名前を削除する
    カウントが10未満のもののみ削除する
    """

    try:
        plus = Plusplus.get(name=name)
    except Plusplus.DoesNotExist:
        message.send(f"`{name}` という名前は登録されていません")
        return

    if abs(plus.counter) > 10:
        botsend(message,
                f"`{name}` のカウントが多いので削除を取り消しました(count: {plus.counter})")
        return

    plus.delete_instance()
    message.send(f"`{name}` を削除しました")
Example #18
0
    def run(self, message: Message) -> None:
        text = message.body["text"]
        argv = runtime.parse(text, name=self.command_name)

        with runtime.handle() as output_list:
            if self.driver is None:
                self.driver = cli_runtime.Driver(parser=self.parser)
                self.driver.run(argv, module=self.module, debug=self.debug)
            else:
                self.driver._run(argv, debug=self.debug)

        if output_list:
            new_line = "\n"
            message.reply(
                f"""\
```
{new_line.join(output_list).strip(new_line)}
```""",
                in_thread=True,
            )
Example #19
0
def plusplus_rename(message: Message, old: str, new: str) -> None:
    """
    指定された old から new に名前を変更する
    """
    try:
        oldplus = Plusplus.get(name=old)
    except Plusplus.DoesNotExist:
        botsend(message, f"`{old}` という名前は登録されていません")
        return

    newplus, created = Plusplus.get_or_create(name=new,
                                              counter=oldplus.counter)
    if not created:
        # すでに存在している
        message.send(f"`{new}` という名前はすでに登録されています")
        return

    # 入れ替える
    oldplus.delete_instance()
    botsend(message,
            f"`{old}` から `{new}` に名前を変更しました(count: {oldplus.counter})")
Example #20
0
def hello_send(message: Message):
    import shlex

    text = message.body["text"]
    parser = Parser(prog="$hello")
    parser.add_argument("--name", default="world")
    argv = shlex.split(text.split("$hello", 1)[1], posix=True)
    try:
        args = parser.parse_args(argv)
        print(f"parsed: {args}", file=sys.stderr)
        message.send(f"hello {args.name}")
    except Exit as e:
        texts = []
        if e.args[0]:
            texts.append(e.args[0])
        texts.append(parser.format_help())
        new_line = "\n"
        message.send(f"""\
```
{new_line.join(texts).strip(new_line)}
```""")
Example #21
0
def app(message: Message):
    global DRIVER
    text = message.body["text"]
    argv = runtime.parse(text, name="$app")

    with runtime.handle() as output_list:
        if DRIVER is None:
            parser = runtime.ExitExceptionParser(prog="$app")
            DRIVER = cli_runtime.Driver(parser=parser)
            DRIVER.run(argv, module=sys.modules[__name__], debug=True)
        else:
            DRIVER._run(argv, debug=True)

    new_line = "\n"
    if output_list:
        message.reply(
            f"""\
```
{new_line.join(output_list).strip(new_line)}
```""",
            in_thread=True,
        )
Example #22
0
def hello_send(message: Message):
    import re

    text = message.body["text"]
    parser = Parser()
    parser.add_argument("--name", default="world")
    argv = [x for x in re.split(r"\s+", text.split("$hello", 1)[1]) if x]
    try:
        args = parser.parse_args(argv)
        print(f"parsed: {args}", file=sys.stderr)
        return message.send(f"hello {args.name}")
    except Exit as e:
        texts = []
        if e.args[0]:
            texts.append(e.args[0])
        texts.append(parser.format_help())
        new_line = "\n"
        return message.send(
            f"""\
```
{new_line.join(texts)}
```"""
        )
Example #23
0
def itb_cancel_membership(message: Message):

    # DBセッションを開く
    db_context = DBContext()

    # ユーザーを取得する
    slack_uid = message.user["id"]
    user = User.get_user_from_slack_uid(db_context, slack_uid)

    # ユーザー登録されていない場合
    if user is None:

        response_txt = "ITBコンシェルジュサービスを利用するには入会する必要があります。"
        message.reply(response_txt)

    # ユーザー登録されている場合
    else:

        response_txt = "退会するなんてとんでもない!"
        message.reply(response_txt)

    # DBセッションを閉じる
    db_context.session.close()
Example #24
0
def late_count(message_info: Message):
    message = message_info.body['text']
    if message.find('이번달') != -1:
        target_date = date.today()
    else:
        try:
            target_date = parse(message, fuzzy=True).date()
        except ValueError:
            target_date = date.today() - relativedelta(months=1)

    slacker = Slacker(settings.API_TOKEN)
    channel_id = message_info.channel._body['id']
    response = slacker.groups.history(channel_id, count=1000)
    messages = response.body['messages']

    late_info = get_late_count_dict(channel_id, messages, target_date)

    if message.find('상세') != -1:
        message = make_late_count_detail_message(target_date, late_info)
    else:
        message = make_late_count_message(target_date, late_info)

    message_info.send(message)
Example #25
0
    def save(self, message: Message):
        now = datetime.now()

        entry_no = ''
        impression = ''
        for block in message.body['blocks']:
            if not ('text' in block and 'text' in block['text']):
                continue

            text = block['text']['text']
            if '*登録番号*' in text:
                entry_no = re.sub('\\D', '', self.converter.to_hankaku(text))
                self.logger.debug(f"entry_no={entry_no}")
            elif '*感想*' in text:
                impression = re.sub('\*感想\*\n', '', text).strip()
                self.logger.debug(f"impression={impression}")

        # 投稿タイムスタンプ(スレッド投稿のため)
        ts = message.body['ts']

        # パラメータチェック
        if not self.validation.validate_impression(entry_no=entry_no, message=message):
            self.logger.debug("パラメータチェックNG")
            return

        # 申請者 Slack ID
        slack_id = self.slack.get_slack_id_from_workflow(message.body['text'])

        # 更新対象レコードを取得
        items = self.dynamodb.query_specified_key_value(self.dynamodb.default_table, 'entry_no', entry_no)
        # プライマリキー指定なので必ず1件取得
        item = items[0]

        if item['slack_id'] != slack_id:
            message.send(f"<@{slack_id}> 購入者本人以外は感想登録できません!", thread_ts=ts)
            return False

        # 感想登録日
        impression_time = now.strftime("%Y%m%d%H%M%S")
        self.logger.debug(f"impression_time={impression_time}")

        # 感想登録フラグ 1:登録あり
        impression_flag = '1'

        # 感想登録
        response = self.dynamodb.update_bookbot_entry_impression(entry_no, impression, impression_time, impression_flag)
        self.logger.debug(response)
        if response is None:
            self.logger.error(f"感想の登録に失敗しました")
            message.send(f"<@{slack_id}> 感想の登録に失敗しました...すいません!", thread_ts=ts)
            return False

        item['impression'] = impression
        reply_texts = [f"<!here> 以下の感想が登録されました!"]
        reply_texts.append(self.converter.get_list_str(item))

        message.send("\n".join(reply_texts), thread_ts=ts)
Example #26
0
def itb_switch_notification_enabled(message: Message):

    # DBセッションを開く
    db_context = DBContext()

    # ユーザーを取得する
    slack_uid = message.user["id"]
    user = User.get_user_from_slack_uid(db_context, slack_uid)

    # ユーザー登録されていない場合
    if user is None:

        response_txt = "ITBコンシェルジュサービスを利用するには入会する必要があります。"
        message.reply(response_txt)

    # ユーザー登録されている場合
    else:

        # メッセージ本文を取得する
        message_body = message.body["text"]

        # メッセージを要素に分解する
        m = re.match("(^ITB.*通知.*?)(ON|OFF)(.*$)", message_body, re.IGNORECASE)

        if m:
            if m.group(2).upper() == "ON":
                user.notification_enabled = True
                response_txt = "通知をONにしました。"
                message.reply(response_txt)
            else:
                user.notification_enabled = False
                response_txt = "通知をOFFにしました。"
                message.reply(response_txt)

        # コミット
        db_context.session.commit()

    # DBセッションを閉じる
    db_context.session.close()
Example #27
0
def itbcafe_list_shopitem(message: Message):

    # DBセッションを開く
    db_context = DBContext()

    # ユーザーを取得する
    slack_uid = message.user["id"]
    user = User.get_user_from_slack_uid(db_context, slack_uid)

    # ユーザー登録されていない場合
    if user is None:

        response_txt = "ITBコンシェルジュサービスを利用するには入会する必要があります。"
        message.reply(response_txt)

    # ユーザー登録されている場合
    else:

        items = db_context.session.query(ShopItem) \
            .filter(ShopItem.available == True) \
            .all()

        if len(items) > 0:

            response_txt = "現在、下記の商品を購入できます。\n"
            response_txt += "```\n"
            for item in items:
                response_txt += "・{} ({:.0f} ITB)\n".format(
                    item.name, item.price)
            response_txt += "```"
            message.reply(response_txt)

        else:

            response_txt = "現在、購入できる商品はありません。\n"
            message.reply(response_txt)

    # DBセッションを閉じる
    db_context.session.close()
Example #28
0
def get_message(text=None, channel='channelid', thread_ts=None):
    message = Message(None, {'channel': channel, 'text': text, 'thread_ts': thread_ts})
    message.send_webapi = MagicMock()
    return message
Example #29
0
def fake_message(client: SlackClient, text: str, *, channel: str) -> Message:
    data = {"text": text, "channel": channel}
    return Message(client, data)
Example #30
0
def hello(msg: Message):
    msg.send("world!!")
Example #31
0
def hi(msg: Message):
    msg.reply("Thank you!!")