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
Beispiel #2
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()
Beispiel #3
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.reply(
            f"""\
```
{new_line.join(output_list).strip(new_line)}
```""",
            in_thread=True,
        )
Beispiel #4
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)
Beispiel #6
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)
Beispiel #7
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,
            )
Beispiel #8
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,
        )
Beispiel #9
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()
Beispiel #10
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()
Beispiel #11
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()
Beispiel #12
0
def echo(message: Message):
    message.reply(f"got {message.body.get('text')}")
Beispiel #13
0
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()
Beispiel #14
0
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()
Beispiel #15
0
def hi(msg: Message):
    msg.reply("Thank you!!")
Beispiel #16
0
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()
Beispiel #17
0
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()
Beispiel #18
0
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)