Exemplo n.º 1
0
def auto_reply_system(token, keyword, is_sticker_kw, src, is_kw_pic_sha=False):
    cid = line_api_proc.source_channel_id(src)

    if gb.is_group_set_to_silence(cid):
        return False

    res = kwd.get_reply(keyword, is_sticker_kw, is_kw_pic_sha)
    if res is not None:
        msg_track.log_message_activity(
            line_api_proc.source_channel_id(src),
            db.msg_event_type.recv_stk_repl
            if is_sticker_kw else db.msg_event_type.recv_txt_repl)
        result = res[0]
        reply_obj = db.kw_dict_mgr.split_reply(
            result[int(db.kwdict_col.reply)].decode('utf-8'),
            result[int(db.kwdict_col.is_pic_reply)])

        if result[int(db.kwdict_col.is_pic_reply)]:
            reply_object_list = [
                ImageSendMessage(original_content_url=reply_obj['main'],
                                 preview_image_url=reply_obj['main'])
            ]

            if reply_obj['attachment'] is not None:
                reply_object_list.append(
                    TextSendMessage(text=reply_obj['attachment']))

            api_reply(token, reply_object_list, src)
            return True
        else:
            api_reply(token, TextSendMessage(text=reply_obj['main']), src)
            return True

    return False
Exemplo n.º 2
0
def api_reply(reply_token, msgs, src):
    if not sys_data.silence:
        if not isinstance(msgs, (list)):
            msgs = [msgs]

        for index, msg in enumerate(msgs):
            if isinstance(msg, TemplateSendMessage):
                msg_track.log_message_activity(
                    line_api_proc.source_channel_id(src),
                    db.msg_event_type.send_stk)
            elif isinstance(msg, TextSendMessage):
                msg_track.log_message_activity(
                    line_api_proc.source_channel_id(src),
                    db.msg_event_type.send_txt)

                if len(msg.text) > 2000:
                    msgs[index] = TextSendMessage(
                        text=error.main.text_length_too_long(
                            webpage_generator.rec_text(msg.text)))

        line_api.reply_message(reply_token, msgs)
    else:
        print '=================================================================='
        print 'Bot set to silence. Expected message to reply will display below: '
        print msgs
        print '=================================================================='
Exemplo n.º 3
0
def handle_media_message(event):
    msg_track.log_message_activity(
        line_api_proc.source_channel_id(event.source),
        db.msg_event_type.recv_txt)
    return

    if isinstance(event.message, ImageMessage):
        ext = 'jpg'
    elif isinstance(event.message, VideoMessage):
        ext = 'mp4'
    elif isinstance(event.message, AudioMessage):
        ext = 'm4a'
    else:
        return

    message_content = line_api.get_content(event.message.id)
    with tempfile.NamedTemporaryFile(dir=static_tmp_path,
                                     prefix=ext + '-',
                                     delete=False) as tf:
        for chunk in message_content.iter_content():
            tf.write(chunk)
        tempfile_path = tf.name

    dist_path = tempfile_path + '.' + ext
    dist_name = os.path.basename(dist_path)
    os.rename(tempfile_path, dist_path)

    api_reply(event.reply_token, [
        TextSendMessage(text='Save content.'),
        TextSendMessage(text=request.host_url +
                        os.path.join('static', 'tmp', dist_name))
    ], event.source)
Exemplo n.º 4
0
def handle_location_message(event):
    msg_track.log_message_activity(
        line_api_proc.source_channel_id(event.source),
        db.msg_event_type.recv_txt)
    return

    api_reply(
        event.reply_token,
        LocationSendMessage(title=event.message.title,
                            address=event.message.address,
                            latitude=event.message.latitude,
                            longitude=event.message.longitude), event.source)
