Exemple #1
0
class Api():
    def __init__(self, token, secret):
        self._app = Flask(__name__)
        self._api = LineBotApi(token)
        self._handler = WebhookHandler(secret)

        self.route()

    @_handler.add(MessageEvent, message=TextMessage)
    def callback(self):
        signature = request.headers['X-Line-Signature']

        body = request.get_data(as_text=True)
        self._app.logger.info("Request body: " + body)

        print(body, signature)
        self._handler.handle(body, signature)

        return 'OK'

    # @handler.add(MessageEvent, message=TextMessage)
    def pretty_echo(self, event):
        self._api.reply_message(event.reply_token,
                                TextSendMessage(text='text'))

    def route(self):
        self._handler.add(MessageEvent, message=TextMessage)

        self._app.add_url_rule('/callback',
                               methods=['POST'],
                               view_func=self.callback)

    def run(self, port=8080):
        self._app.run(port=port)
Exemple #2
0
class BotEcho:
    def __init__(self,event,access_token,channel_secret):
        self.event = event
        self.bot = LineBotApi(access_token)
        self.handler = WebhookHandler(channel_secret)
        self.body = json.loads(event['body'])['events'][0]
        self.sender_id = self.body['source']['userId']
        self.text_message = self.body['message']['text']
        self.log(sender=self.sender_id,to='self',message=self.text_message)
    @property
    def signature_check(self):
        signature = self.event['headers']['X-Line-Signature']
        try:
            self.handler.handle(self.event['body'], signature)
            return 200
        except InvalidSignatureError:
            return 400

    def send_reply(self,message):
        self.log(sender='self',to=self.sender_id,message=message)
        response = self.bot.reply_message(self.body['replyToken'], \
                                    TextSendMessage(text=message))
        return response

    def log(self,sender,to,message):
        log_head = ['to','message']
        log_value = [to, message]
        response = DynamoDB(table_name, key_name, sec_key_name)\
                                .put(sender,log_head,log_value)
        print(response)
        return response
Exemple #3
0
def lambda_handler(event, context):

    # LINE_USER_INFO
    YOUR_CHANNEL_ACCESS_TOKEN = os.environ["YOUR_CHANNEL_ACCESS_TOKEN"]
    YOUR_CHANNEL_SECRET = os.environ["YOUR_CHANNEL_SECRET"]

    line_bot_api = LineBotApi(YOUR_CHANNEL_ACCESS_TOKEN)
    handler = WebhookHandler(YOUR_CHANNEL_SECRET)

    # get X-Line-Signature header value
    signature = event["headers"]['x-line-signature']
    # get request body as text
    requestBody = event["body"]

    print("***GET REQUEST***\n", event)

    # add handler method
    @handler.add(MessageEvent)
    def text_message(line_event):
        try:
            if (line_event.message.type == 'image'):
                print("***画像を受信***")
                message_id = line_event.message.id
                message_content = line_bot_api.get_message_content(message_id)
                # # tempfileに受け付けた画像を書き込み
                with tempfile.NamedTemporaryFile(suffix='.jpg',
                                                 delete=False) as fp:
                    tempfile_name = fp.name
                    for chunk in message_content.iter_content():
                        fp.write(chunk)

                googleDrive_path = "https://drive.google.com/drive/folders/1P4of3548yOXKgygy2a-FwIkIN8Qx3yvr"
                message = f'ナイスファイト!ダァーー!\n{googleDrive_path}'

                line_bot_api.reply_message(line_event.reply_token,
                                           TextSendMessage(text=message))

                # tempfileの画像をgoogleDriveに転送
                sendMessage = uploadFileToGoogleDrive(tempfile_name)

            else:
                # 受付メッセージをおうむ返し
                text = f'「{line_event.message.text}」\n画像を送信しろ!!'
                line_bot_api.reply_message(line_event.reply_token,
                                           TextSendMessage(text=text))

        except Exception as e:
            line_bot_api.reply_message(line_event.reply_token,
                                       TextSendMessage(text=e))

    try:
        handler.handle(requestBody, signature)
    except LineBotApiError as e:
        logger.error("Got exception from LINE Messaging API: %s\n" % e.message)
        for m in e.error.details:
            logger.error("  %s: %s" % (m.property, m.message))
    except InvalidSignatureError:
        logger.error("sending message happen error")
    except Exception as e:
        logger.error("handler error\n", e)
