Life is Like a Boat

忘備録や経済、投資、プログラミングに関するメモやtipsなど

Django + Zendesk APIで問い合わせフォームを作る

DjangoでWebサイト作ると間違いなく問い合わせフォームを作ると思います。

Djangoだけで完結するシステムだと、ユーザは問い合わせ内容をフォームに記述し、送信ボタンを押した後、Django側で問い合わせレコードをDBに作成する、という流れになると思います。

問い合わせ対応の効率化

その問い合わせ内容を例えば社内のサポート部隊で管理したい場合はどうでしょうか。

問い合わせチケット作成後、一次サポートのAさんにそのチケットをアサイン、Aさんがオーナーシップを持って担当部署に照会する必要があるかもしれません。そのやり取りを記した社内メモも残したいですよね。

ショッピングサイト(Django製)の例を使えば、楽天やAmazonにも出店しているかもしれません。その場合の問い合わせを一元管理したいところです。

購入後に何かしらのトラブルがあった場合、コールセンターに問い合わせできる電話番号が必要でしょう。メールでもチャットでも対応できるようにしたい。カスタマーサポートって思っている以上にやることが多いです。

これらを自前で実装するかどうか、結構判断がいるところです。 世の中には金を払えば手に入る良いサービスがあり、貴重な開発リソースをもう世の中に既にあるサービスの開発に使うべきでしょうか。

SaaSを使う

そこが特化型のSaaSの出番で、上記の課題を解決してくれるのがZendeskです。NasdaqにZENのティッカーで上場しています。

このSaaSを使うメリットとして

  • 問い合わせ対応を効率化
  • 顧客の疑問を自己解決できるオンラインコミュニティを作れる
  • リアルタイムのチャットサポート
  • 通話記録(Zendesk Talkという機能)
  • CRM機能

などがあります。

Djangoとの連携

DjangoとZendeskを連携させて使う場合、問い合わせフォームの送り先がZendeskになるイメージです。

以下、FormViewを継承したクラスでform_validの中でrequestsを使ってZendesk APIのエンドポイントにPOSTするサンプルコードです。

class Contact(FormView):
    template_name = 'web/contact.html'
    form_class = ContactForm

    def form_valid(self, form):
        subject = form.data.get('subject')
        description = form.data.get('description')
        email = form.data.get('email')
        user_name = form.data.get('user_name')

        # Package the data for the API
        data = {'request': {
            'subject': subject,
            'comment': {'body': description},
            'requester': {
                'name': user_name,
                'email': email
            },
        }}
        ticket = json.dumps(data)

        # Make the API request
        url = 'https://your_sub_domain.zendesk.com/api/v2/requests.json'
        headers = {'content-type': 'application/json'}
        r = requests.post(
            url,
            data=ticket,
            headers=headers
        )
        if r.status_code != 201:
            if r.status_code == 401 or 422:
                status = 'Could not authenticate you. Check your email address or register.'
            else:
                status = 'Problem with the request. Status ' + str(r.status_code)
            response = render_to_response('web/error.html')
            return response
        return redirect('web:thankyou')

Zendeskでは30日間のトライアルが可能です。

試しにcurlでエンドポイントを叩いてみたい場合のサンプルはこちらです。

curl -X "POST" "https://your_sub_domain.zendesk.com/api/v2/requests.json" \
     -H 'content-type: application/json' \
     -d $'{
  "request": {
    "tags": [
      "故障",
      "プリンタ"
    ],
    "subject": "緊急事態 - Help Needed",
    "comment": {
      "uploads": [
        "your token from upload api"
      ],
      "body": "プリンターが火を吹いています!!!!!! 大変!!!"
    },
    "requester": {
      "name": "nerimplo",
      "email": "hogehoge@example.com"
    },
    "is_public": "false"
  }
}'

(このTweetでは添付画像を加えています。フローとしてはUpload APIで先に添付ファイルをアップロード、戻り値のtokenをRequest APIに含めてあげます)

手っ取り早くテストしたければこのcurlでチケットがZendesk側に作成されます。Djangoで実装する際にはreCAPTCHAを追加してボットやスパム対策を施すといいと思います。

上記のケースはDjangoのFormビューとの連携ですが、ZendeskにはJavaScript Widgetがあり、Django Templateのscriptタグ内に埋め込んであげるだけでサイトの右または左下に問い合わせWidgetを埋め込むことができます。わざわざ問い合わせフォームがあるページに誘導するより、手軽さを考えるとこちらの方がいいかもしれません。

参考サイト

Zendesk Developer Portal

Zendeskって何?全7サービスを紹介。 - サポートタイムズ

Mastering Zendesk

Mastering Zendesk

  • 作者:Cedric F. Jacob
  • 出版社/メーカー: Packt Publishing
  • 発売日: 2017/01/13
  • メディア: ペーパーバック