Exemplo n.º 5
0
def handle_image_message(event):
    msg_track.log_message_activity(
        line_api_proc.source_channel_id(event.source),
        db.msg_event_type.recv_pic)

    src = event.source
    token = event.reply_token
    msg = event.message

    cid = line_api_proc.source_channel_id(src)

    try:
        image_sha = img_executor.image_sha224_of_message(msg)
        sys_data.set_last_pic_sha(cid, image_sha)

        if isinstance(src, SourceUser):
            image_uploaded = img_executor.upload_imgur(msg)

            send_message_list = [
                TextSendMessage(text=u'檔案雜湊碼(SHA224)'),
                TextSendMessage(text=image_sha)
            ]
            send_message_list.extend(
                [TextSendMessage(text=txt) for txt in image_uploaded])

            api_reply(token, send_message_list, src)
        else:
            auto_reply_system(token, image_sha, False, src, True)
    except Exception as exc:
        text = u'開機時間: {}\n\n'.format(sys_data.boot_up)
        exc_type, exc_obj, exc_tb = sys.exc_info()
        text += u'錯誤種類: {}\n\n第{}行 - {}'.format(exc_type, exc_tb.tb_lineno,
                                                exc.message.decode("utf-8"))

        error_msg = webpage_generator.rec_error(
            text,
            traceback.format_exc().decode('utf-8'),
            line_api_proc.source_channel_id(src))
        api_reply(token, TextSendMessage(text=error_msg), src)
Exemplo n.º 6
0
def intercept_text(event):
    src = event.source
    uid = line_api_proc.source_user_id(src)

    user_profile = line_api.profile(uid, src)

    print '==========================================='
    print 'From Channel ID \'{}\''.format(line_api_proc.source_channel_id(src))
    print 'From User ID \'{}\' ({})'.format(
        uid, 'unknown' if user_profile is None else
        (user_profile.display_name.encode('utf-8')
         if user_profile.display_name is not None else '(Empty)'))
    print 'Message \'{}\''.format(event.message.text.encode('utf-8'))
    print '=================================================================='
Exemplo n.º 7
0
def handle_join(event):
    src = event.source
    reply_token = event.reply_token
    cid = line_api_proc.source_channel_id(src)

    global command_executor

    if not isinstance(event.source, SourceUser):
        group_data = gb.get_group_by_id(cid)
        if group_data is None:
            added = gb.new_data(cid, MAIN_UID, administrator)
            msg_track.new_data(cid)

            api_reply(reply_token, [
                TextMessage(
                    text=u'群組資料註冊{}。'.format(u'成功' if added else u'失敗')),
                introduction_template()
            ], src)
        else:
            api_reply(reply_token, [
                TextMessage(text=u'群組資料已存在。'),
                TextMessage(text=command_exec.G(src, [None, None, None])),
                introduction_template()
            ], cid)