Exemple #4
0
    def post(slef, request, channel_id):
        line_account    = get_object_or_404(LineAccounts, active=True, channel_id=channel_id)
        line_bot_api    = LineBotApi(line_account.channel_access_token)
        handler         = WebhookHandler(line_account.channel_secret)

        signature   = request.META.get('HTTP_X_LINE_SIGNATURE', '')
        body        = request.body.decode('utf-8')

        @handler.add(MessageEvent)
        def handle_message(event):
            contact = line_account.getProfile(event.source)
            chat_session_list = ChatSession.objects.filter(line_account=line_account, line_contact=contact, end_conversation_at=None)
            if not chat_session_list :
                token = hashlib.md5("{}.{}".format(contact.contact_id, str(datetime.now())).encode('utf-8')).hexdigest()
                chat_session = ChatSession(
                    token               = token,
                    line_account        = line_account,
                    line_contact        = contact,
                )
                chat_session.save()
            else:
                chat_session = chat_session_list.first()

            text = ''
            file = None
            image = None

            if event.message.type == 'text':
                text = event.message.text
            
            # status coversation 
            # 0 คือ Contact คุยกับ Line@
            # 1 คือ Line@ คุยกับ Contact
            # ChatSession.objects.filter(line_account=line_account, line_contact=line_contact)
            
            chat_message = ChatMessage(
                session             = chat_session,
                line_account        = line_account,
                line_contact        = contact,
                message_type        = event.message.type,
                text                = text,
                image               = image,
                file                = file,
                raw_data            = body,
                status_coversation  = 0
            )
            chat_message.save()

        try:
            
            handler.handle(body, signature)

            # if not line_channel.is_verify_webhook:  # Verify webhook
            #     line_channel.is_verify_webhook = True
            #     line_channel.save()
        except InvalidSignatureError:
            return HttpResponseBadRequest('400 - Bad request')

        return HttpResponse('OK')
class ChatbotHandler():
    def __init__(self, load_clients, redis=None):
        self.handler = WebhookHandler(os.environ.get('CHANNEL_SECRET'))
        self.bot = LineBotApi(os.environ.get('CHANNEL_ACCESS_TOKEN'))
        load_clients(ClientHandler(self.handler, self.bot, redis)).start()

    def handle(self, request, logger=None):
        body = request.get_data(as_text=True)
        if (logger):
            logger.info('Request body: {}'.format(body))
        self.handler.handle(body, request.headers.get('X-Line-Signature'))
Exemple #6
0
def verify_auth(request):

    channel_secret = config.get('CHANNEL_SECRET')
    handler = WebhookHandler(channel_secret)

    body = request.get_data(as_text=True)
    signature = request.headers['X-Line-Signature']

    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        print('Invalid signature.')
        return 'Invalid signature.', 400

    return 'OK'
def webhook():
    line_bot_api = LineBotApi(os.environ.get('LINE_CHANNEL_TOKEN'))
    handler = WebhookHandler(os.environ.get('LINE_CHANNEL_SECRET_KEY'))

    # get X-Line-Signature header value
    signature = request.headers['X-Line-Signature']

    body = request.get_data(as_text=True)
    event = json.loads(body)
    print(event)
    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        print(
            "Invalid signature. Please check your channel access token/channel secret.")
        abort(400)

    token = event['events'][0]['replyToken']
    if token == "00000000000000000000000000000000":
        pass
    else:
        line_bot_api.reply_message(token, TextSendMessage(
                text=event['events'][0]['message']['text']))
    return 'OK'
