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 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 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.reply( f"""\ ``` {new_line.join(output_list).strip(new_line)} ```""", in_thread=True, )
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 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 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 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 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 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 echo(message: Message): message.reply(f"got {message.body.get('text')}")
def itbcafe_create_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: # メッセージ本文を取得する message_body = message.body["text"] # メッセージを要素に分解する m = re.match("(^ITB.*商品登録)\s(.*?)\s(.*?)($)", message_body, re.IGNORECASE) if m: validation_errors = [] # 入力値を検証する(商品名) name = str(m.group(2)).replace(" ", "").replace(" ", "") if len(name) == 0: validation_errors.append("商品名を入力してください。") # 入力値を検証する(商品価格) try: price = Decimal(int(m.group(3))) if price < Decimal('1'): validation_errors.append("商品価格は1 ITB以上の整数で入力してください。") except: validation_errors.append("商品価格は1 ITB以上の整数で入力してください。") if len(validation_errors) == 0: item = db_context.session.query(ShopItem) \ .filter(ShopItem.name == name) \ .first() # 商品が登録されている場合、登録を更新する if item: item.price = price item.available = True item.updated_at = func.now() # 商品が登録されていない場合、新規登録する else: item = ShopItem(name=name, price=price, available=True, created_at=func.now(), updated_at=func.now()) db_context.session.add(item) db_context.session.flush() # コミット db_context.session.commit() response_txt = "商品「{} ({:.0f} ITB)」を登録しました。" response_txt = response_txt.format(item.name, item.price) message.reply(response_txt) else: response_txt = "\n".join(validation_errors) message.reply(response_txt) else: response_txt = "商品登録は下記のフォーマットで入力してください。\n" response_txt += "「ITB 商品登録 {商品名} {商品価格}」" message.reply(response_txt) # DBセッションを閉じる db_context.session.close()
def itbcafe_delete_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: # メッセージ本文を取得する message_body = message.body["text"] # メッセージを要素に分解する m = re.match("(^ITB.*商品削除)\s(.*?)($)", message_body, re.IGNORECASE) if m: validation_errors = [] # 入力値を検証する(商品名) name = str(m.group(2)).replace(" ", "").replace(" ", "") if len(name) == 0: validation_errors.append("商品名を入力してください。") if len(validation_errors) == 0: item = db_context.session.query(ShopItem) \ .filter(ShopItem.name == name) \ .first() # 商品が登録されている場合、登録を削除する(論理削除) if item: item.available = False item.updated_at = func.now() # コミット db_context.session.commit() response_txt = "商品「{}」を削除しました。" response_txt = response_txt.format(item.name) message.reply(response_txt) # 商品が登録されていない場合 else: response_txt = "商品「{}」は登録されていません。" response_txt = response_txt.format(name) message.reply(response_txt) else: response_txt = "\n".join(validation_errors) message.reply(response_txt) else: response_txt = "商品削除は下記のフォーマットで入力してください。\n" response_txt += "「ITB 商品削除 {商品名}」" message.reply(response_txt) # DBセッションを閉じる db_context.session.close()
def hi(msg: Message): msg.reply("Thank you!!")
def itbcafe_buy_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: # メッセージ本文を取得する message_body = message.body["text"] # メッセージを要素に分解する m = re.match("(^ITB.*購入)\s(.*?)($)", message_body, re.IGNORECASE) if m: validation_errors = [] # 入力値を検証する(商品名) name = str(m.group(2)).replace(" ", "").replace(" ", "") if len(name) == 0: validation_errors.append("商品名を入力してください。") if len(validation_errors) == 0: item = db_context.session.query(ShopItem) \ .filter(ShopItem.name == name) \ .filter(ShopItem.available == True) \ .first() # 商品が登録されている場合 if item: # 商品を購入する user_wallet = WalletController(user.eth_address, user.eth_privkey) is_success, tx_hash, error_reason = user_wallet.send_to( ITB_FOUNDATION_ADDRESS, Symbol.ITB, Decimal(item.price)) # 結果を通知する if is_success == True: order = ShopOrder(userid=user.id, name=item.name, price=item.price, ordered_at=func.now(), created_at=func.now(), updated_at=func.now()) db_context.session.add(order) db_context.session.commit() response_txt = "{}の購入が完了しました:yum: (-{:.0f} ITB)\n" response_txt += "https://ropsten.etherscan.io/tx/{}" response_txt = response_txt.format( item.name, item.price, tx_hash) message.reply(response_txt) else: response_txt = "{}の購入に失敗しました:sob:\n" response_txt += "{}" response_txt = response_txt.format( item.name, error_reason) message.reply(response_txt) # 商品が登録されていない場合 else: response_txt = "取り扱いのない商品です。" message.reply(response_txt) else: response_txt = "\n".join(validation_errors) message.reply(response_txt) else: response_txt = "購入は下記のフォーマットで入力してください。\n" response_txt += "「ITBCafe 購入 {商品名}」" message.reply(response_txt) # DBセッションを閉じる db_context.session.close()
def itb_join_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 not None: response_txt = "既にITBコンシェルジュサービスに入会しています。" message.reply(response_txt) response_txt = "ITBコンシェルジュサービスへようこそ。\n" response_txt += "あなたのアカウント情報はこちらです。\n" response_txt += "この秘密鍵は外部ウォレットで利用することができます。\n" response_txt += "```\n" response_txt += "slack_uid:{}\n" response_txt += "eth_address:{}\n" response_txt += "eth_privkey:{}\n" response_txt += "https://ropsten.etherscan.io/token/{}?a={}\n" response_txt += "```" response_txt = response_txt.format(user.slack_uid, user.eth_address, user.eth_privkey, CONTRACT_ADDRESS, user.eth_address) message.direct_reply(response_txt) # ユーザー登録されていない場合 else: # ユーザーを新規登録する user = User(slack_uid=slack_uid, slack_name=message.user["real_name"], notification_enabled=True, created_at=func.now(), updated_at=func.now()) db_context.session.add(user) db_context.session.flush() # 新規アドレスを発行する eth_address, eth_privkey = WalletController.create_address(user.id) user.eth_address = eth_address user.eth_privkey = eth_privkey response_txt = "ITBコンシェルジュサービスへ入会しました。" message.reply(response_txt) response_txt = "ITBコンシェルジュサービスへようこそ。\n" response_txt += "あなたのアカウント情報はこちらです。\n" response_txt += "この秘密鍵は外部ウォレットで利用することができます。\n" response_txt += "```\n" response_txt += "slack_uid:{}\n" response_txt += "eth_address:{}\n" response_txt += "eth_privkey:{}\n" response_txt += "https://ropsten.etherscan.io/token/{}?a={}\n" response_txt += "```" response_txt = response_txt.format(user.slack_uid, user.eth_address, user.eth_privkey, CONTRACT_ADDRESS, user.eth_address) message.direct_reply(response_txt) # ガス代を付与する wc = WithdrawalController(db_context) wc.request_to_withdraw(Symbol.ETH, Decimal("1"), ITB_FOUNDATION_ADDRESS, user.eth_address, "ガス代補充") # 新規登録ボーナスを付与する wc.request_to_withdraw(Symbol.ITB, Decimal("1000"), ITB_FOUNDATION_ADDRESS, user.eth_address, "新規登録ボーナス") # コミット db_context.session.commit() # DBセッションを閉じる db_context.session.close()
def itb_get_help(message: Message): response_txt = "```\n" response_txt += "ITBトークンとは\n" response_txt += " ITBトークンとは、IT分科会を主体とし、発行されたトークンのことです。\n" response_txt += " 社内の良好なコミュニケーションの実現を目的とし、\n" response_txt += " これを実現するため、各種サービスの提供を計画しています。\n" response_txt += " 初期リリース時に提供されるサービスとして、「いいね!チップ送信機能」があります。\n" response_txt += " Slackで「いいね!」をすると、ITBトークンがチップとして送付されます。\n" response_txt += " さぁ、ITBコンシェルジュサービスに入会し、ITBトークンを送りあいましょう。\n" response_txt += "\n" response_txt += "ITBコンシェルジュサービスとは\n" response_txt += " 良いサービスとは誰でも気軽に利用できるサービスであると考えています。\n" response_txt += " そこでITBトークンを気軽に送りあえるプラットフォームをSlack上に構築しました。\n" response_txt += " このプラットフォームの名前が「ITBコンシェルジュサービス」です。\n" response_txt += " 「ITBコンシェルジュ」が招待されているチェンネルであれば、\n" response_txt += " どこでもサービスを受けることができます。\n" response_txt += "\n" response_txt += "ITBカフェとは\n" response_txt += " みなさん、ビットコインで商品を購入した経験はございますか?\n" response_txt += " ITBCafeでは、トークンエコノミーをより身近に感じていただくため、\n" response_txt += " ITBトークンを使った購入体験を提供したいと考えております。\n" response_txt += " 現在は有志によって運営されおりますが、持続可能な運営体制を構築してまいります。\n" response_txt += "\n" response_txt += "グッドコミュニケーションボーナスとは\n" response_txt += " 一般的なブロックチェーンはProof Of Workと呼ばれるコンセンサスアルゴリズムを使用しています。\n" response_txt += " 一方、ITBトークンは、Proof Of Happinessを採用しています。\n" response_txt += " 皆さんの良好なコミュニケーションがトークンの源泉になります。(適当\n" response_txt += "\n" response_txt += "ITB ヘルプ\n" response_txt += " ITBコンシェルジュサービスで利用できるコマンドと説明を表示します。\n" response_txt += "\n" response_txt += "ITB 入会\n" response_txt += " ITBコンシェルジュサービスに入会します。\n" response_txt += " 入会するとETHアドレスが新規発行され、ITBトークンを利用できるようになります。\n" response_txt += " 新規発行されたETHアドレスと秘密鍵は、入会したユーザーにDMで通知します。\n" response_txt += " サービスを提供するため、このアドレスの秘密鍵はコンシェルジュでもお預かりします。\n" response_txt += "\n" response_txt += "ITB 退会\n" response_txt += " ITBコンシェルジュサービスを退会します。\n" response_txt += "\n" response_txt += "ITB 残高照会\n" response_txt += " ITBトークンの残高を取得します。\n" response_txt += "\n" response_txt += "ITB 通知 (ON/OFF)\n" response_txt += " ITBコンシェルジュからの通知を受け取りたくない場合、OFFに設定します。\n" response_txt += "\n" response_txt += "ITBCafe 商品一覧\n" response_txt += " ITBCafeで購入できる商品一覧を取得します。\n" response_txt += "\n" response_txt += "ITBCafe 購入 {商品名}\n" response_txt += " ITBCafeで商品を購入します。\n" response_txt += "\n" response_txt += "ITBCafe 商品登録 {商品名} {商品価格}\n" response_txt += " ITBCafeで購入できる商品を登録します。\n" response_txt += "\n" response_txt += "ITBCafe 商品削除 {商品名}\n" response_txt += " ITBCafeで購入できる商品を削除します。\n" response_txt += "```" message.reply(response_txt)