Exemplo n.º 8
0
def handle_sticker_message(event):
    package_id = event.message.package_id
    sticker_id = event.message.sticker_id
    rep = event.reply_token
    src = event.source

    try:
        cid = line_api_proc.source_channel_id(src)

        sys_data.set_last_sticker(cid, sticker_id)

        global game_data
        rps_obj = game_data.get_rps(cid)

        msg_track.log_message_activity(cid, db.msg_event_type.recv_stk)

        if rps_obj is not None:
            text = minigame_rps_capturing(rps_obj, True, sticker_id,
                                          line_api_proc.source_user_id(src))
            if text is not None:
                api_reply(rep, TextSendMessage(text=text), src)
                return

        if isinstance(event.source, SourceUser):
            results = kwd.search_sticker_keyword(sticker_id)

            if results is not None:
                kwdata = u'相關回覆組ID: {}。\n'.format(u', '.join([
                    unicode(result[int(db.kwdict_col.id)])
                    for result in results
                ]))
            else:
                kwdata = u'無相關回覆組ID。\n'

            api_reply(rep, [
                TextSendMessage(
                    text=kwdata +
                    u'貼圖圖包ID: {}\n貼圖圖片ID: {}'.format(package_id, sticker_id)),
                TextSendMessage(
                    text=
                    u'圖片路徑(Android):\nemulated\\0\\Android\\data\\jp.naver.line.android\\stickers\\{}\\{}'
                    .format(package_id, sticker_id)),
                TextSendMessage(
                    text=
                    u'圖片路徑(Windows):\nC:\\Users\\USER_NAME\\AppData\\Local\\LINE\\Data\\Sticker\\{}\\{}'
                    .format(package_id, sticker_id)),
                TextSendMessage(text=u'圖片路徑(網路):\n{}'.format(
                    db.kw_dict_mgr.sticker_png_url(sticker_id)))
            ], src)
        else:
            auto_reply_system(rep, sticker_id, True, src)
    except exceptions.LineBotApiError as ex:
        text = u'開機時間: {}\n\n'.format(sys_data.boot_up)
        text += u'LINE API發生錯誤,狀態碼: {}\n\n'.format(ex.status_code)
        for err in ex.error.details:
            text += u'錯誤內容: {}\n錯誤訊息: {}\n'.format(err.property,
                                                   err.message.decode("utf-8"))

        error_msg = webpage_generator.rec_error(
            text,
            traceback.format_exc().decode('utf-8'),
            line_api_proc.source_channel_id(src))
        api_reply(rep, TextSendMessage(text=error_msg), src)
    except Exception as exc:
        text = u'開機時間: {}\n\n'.format(sys_data.boot_up)
        exc_type, exc_obj, exc_tb = sys.exc_info()
        text += u'錯誤種類: {}\n\n第{}行 - {}'.format(exc_type, exc_tb.tb_lineno,
                                                exc.message.decode("utf-8"))

        error_msg = webpage_generator.rec_error(
            text,
            traceback.format_exc().decode('utf-8'),
            line_api_proc.source_channel_id(src))
        api_reply(rep, TextSendMessage(text=error_msg), src)