Exemple #8
0
 
 
## 1 ##
#Webhookからのリクエストをチェックします。
@app.route("/callback", methods=['POST'])
def callback():
    # リクエストヘッダーから署名検証のための値を取得します。
    signature = request.headers['X-Line-Signature']
 
    # リクエストボディを取得します。
    body = request.get_data(as_text=True)
    app.logger.info("Request body: " + body)
    # handle webhook body
 # 署名を検証し、問題なければhandleに定義されている関数を呼び出す。
    try:
        handler.handle(body, signature)
 # 署名検証で失敗した場合、例外を出す。
    except InvalidSignatureError:
        abort(400)
 # handleの処理を終えればOK
    return 'OK'
 
## 2 ##
###############################################
#LINEのメッセージの取得と返信内容の設定(オウム返し)
###############################################
 
#LINEでMessageEvent(普通のメッセージを送信された場合)が起こった場合に、
#def以下の関数を実行します。
#reply_messageの第一引数のevent.reply_tokenは、イベントの応答に用いるトークンです。 
#第二引数には、linebot.modelsに定義されている返信用のTextSendMessageオブジェクトを渡しています。
class TestWebhookHandler(unittest.TestCase):
    def setUp(self):
        self.handler = WebhookHandler('channel_secret')
        self.calls = []

        @self.handler.add(MessageEvent, message=TextMessage)
        def message_text(event):
            self.calls.append('1 ' + event.type + '_' + event.message.type)

        @self.handler.add(MessageEvent,
                          message=(ImageMessage, VideoMessage, AudioMessage))
        def message_content(event):
            self.calls.append('2 ' + event.type + '_' + event.message.type)

        @self.handler.add(MessageEvent, message=StickerMessage)
        def message_sticker(event):
            self.calls.append('3 ' + event.type + '_' + event.message.type)

        @self.handler.add(MessageEvent)
        def message(event):
            self.calls.append(event.type + '_' + event.message.type)

        @self.handler.add(FollowEvent)
        def follow(event):
            self.calls.append('4 ' + event.type)

        @self.handler.add(JoinEvent)
        def join(event):
            self.calls.append('5 ' + event.type)

        @self.handler.add(PostbackEvent)
        def postback(event):
            self.calls.append('6 ' + event.type)

        @self.handler.add(BeaconEvent)
        def beacon(event):
            self.calls.append('7 ' + event.type)

        @self.handler.default()
        def default(event):
            self.calls.append('default ' + event.type)

    def test_handler(self):
        file_dir = os.path.dirname(__file__)
        webhook_sample_json_path = os.path.join(file_dir, 'text',
                                                'webhook.json')
        with open(webhook_sample_json_path) as fp:
            body = fp.read()

        # mock
        self.handler.parser.signature_validator.validate = lambda a, b: True

        self.handler.handle(body, 'signature')

        self.assertEqual(self.calls[0], '1 message_text')
        self.assertEqual(self.calls[1], '2 message_image')
        self.assertEqual(self.calls[2], '2 message_video')
        self.assertEqual(self.calls[3], '2 message_audio')
        self.assertEqual(self.calls[4], 'message_location')
        self.assertEqual(self.calls[5], '3 message_sticker')
        self.assertEqual(self.calls[6], '4 follow')
        self.assertEqual(self.calls[7], 'default unfollow')
        self.assertEqual(self.calls[8], '5 join')
        self.assertEqual(self.calls[9], 'default leave')
        self.assertEqual(self.calls[10], '6 postback')
        self.assertEqual(self.calls[11], '7 beacon')
        self.assertEqual(self.calls[12], '7 beacon')
        self.assertEqual(self.calls[13], '1 message_text')
        self.assertEqual(self.calls[14], '1 message_text')
        self.assertEqual(self.calls[15], '6 postback')
        self.assertEqual(self.calls[16], '6 postback')
        self.assertEqual(self.calls[17], '6 postback')
