API GatewayとLambdaでZendeskトリガのカスタマイズをする

ベルリンの半瀬です。

クラスメソッドではZendeskをお客様のお問い合わせの管理に利用していますが、私は管理者として設定周りをいじることが多いので、そのメモをよくこのブログに書いています。

(プチ前段:読み飛ばし可
Zendeskではお客様のお問い合わせ1つ1つはチケット化されますが、自動化機能として「トリガ」というものが用意されており、チケットもつステータスの変化に応じて様々なアクションを自動で実行できるようになっています。例えば、 - 「チケットのステータスが "新規"から"解決"になった」場合に「お客様にメールを送信する」 - 「チケットにお客様から新しいコメントが入った」場合に「担当者全員にメールを送信する」 などといったものです。 この場合分けの判定は様々な条件が用意されており、複数の条件を課することも可能です。
新しいお問い合わせがあった時に、「営業時間外か・営業時間内か」、などによって自動返信の文言内容を変えることなども可能です。

本日の投稿はそのトリガに関するメモです。

はじめに

チケットのステータス変更に応じて社内メモをチケットに残す動作をトリガで実行したかったのですが、アクションにはチケット内容そのものの更新(パブリック返信や社内メモを追加する)に関するアクションが用意されていないようでした。なので、簡単にLambdaとAPI Gatewayを使用してチケット操作を作ってみました。

材料

テストにはZendesk 管理者権限のアカウントが必要です。Sandboxなどで実行するとよいかと思います。

Pythonで以下のようなスクリプトを準備します。

from __future__ import print_function

import pycurl
import json

chk_user = "{{ユーザー: お好みの文字列}}"
chk_pass = "{{パスワード: お好みの文字列}}"

def lambda_handler(event, context):
    if event['user'] == chk_user and event['pass'] == chk_pass :
        url = 'https://' + str(event['url']).replace('agent', 'api/v2') + '.json'
        
        username = str(event['username'])
        password = str(event['password'])
        data = json.dumps(event['data'])

        header = 'Content-Type: application/json'

        c = pycurl.Curl()
        c.setopt(pycurl.URL, url)
        c.setopt(pycurl.HTTPHEADER, [header])
        c.setopt(pycurl.POST, 1)
        c.setopt(pycurl.CUSTOMREQUEST, "PUT")
        c.setopt(pycurl.USERPWD, '%s/token:%s' % (username, password))
        c.setopt(pycurl.POSTFIELDSIZE, -1)
        c.setopt(pycurl.POSTFIELDS, '%s' % data)

        c.perform()
        c.close()

        print(data)

    else :
        print('not authorized request.')

エラー処理などは省略。この記事での確認用に print() をしています。

AWS Lambda関数を作成します

前項で作ったスクリプトをあげます。
「コードをインラインで編集」で、そのまま貼り付けます。
chk_user, chk_passはZendeskからのアクセスのみに絞るために、適当な文字列を放り込んでおきます。
20170420-01
チケットのアップデートをするので「test-update」と名付けます。

API Gatewayを準備します。

テスト用のAPI「hanse」に設定していきます。

新しいリソースを準備

今回は、Lambda関数名と同じ「test-update」とします。
20170420-02

メソッドを準備

POSTメソッドを作成します。統合ポイントにLambda関数を指定し、先ほど作成した関数「test-update」を指定します。
20170420-03
できました
20170420-04

ステージにデプロイ

ステージ名は「prod」とします。
20170420-05
できました
20170420-06
今回作成したAPIのパスは、「https://xxxxxxx.amazonaws.com/prod/test-update」となります。

Zendeskの設定をします

APIトークンを準備

Zendesk管理画面にログインし、画面左側のギアのマークから管理設定画面に遷移します。
<チャネル:API>で新しいAPIトークンを作成します。
20170420-07
APIトークンは作成後に管理画面上で確認できなくなりますので、メモなどにとっておきます。
メモに取ったら「保存」を押して作成を完了します。

拡張機能を準備

API Gatewayの先にあるLambdaを実行するために、ZendeskからHTTPリクエストをするアクションを作成します。
管理画面左側のギアのマークから管理設定画面に遷移します。
<設定:拡張機能>で表示される一覧から「HTTPターゲット」を選択します。
20170420-08
HTTPターゲットの詳細設定画面では、先ほど作成したAPI Gateway のURL「https://xxxxxxx.amazonaws.com/prod/test-update」を記載、「方法」は「POST」、「コンテンツタイプ」に「JSON」を選択して「ターゲットの作成」を実行します。
20170420-09
できました。
20170420-10

テストトリガの設定

トリガの設定をして完了です。
管理画面<ビジネスルール:トリガ>で作成を行います。
20170420-11
トリガ条件は最もシンプルに「チケットが"解決済み"に変更された」ケースとします。
「次の全ての条件を満たす」というコーナーで設定。
アクション実行は前項で用意した拡張機能「test-update」を指定。POSTするJSONボディの欄が表示されますので、以下のjsonを記載します。

{
  "user": "{python側で設定したchk_userの文字列}",
  "pass": "{python側で設定したchk_passの文字列}",
  "url": "{{ticket.url}}",
  "username": "{APIトークンを発行したユーザー}",
  "password": "{発行したAPIトークン文字列}",
  "data": {
    "ticket": {
      "comment": { 
        "body": "ステータス解決になりました。", 
        "public": false 
      }
    }
  }
}
  • user, pass: python側で書いたものを記載(簡単に認証)。
  • url: 固定文字列 {{ticket.url}} プレースホルダという機能を利用して、Zendesk側でチケットのURLを動的に入力してくれます。
  • username: APIトークンを発行したユーザーのメールアドレスになります。
  • password: 上の項で発行したAPIトークンを記載
  • data: 実行したいupdate動作をここに記載します。上の例では 「ステータス解決になりました」というコメントを「社内メモ(puclic=false)」で追加する、という動作となっています。ここのAPI実行を参考に動作をカスタマイズすることも可能かと思います。

これでトリガは完成です。

テスト実行

テスト実行をしてみます。下のような「オープン」ステータスのチケットを作成し、 20170420-12

ステータスを「解決済み」に変更すると。。
20170420-13

APIGateway経由で社内メモが入りました!!

以上です。
蛇足ですが、Lambda側でprint()していた箇所のログ。
20170420-14

最後に

Zendeskトリガーのカスタマイズ方法のメモでした。
Zendeskトリガーでは様々な機能が用意されていますが、現行で準備がないものもZendesk APIを実行することでかなりやれることが増えます。どうやったらやりたい動きができるか試行錯誤しながら処理を作っていくのは結構楽しいです。

ではまた。