オペ用チケット全文検索システムを作ってみた
はじめに
前回のブログで、zendeskのチケットデータをAmazon Elasticsearch Serviceへ自動でアップロードする方法をご紹介しました。
今回はサポートメンバーがAmazon Elasticsearch Serviceから類似チケットを ChatWorkを使用して検索できるようにしましたのでご紹介いたします。
Overview
- ユーザーは検索したいキーワードをChatWorkに投稿
- ChatWorkのWebhookでPOSTリクエスト
- Amazon API Gatewayを使用してAWS Lambda(VPC)を実行
- Amazon API Gateway はPOSTメソッド
- インターネットアクセスが必要なのでNAT ゲートウェイを使用
- VPCプライベートサブネットのAmazon Elasticsearch Serviceで検索
- 検索結果をChatWorkに投稿
設定内容
ChatWork
ChatWorkのWebhookの設定をします。
- Webhook URLに Amazon API Gateway で作成したURLを入力
- Eventは
Room Event
を選択しMessage created
にチェック - Room IDを指定
AWS Lambda
コードはgithubへアップしましたが簡単に説明します。
ChatWork Webhookで検索キーワードを取得
lambda_function.py
keyword = event['webhook_event']['body']
Amazon Elasticsearch Serviceで検索
- Bool Queryでmustを使いkeywordsが全て含まれるチケットを探すようにしています。
_source
で検索に引っかかったチケットの件名とurlだけ取得しています。
client/es.py
def get_document_and(self, keyword): must_keywords = [] keywords = keyword.split() for keyword in keywords: must_keyword = { "match": {"comment.body": keyword} } must_keywords.append(must_keyword) search_query = { "query": { "bool": { "must": [ must_keywords ] } }, "_source": [ "subject", "url" ] } response = self.es.search(index="zendesk", body=search_query) return response
検索結果を成形
- レスポンスをlistにしてからChatWorkに送る内容を作成しています。
lambda_function.py
tickets = [] for ticket_record in response['hits']['hits']: ticket = Ticket(ticket_record) tickets.append(ticket)
util/message.py
def get_message_body(message_id, reply_account, tickets, room_id): body = '' if not tickets: message = f'[rp aid={reply_account} to={room_id}-{message_id}]' + \ f'[info][title]Search Results(Sort by highest score)[/title]' + \ f'There is no result.[/info]' return message for ticket in tickets: body += ticket.subject + '\n' + ticket.url + '\n' message = f'[rp aid={reply_account} to={room_id}-{message_id}]' + \ f'[info][title]Search Results(Sort by highest score)[/title]' + \ f'{body}[/info]' return message
ChatWorkへ検索結果をPOSTする
client/chatwork.py
def post_messages(message, room_id): url = f'{URL}/rooms/{room_id}/messages' params = {"body": message} response = requests.post(url, headers=headers, params=params) return response
検索してみる
検索キーワードを入力
レスポンス
スコアの高い順に、チケットの件名とURLが返って来ました。
まとめ
ChatWorkに検索キーワードを作成するだけで誰もが類似チケットを検索できるようになりました。 ではまた