Exemple #10
0
class TestWebhookHandler(unittest.TestCase):
    def setUp(self):
        self.handler = WebhookHandler('channel_secret')

        @self.handler.add(MessageEvent, message=TextMessage)
        def message_text(event, destination):
            self.assertEqual('message', event.type)
            self.assertEqual('text', event.message.type)
            self.assertEqual('U123', destination)

        @self.handler.add(MessageEvent,
                          message=(ImageMessage, VideoMessage, AudioMessage))
        def message_content(event):
            self.assertEqual('message', event.type)
            self.assertIn(event.message.type, ['image', 'video', 'audio'])

        @self.handler.add(MessageEvent, message=StickerMessage)
        def message_sticker(event):
            self.assertEqual('message', event.type)
            self.assertEqual('sticker', event.message.type)

        @self.handler.add(MessageEvent)
        def message(event):
            self.assertEqual('message', event.type)
            self.assertNotIn(event.message.type,
                             ['text', 'image', 'video', 'audio', 'sticker'])

        @self.handler.add(FollowEvent)
        def follow(event, destination):
            self.assertEqual('follow', event.type)
            self.assertEqual('U123', destination)

        @self.handler.add(JoinEvent)
        def join(event):
            self.assertEqual('join', event.type)

        @self.handler.add(PostbackEvent)
        def postback(event):
            self.assertEqual('postback', event.type)

        @self.handler.add(BeaconEvent)
        def beacon(event):
            self.assertEqual('beacon', event.type)

        @self.handler.add(AccountLinkEvent)
        def account_link(event):
            self.assertEqual('accountLink', event.type)

        @self.handler.default()
        def default(event):
            self.assertNotIn(event.type, [
                'message', 'follow', 'join', 'postback', 'beacon',
                'accountLink'
            ])

    def test_handler(self):
        file_dir = os.path.dirname(__file__)
        webhook_sample_json_path = os.path.join(file_dir, 'text',
                                                'webhook.json')
        with open(webhook_sample_json_path) as fp:
            body = fp.read()

        # mock
        self.handler.parser.signature_validator.validate = lambda a, b: True

        self.handler.handle(body, 'signature')
Exemple #11
0
class LineEventHandler():
    @classmethod
    def initialize(self):
        self.line_client = LineBotApi(
            str(os.environ.get('CHANNEL_ACCESS_TOKEN')))
        self.line_handler = WebhookHandler(
            str(os.environ.get('CHANNEL_SECRET')))

        # テキストメッセージハンドラ
        @self.line_handler.add(MessageEvent, message=TextMessage)
        def handle_message(event):
            url = os.environ.get('API_APP_MESSAGE')
            body = {
                'request_message': event.message.text,
                'user_id': event.source.user_id,
                'client': 'line',
                'config': {},
                'action': ''
            }

            @gen.coroutine
            def requestasync():
                http_client = httpclient.AsyncHTTPClient()
                http_req = httpclient.HTTPRequest(url, method='POST')
                http_req.headers = {
                    'Access-Token': os.environ['API_APP_ACCESS_TOKEN']
                }
                http_req.body = json.dumps(body).encode()
                raw_response = yield http_client.fetch(http_req)
                self.handle_response(event, raw_response)

            requestasync()

        # ポストバックアクションハンドラ
        @self.line_handler.add(PostbackEvent)
        def handle_message(event):
            print('hook')
            url = os.environ.get('API_APP_MESSAGE')
            body = {
                'request_message': '',
                'user_id': event.source.user_id,
                'client': 'line',
                'config': {},
                'action': event.postback.data
            }

            @gen.coroutine
            def requestasync():
                http_client = httpclient.AsyncHTTPClient()
                http_req = httpclient.HTTPRequest(url, method='POST')
                http_req.headers = {
                    'Access-Token': os.environ['API_APP_ACCESS_TOKEN']
                }
                http_req.body = json.dumps(body).encode()
                raw_response = yield http_client.fetch(http_req)
                self.handle_response(event, raw_response)

            requestasync()

        # 位置情報メッセージハンドラ
        @self.line_handler.add(MessageEvent, message=LocationMessage)
        def handle_message(event):
            url = os.environ.get('API_APP_ADDRESS')
            body = {
                'user_id': event.source.user_id,
                'longitude': event.message.longitude,
                'latitude': event.message.latitude
            }

            @gen.coroutine
            def requestasync():
                http_client = httpclient.AsyncHTTPClient()
                http_req = httpclient.HTTPRequest(url, method='POST')
                http_req.headers = {
                    'Access-Token': os.environ['API_APP_ACCESS_TOKEN']
                }
                http_req.body = json.dumps(body).encode()
                raw_response = yield http_client.fetch(http_req)
                self.handle_response(event, raw_response)

            requestasync()

    @classmethod
    def handle_request(self, body, signature):
        self.line_handler.handle(body, signature)

    @classmethod
    def handle_response(self, event, raw_response):
        raw_body = raw_response.body.decode('utf-8')
        response = json.loads(raw_body)
        reply = []
        for index, message in enumerate(response['messages']):
            mes = ResponseFactory.create_response(message)
            reply.append(mes)
        self.line_client.reply_message(event.reply_token, reply)
