Building a full-text ticket search system for support team

2018.02.15

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

In the previous post, we illustrated how to automatically upload Zendesk ticket data to an Amazon Elasticsearch Service.

Automatically upload Zendesk ticket data to an Amazon Elasticsearch Service

In this post, we illustrate how to build a full-text ticket search system for the support team using ChatWork.

Overview

画像

  • The user posts the keywords they want to search on ChatWork
  • POST request with ChatWork's Webhook
  • Execute AWS Lamdba (Amazon Virtual Private Cloud) using Amazon API Gateway.
    • Amazon API Gateway creates a POST method
    • We use a NAT gateway as internet access is required
    • Search on Amazon Elasticsearch Service on a VPC private subnet
  • Post search results to ChatWork

Implementation

ChatWork

We will begin by setting up ChatWork's Webhook.

画像

  • Webhook URL specifies the url of Amazon API Gateway.
  • Choose the Room Event and select the Message created checkbox.
  • This specifies the Room ID.

AWS Lambda

The code for AWS Lambda has been uploaded to Github. Here's a brief explanation of the code:

Get search keyward from ChatWork Webhook

lambda_function.py

keyword = event['webhook_event']['body']

Search using Amazon Elasticsearch Service

  • We try to find tickets that contain all the required keywords, using must of Bool Query.
  • We only get the subject and url of the ticket hit on search using _source.

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

Adjust search results to post to ChatWork

  • After converting the response to a list object, we create the content to post to 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

Post search results to ChatWork

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

Try searching

Create search keywords

画像

Response

画像

In descending order of score, the subject and URL of the ticket are listed.

Conclusion

We can now search for similar tickets by creating search keywords in ChatWork.