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
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)
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)} ```""")
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)
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)
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
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
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)
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)
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))
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))
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)
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
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)
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}` を削除しました")
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, )
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})")
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)} ```""")
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, )
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)} ```""" )
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()
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)
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)
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()
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()
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
def fake_message(client: SlackClient, text: str, *, channel: str) -> Message: data = {"text": text, "channel": channel} return Message(client, data)
def hello(msg: Message): msg.send("world!!")
def hi(msg: Message): msg.reply("Thank you!!")