Exemplo n.º 9
0
def handle_text_message(event):
    global game_data
    global command_executor
    global game_executor

    token = event.reply_token
    text = event.message.text
    src = event.source
    splitter = '\n'

    # IMPORTANT: linked keyword (test block)
    if text == 'confirm':
        carousel_template = CarouselTemplate(columns=[
            CarouselColumn(text='Linked 1~3',
                           title='Linked 1~3 (Title)',
                           actions=[
                               MessageTemplateAction(label='1 (ACTUAL)',
                                                     text='小水母'),
                               MessageTemplateAction(label='2', text='LINKED'),
                               MessageTemplateAction(label='3', text='LINKED')
                           ]),
            CarouselColumn(text='Linked 4~6',
                           title='Linked 4~6 (Title)',
                           actions=[
                               MessageTemplateAction(label='4', text='LINKED'),
                               MessageTemplateAction(label='5', text='LINKED'),
                               MessageTemplateAction(label='6', text='LINKED')
                           ]),
            CarouselColumn(text='Linked 7~9',
                           title='Linked 7~9 (Title)',
                           actions=[
                               MessageTemplateAction(label='1', text='LINKED'),
                               MessageTemplateAction(label='2', text='LINKED'),
                               MessageTemplateAction(label='3', text='LINKED')
                           ]),
            CarouselColumn(text='Linked 10~12',
                           title='Linked 10~12 (Title)',
                           actions=[
                               MessageTemplateAction(label='1', text='LINKED'),
                               MessageTemplateAction(label='2', text='LINKED'),
                               MessageTemplateAction(label='3', text='LINKED')
                           ]),
            CarouselColumn(text='Linked 13~15',
                           title='Linked 13~15 (Title)',
                           actions=[
                               MessageTemplateAction(label='1', text='LINKED'),
                               MessageTemplateAction(label='2', text='LINKED'),
                               MessageTemplateAction(label='3', text='LINKED')
                           ])
        ])
        template_message = TemplateSendMessage(
            alt_text='Linked word template (Related ID: 1, 2, 3...15)',
            template=carousel_template)
        api_reply(event.reply_token, template_message, src)

    try:
        if text == '561563ed706e6f696abbe050ad79cf334b9262da6f83bc1dcf7328f2':
            sys_data.intercept = not sys_data.intercept
            api_reply(
                token,
                TextSendMessage(text='Bot {}.'.format(
                    'start to intercept messages' if sys_data.
                    intercept else 'stop intercepting messages')), src)
            return
        elif sys_data.intercept:
            intercept_text(event)

        if text == administrator:
            line_api.reply_message(
                token,
                TextSendMessage(text='Bot set to {}.'.format(
                    'Active' if sys_data.silence else 'Silent')))
            sys_data.silence = not sys_data.silence
            return
        elif sys_data.silence:
            return

        if text == '43afdb2391686dd9710c3879a86c04b5c0a2fc3391ffd2c6a05e4ce0':
            sys_data.calc_debug = not sys_data.calc_debug
            api_reply(
                token,
                TextSendMessage(text='Calculator debugging {}.'.format(
                    'enabled' if sys_data.calc_debug else 'disabled')), src)
            return

        msg_track.log_message_activity(line_api_proc.source_channel_id(src),
                                       db.msg_event_type.recv_txt)

        if text == 'ERRORERRORERRORERROR':
            raise Exception('THIS ERROR IS CREATED FOR TESTING PURPOSE.')
        elif splitter in text:
            head, cmd, oth = msg_handler.split(text, splitter, 3)
            head = head.replace(' ', '')
            cmd = cmd.replace(' ', '')

            if head == 'JC':
                params = command_executor.split_verify(cmd, splitter, oth)

                if isinstance(params, unicode):
                    api_reply(token, TextSendMessage(text=params), src)
                    return
                else:
                    sys_data.sys_cmd_dict[cmd].count += 1

                # SQL Command
                if cmd == 'S':
                    text = command_executor.S(src, params)

                    api_reply(token, TextSendMessage(text=text), src)
                # ADD keyword & ADD top keyword
                elif cmd == 'A' or cmd == 'M':
                    if sys_data.sys_cmd_dict[cmd].non_user_permission_required:
                        text = command_executor.M(src, params)
                    else:
                        text = command_executor.A(src, params)

                    api_reply(token, TextSendMessage(text=text), src)
                # DELETE keyword & DELETE top keyword
                elif cmd == 'D' or cmd == 'R':
                    if sys_data.sys_cmd_dict[cmd].non_user_permission_required:
                        text = command_executor.R(src, params)
                    else:
                        text = command_executor.D(src, params)

                    api_reply(token, TextSendMessage(text=text), src)
                # QUERY keyword
                elif cmd == 'Q':
                    text = command_executor.Q(src, params)

                    api_reply(token, TextSendMessage(text=text), src)
                # INFO of keyword
                elif cmd == 'I':
                    text = command_executor.I(src, params)

                    api_reply(token, TextSendMessage(text=text), src)
                # RANKING
                elif cmd == 'K':
                    text = command_executor.K(src, params)

                    api_reply(token, TextSendMessage(text=text), src)
                # SPECIAL record
                elif cmd == 'P':
                    text = command_executor.P(src, params, oxr_client)

                    api_reply(token, TextSendMessage(text=text), src)
                # GROUP ban basic (info)
                elif cmd == 'G':
                    text = command_executor.G(src, params)

                    api_reply(token, TextSendMessage(text=text), src)
                # GROUP ban advance
                elif cmd == 'GA':
                    texts = command_executor.GA(src, params)

                    api_reply(token,
                              [TextSendMessage(text=text) for text in texts],
                              src)
                # get CHAT id
                elif cmd == 'H':
                    output = command_executor.H(src, params)

                    api_reply(token, [
                        TextSendMessage(text=output[0]),
                        TextSendMessage(text=output[1])
                    ], src)
                # SHA224 generator
                elif cmd == 'SHA':
                    text = command_executor.SHA(src, params)

                    api_reply(token, TextSendMessage(text=text), src)
                # Look up vocabulary in OXFORD Dictionary
                elif cmd == 'O':
                    text = command_executor.O(src, params)

                    api_reply(token, TextSendMessage(text=text), src)
                # RANDOM draw
                elif cmd == 'RD':
                    text = command_executor.RD(src, params)

                    api_reply(token, TextSendMessage(text=text), src)
                # last STICKER message
                elif cmd == 'STK':
                    text = command_executor.STK(src, params)

                    api_reply(token, TextSendMessage(text=text), src)
                # SHA224 of last PICTURE
                elif cmd == 'PIC':
                    text_tuple = command_executor.PIC(src, params)

                    api_reply(
                        token,
                        [TextSendMessage(text=text)
                         for text in text_tuple], src)
                # TRANSLATE text to URL form
                elif cmd == 'T':
                    text = command_executor.T(src, params)

                    api_reply(token, TextSendMessage(text=text), src)
                # CURRENCY exchange
                elif cmd == 'C':
                    text = command_executor.C(src, params, oxr_client)

                    api_reply(token, TextSendMessage(text=text), src)
                else:
                    sys_data.sys_cmd_dict[cmd].count -= 1
            elif head == 'HELP':
                params = helper_executor.split_verify(cmd, splitter, oth)

                if isinstance(params, unicode):
                    api_reply(token, TextSendMessage(text=params), src)
                    return
                else:
                    sys_data.helper_cmd_dict[cmd].count += 1

                if cmd == 'MFF':
                    message_instance = helper_executor.MFF(params)

                    api_reply(token, message_instance, src)
            elif head == 'G':
                if cmd not in sys_data.game_cmd_dict:
                    text = error.main.invalid_thing(u'遊戲', cmd)
                    api_reply(token, TextSendMessage(text=text), src)
                    return

                max_prm = sys_data.game_cmd_dict[cmd].split_max
                min_prm = sys_data.game_cmd_dict[cmd].split_min
                params = msg_handler.split(oth, splitter, max_prm)

                if min_prm > len(params) - params.count(None):
                    text = error.main.lack_of_thing(u'參數')
                    api_reply(token, TextSendMessage(text=text), src)
                    return

                params.insert(0, None)

                # GAME - Rock-Paper-Scissor
                if cmd == 'RPS':
                    text = game_executor.RPS(src, params)

                    api_reply(token, TextSendMessage(text=text), src)
                else:
                    sys_data.game_cmd_dict[cmd].count -= 1
            elif head == 'FX':
                calc_str = cmd + ('' if oth is None else splitter + oth)

                # IMPORTANT: temp, add analysis
                calc_result = str_calc.calculate(calc_str, sys_data.calc_debug,
                                                 True)
                sys_data.helper_cmd_dict['CALC'].count += 1

                result_str = calc_result.get_basic_text()

                if calc_result.over_length:
                    text = u'因算式結果長度大於100字,為避免洗板,請點選網址察看結果。\n{}'.format(
                        webpage_generator.rec_text(result_str))
                else:
                    text = result_str

                if calc_result.latex_avaliable:
                    text += u'\nLaTeX URL:\n{}'.format(
                        webpage_generator.rec_latex(calc_result.latex))

                api_reply(token, TextSendMessage(text=text), src)

        rps_obj = game_data.get_rps(line_api_proc.source_channel_id(src))
        if rps_obj is not None:
            rps_text = minigame_rps_capturing(
                rps_obj, False, text, line_api_proc.source_user_id(src))
            if rps_text is not None:
                api_reply(token, TextSendMessage(text=rps_text), src)
                return

        replied = auto_reply_system(token, text, False, src)
        if not replied:
            if (text.startswith('JC ') or text.startswith('HELP ')
                    or text.startswith('G ')) and ((' ' or '  ') in text):
                msg = u'小水母指令分隔字元已從【雙空格】修改為【換行】。'
                msg += u'\n\n如欲輸入指令,請以換行分隔指令,例如:\nJC\nA\n你!\n我?'
                msg += u'\n\n如果參數中要包含換行的話,請輸入【\\n】。\n另外,JC RD的文字抽籤中,原先以換行分隔,現在則以單空格分隔。'
                text = error.main.miscellaneous(msg)
                api_reply(token, TextSendMessage(text=text), src)
                return
            else:
                calc_result = str_calc.calculate(text, sys_data.calc_debug)
                if calc_result.success or calc_result.timeout:
                    sys_data.helper_cmd_dict['CALC'].count += 1

                    result_str = calc_result.get_basic_text()

                    if calc_result.over_length:
                        text = u'因算式結果長度大於100字,為避免洗板,請點選網址察看結果。\n{}'.format(
                            webpage_generator.rec_text(result_str))
                    else:
                        text = result_str

                    api_reply(token, TextSendMessage(text=text), src)
                    return
    except LineBotApiError as ex:
        text = u'開機時間: {}\n\n'.format(sys_data.boot_up)
        text += u'LINE API發生錯誤,狀態碼: {}\n\n'.format(ex.status_code)
        text += u'錯誤內容: {}'.format(ex.error.as_json_string())

        error_msg = webpage_generator.rec_error(
            text,
            traceback.format_exc().decode('utf-8'),
            line_api_proc.source_channel_id(src))
        if ex.status_code != 429:
            api_reply(token, TextSendMessage(text=error_msg), src)
    except Exception as exc:
        text = u'開機時間: {}\n\n'.format(sys_data.boot_up)
        exc_type, exc_obj, exc_tb = sys.exc_info()
        text += u'錯誤種類: {}\n\n第{}行 - {}'.format(exc_type, exc_tb.tb_lineno,
                                                exc.message.decode("utf-8"))

        error_msg = webpage_generator.rec_error(
            text,
            traceback.format_exc().decode('utf-8'),
            line_api_proc.source_channel_id(src))
        api_reply(token, TextSendMessage(text=error_msg), src)