Exemple #12
0
class LineSDK():
    def __init__(self,
                 access_token: str,
                 channel_secret: str,
                 prefix: str = "!"):
        self.lineapi = LineBotApi(access_token)
        self.handler = WebhookHandler(channel_secret)
        self.prefix = prefix
        self.commands = {}
        self._pre_start()

    def handle(self, request) -> str:
        signature = request.headers['X-Line-Signature']
        body = request.get_data(as_text=True)

        try:
            self.handler.handle(body, signature)
        except InvalidSignatureError:
            print(
                "Invalid signature. Please check your channel access token/channel secret."
            )
            abort(400)
        return "OK"

    def on_command(self, cmd):
        command = f"{self.prefix}{cmd}"

        def decorate(function):
            self.commands[command] = function

        return decorate

    def parse_command(self, ctx, cmd, *args) -> bool:
        if cmd in self.commands:
            self.commands[cmd](ctx, *args)
            return True
        return False

    def on_message(self, event):
        ctx = Context(event, self.lineapi)
        splitted = shlex.split(event.message.text)
        self.parse_command(ctx, *splitted)
        return

    def on_follow(self, event):
        pass

    def on_unfollow(self, event):
        pass

    def on_join(self, event):
        pass

    def on_leave(self, event):
        pass

    def _pre_start(self):
        @self.handler.add(MessageEvent, message=TextMessage)
        def on_message(event):
            self.on_message(event)

        @self.handler.add(FollowEvent)
        def on_follow(event):
            self.on_follow(event)

        @self.handler.add(UnfollowEvent)
        def on_unfollow(event):
            self.on_unfollow(event)

        @self.handler.add(JoinEvent)
        def on_join(event):
            self.on_join(event)

        @self.handler.add(LeaveEvent)
        def on_leave(event):
            self.on_leave(event)
Exemple #13
0
class LINE(object):
    @staticmethod
    def get_key(event, message=None):
        if message is None:
            return event.__name__
        else:
            return event.__name__ + '_' + message.__name__

    def set_handler(self, callback, event, message=None):
        key = self.get_key(event, message=message)
        self.handler._handlers[key] = callback

    def __init__(self,
                 app,
                 api_token,
                 secret,
                 path='/line-callback',
                 name='line_callback'):
        self.app = app
        self.app.add_url_rule(path, name, self.callback, methods=['POST'])
        self.bot_api = LineBotApi(api_token)
        self.handler = WebhookHandler(secret)
        self.set_handler(self.got_text, MessageEvent, message=TextMessage)
        self.text_message = None
        self.command_call = {}
        self.unknown_command = "Ummm... This command not found."
        self.text_message = "Umm... This bot no reply feature."
        self._stop = True

    def Command(self, command, func, pass_args=False):
        self.command_call[command] = {}
        self.command_call[command]['call'] = func
        self.command_call[command]['args'] = pass_args

    def Start(self):
        self._stop = False

    def Stop(self):
        self._stop = True

    def Push(self, to, data, type='text'):
        if type == 'text':
            self.bot_api.push_message(to, TextSendMessage(text=data))

    def got_text(self, event):
        cmd = re_match(r'^\/(\w+)', event.message.text)
        if cmd:
            cmd = cmd.group(1)
            if cmd in self.command_call:
                if type(self.command_call[cmd]['call']) is str:
                    text = self.command_call[cmd]['call']
                    self.bot_api.reply_message(event.reply_token,
                                               TextSendMessage(text=text))
                elif self.command_call[cmd]['args']:
                    if ' ' in event.message.text:
                        args = event.message.text.split()
                        del args[0]
                        msg = Message('LINE')
                        msg.setEvent(bot=self.bot_api,
                                     event=event,
                                     args=args,
                                     type='command')
                        self.command_call[cmd]['call'](msg)
                    else:
                        msg = Message('LINE')
                        msg.setEvent(bot=self.bot_api,
                                     event=event,
                                     args=[],
                                     type='command')
                        self.command_call[cmd]['call'](msg)
                else:
                    msg = Message('LINE')
                    msg.setEvent(bot=self.bot_api, event=event, type='command')
                    self.command_call[cmd]['call'](msg)
            elif event.source.type not in ('room', 'group', 'supergroup'):
                text = self.unknown_command
                self.bot_api.reply_message(event.reply_token,
                                           TextSendMessage(text=text))
        else:
            if type(self.text_message) in (str, unicode):
                self.bot_api.reply_message(
                    event.reply_token, TextSendMessage(text=self.text_message))
            else:
                msg = Message('LINE')
                msg.setEvent(bot=self.bot_api, event=event, type='text')
                self.text_message(msg)

    def callback(self):
        if self._stop:
            abort(404)
        signature = request.headers['X-Line-Signature']
        body = request.get_data(as_text=True)
        self.app.logger.info("Request body: " + body)
        try:
            self.handler.handle(body, signature)
        except InvalidSignatureError:
            abort(400)
        return 'OK'
class TestWebhookHandler(unittest.TestCase):
    def setUp(self):
        self.handler = WebhookHandler('channel_secret')
        self.calls = []

        @self.handler.add(MessageEvent, message=TextMessage)
        def message_text(event):
            self.calls.append('1 ' + event.type + '_' + event.message.type)

        @self.handler.add(
            MessageEvent, message=(ImageMessage, VideoMessage, AudioMessage))
        def message_content(event):
            self.calls.append('2 ' + event.type + '_' + event.message.type)

        @self.handler.add(MessageEvent, message=StickerMessage)
        def message_sticker(event):
            self.calls.append('3 ' + event.type + '_' + event.message.type)

        @self.handler.add(MessageEvent)
        def message(event):
            self.calls.append(event.type + '_' + event.message.type)

        @self.handler.add(FollowEvent)
        def follow(event):
            self.calls.append('4 ' + event.type)

        @self.handler.add(JoinEvent)
        def join(event):
            self.calls.append('5 ' + event.type)

        @self.handler.add(PostbackEvent)
        def postback(event):
            self.calls.append('6 ' + event.type)

        @self.handler.add(BeaconEvent)
        def beacon(event):
            self.calls.append('7 ' + event.type)

        @self.handler.default()
        def default(event):
            self.calls.append('default ' + event.type)

    def test_handler(self):
        file_dir = os.path.dirname(__file__)
        webhook_sample_json_path = os.path.join(file_dir, 'text', 'webhook.json')
        with open(webhook_sample_json_path) as fp:
            body = fp.read()

        # mock
        self.handler.parser.signature_validator.validate = lambda a, b: True

        self.handler.handle(body, 'signature')

        self.assertEqual(self.calls[0], '1 message_text')
        self.assertEqual(self.calls[1], '2 message_image')
        self.assertEqual(self.calls[2], '2 message_video')
        self.assertEqual(self.calls[3], '2 message_audio')
        self.assertEqual(self.calls[4], 'message_location')
        self.assertEqual(self.calls[5], '3 message_sticker')
        self.assertEqual(self.calls[6], '4 follow')
        self.assertEqual(self.calls[7], 'default unfollow')
        self.assertEqual(self.calls[8], '5 join')
        self.assertEqual(self.calls[9], 'default leave')
        self.assertEqual(self.calls[10], '6 postback')
        self.assertEqual(self.calls[11], '7 beacon')
        self.assertEqual(self.calls[12], '7 beacon')
        self.assertEqual(self.calls[13], '1 message_text')
        self.assertEqual(self.calls[14], '1 message_text')
        self.assertEqual(self.calls[15], '6 postback')
        self.assertEqual(self.calls[16], '6 postback')
        self.assertEqual(self.calls[17], '6 postback')