Exemplo n.º 10
0
    def RPS(self, src, params):
        cid = line_api_proc.source_channel_id(src)
        uid = line_api_proc.source_user_id(src)

        if params[4] is not None:
            rps_obj = self._game_data.get_rps(cid)
            if rps_obj is not None and isinstance(rps_obj, game.rps):
                action = params[1]
                if action == 'ADD':
                    item_type = params[2]
                    is_sticker = params[3]
                    content = params[4]

                    battle_item = None

                    if item_type == 'R':
                        battle_item = game.battle_item.rock
                    if item_type == 'P':
                        battle_item = game.battle_item.paper
                    if item_type == 'S':
                        battle_item = game.battle_item.scissor

                    if battle_item is not None:
                        if is_sticker == 'STK':
                            if string_can_be_int(content):
                                rps_obj.register_battle_item(battle_item, True, content)
                                text = rps_obj.battle_item_dict_text()
                            else:
                                text = error.main.incorrect_param(u'參數4', u'整數,以代表貼圖ID')
                        elif is_sticker == 'TXT':
                            rps_obj.register_battle_item(battle_item, False, content)
                            text = rps_obj.battle_item_dict_text()
                        else:
                            text = error.main.incorrect_param(u'參數3', u'STK(是貼圖ID)或TXT(文字訊息)')
                    else:
                        text = error.main.incorrect_param(u'參數2', u'S(剪刀)、R(石頭)或P(布)')
                else:
                    text = error.main.incorrect_param(u'參數1', u'ADD')
            else:
                text = error.main.miscellaneous(u'尚未建立猜拳遊戲。')
        elif params[3] is not None:
            scissor = params[1]
            rock = params[2]
            paper = params[3]

            rps_obj = game.rps(True if isinstance(src, SourceUser) else False, rock, paper, scissor)
            if isinstance(rps_obj, game.rps):
                if line_api_proc.is_valid_user_id(uid):
                    rps_obj.register_player(self._line_api.profile(uid).display_name, uid)
                    text = u'遊戲建立成功。\n\n剪刀貼圖ID: {}\n石頭貼圖ID: {}\n布貼圖ID: {}'.format(scissor, rock, paper)
                    self._game_data.set_rps(cid, rps_obj)
                else:
                    text = error.main.unable_to_receive_user_id()
            else:
                text = rps_obj
        elif params[2] is not None:
            rps_obj = self._game_data.get_rps(cid)
            if rps_obj is not None and isinstance(rps_obj, game.rps):
                action = params[1]
                battle_item_text = params[2]

                if action == 'RST':
                    if battle_item_text == 'R':
                        rps_obj.reset_battle_item(game.battle_item.rock)
                        text = u'已重設代表【石頭】的物件。'
                    elif battle_item_text == 'P':
                        rps_obj.reset_battle_item(game.battle_item.paper)
                        text = u'已重設代表【布】的物件。'
                    elif battle_item_text == 'S':
                        rps_obj.reset_battle_item(game.battle_item.scissor)
                        text = u'已重設代表【剪刀】的物件。'
                    else:
                        text = error.main.incorrect_param(u'參數2', u'R(石頭), P(布), S(剪刀)')
                else:
                    text = error.main.incorrect_param(u'參數1', u'RST')
            else:
                text = error.main.miscellaneous(u'尚未建立猜拳遊戲。')
        elif params[1] is not None:
            rps_obj = self._game_data.get_rps(cid)
            action = params[1]

            if rps_obj is not None and isinstance(rps_obj, game.rps):
                if action == 'DEL':
                    self._game_data.del_rps(cid)
                    text = u'猜拳遊戲已刪除。'
                elif action == 'RST':
                    rps_obj.reset_statistics()
                    text = u'猜拳遊戲統計資料已重設。'
                elif action == 'R':
                    text = rps_obj.battle_item_dict_text(game.battle_item.rock)
                elif action == 'P':
                    text = rps_obj.battle_item_dict_text(game.battle_item.paper)
                elif action == 'S':
                    text = rps_obj.battle_item_dict_text(game.battle_item.scissor)
                elif action == 'PLAY':
                    uid = line_api_proc.source_user_id(src)
                    if line_api_proc.is_valid_user_id(uid):
                        player_name = self._line_api.profile(uid).display_name
                        reg_success = rps_obj.register_player(player_name, uid)
                        if reg_success:
                            text = u'成功註冊玩家 {}。'.format(player_name)
                        else:
                            text = u'玩家 {} 已存在於玩家清單中。'.format(player_name)
                    else:
                        text = error.main.unable_to_receive_user_id()
                elif action == 'SW':
                    rps_obj.enabled = not rps_obj.enabled
                    if rps_obj.enabled:
                        text = u'遊戲已繼續。'
                    else:
                        text = u'遊戲已暫停。'
                else:
                    text = error.main.incorrect_param(u'參數1', u'DEL, RST, R, P, S, PLAY, SW')
            else:
                text = error.main.miscellaneous(u'尚未建立猜拳遊戲。')
        else:
            rps_obj = self._game_data.get_rps(cid)
            if rps_obj is not None and isinstance(rps_obj, game.rps):
                if rps_obj.player_dict is not None and len(rps_obj.player_dict) > 0:
                    text = game.rps.player_stats_text(rps_obj.player_dict)
                    text += '\n\n'
                    text += rps_obj.battle_item_dict_text()
                else:
                    text = error.main.miscellaneous(u'無玩家資料。')
            else:
                text = error.main.miscellaneous(u'尚未建立猜拳遊戲。')

        return text