Exemple #15
0
class BotService:
    def __init__(self):
        self.line_bot_api = LineBotApi(
            os.environ.get('YOUR_CHANNEL_ACCESS_TOKEN', ''))
        self.handler = WebhookHandler(os.environ.get('YOUR_CHANNEL_SECRET',
                                                     ''))
        self.lending_use_case = LendingUseCase(
            LendingRepositoryImpl(UserRepositoryImpl()))
        self.slack_service = SlackService()

        @self.handler.add(MessageEvent, message=TextMessage)
        def handle_message(event: MessageEvent):
            request_text: str = event.message.text
            split_request_text = request_text.split()

            if len(split_request_text) is not 2:
                self._response_random(event.reply_token)
                return

            request_message, lending_id = split_request_text

            lending = self.lending_use_case.fetch_lending(lending_id)
            content = lending.content
            owner_name = lending.owner_name
            borrower_id = lending.borrower_id
            is_confirming_returned = lending.is_confirming_returned

            if not is_confirming_returned:
                self._response_random(event.reply_token)
                return

            if request_message == 'はい':
                self.line_bot_api.reply_message(
                    event.reply_token, TextSendMessage(text='返ってきてよかったチュン!'))
                self.line_bot_api.push_message(
                    borrower_id,
                    TextSendMessage(
                        text=f"「{owner_name}」さんから借りた「{content}」返してくれてありがとチュン!")
                )
                self.lending_use_case.register_return_lending(lending_id)
                self.lending_use_case.finish_confirming_returned(lending_id)

            elif request_message == 'いいえ':
                self.line_bot_api.reply_message(event.reply_token, [
                    TextSendMessage(text='悲しいチュン...'),
                    TextSendMessage(text='早く返してって言ってくるチュン!')
                ])
                self.line_bot_api.push_message(
                    borrower_id,
                    TextSendMessage(
                        text=f"「{owner_name}」さんに借りた「{content}」返して欲しいチュン\n\n"
                        f"もし既に返してたら申し訳ないチュン...\n"
                        f"「{owner_name}」さんに通知解除してって言って欲しいチュン..."))
                self.lending_use_case.finish_confirming_returned(lending_id)

            else:
                self.line_bot_api.reply_message(
                    event.reply_token,
                    TextSendMessage(text='上のボタンをタップして答えて欲しいチュン。'))

    def _response_random(self, reply_token: str):
        self.line_bot_api.reply_message(
            reply_token, TextSendMessage(text=random.choice(random_messages)))

    def handle_hook(self, body, signature):
        self.handler.handle(body, signature)

    def send_message_for_deadline_lendings(self, notify: bool = True):
        deadline_lending_list = self.lending_use_case.fetch_deadline_lending_list(
        )

        if notify:
            list_len = len(deadline_lending_list)

            if list_len == 0:
                message = '今日が期限の貸借りはなかったチュン!\nみんなちゃんと返しててえらいチュン!'
            else:
                message = f"今日が締め切りの貸借りは{list_len}件だチュン!みんな返してもらえてるか確認してくるチュン!"

            webhook_username = '******'
            try:
                self.slack_service.notify(webhook_username, message)
            except Exception as e:
                print(e)

        with open(f"{root_path}/src/api/service/confirm_message.json") as f:
            base_contents = json.load(f)

        for owner_id, lendings in deadline_lending_list.items():
            messages = []

            for lending in lendings:
                self.lending_use_case.start_confirming_returned(
                    lending.lending_id)

                contents = base_contents.copy()

                message = f"「{lending.borrower_name}」さんに貸した「{lending.content}」返ってきたチュン?"
                contents['body']['contents'][0]['text'] = message

                # コールバックのエンドポイントに送信されるデータの末尾に、空白区切りで貸借りidを追加する
                contents['footer']['contents'][0]['action'][
                    'text'] += f" {lending.lending_id}"
                contents['footer']['contents'][1]['action'][
                    'text'] += f" {lending.lending_id}"

                messages.append(
                    FlexSendMessage(alt_text=message, contents=contents))

            self.line_bot_api.push_message(owner_id, messages)