mixiグループ Advent Calendar 2017 の21日目です。
XFLAGスタジオ CRE(Customer Reliability Engineering)チームの @njin です。
はじめに
CREチームの業務の一つに、カスタマーサポート(CS)スタッフ向けの管理画面(CSツール)の開発があります。
今回は最近実装したCSツールの機能で起きた問題とその解決方法についてまとめました。
CREとは?CREチームって何やってるの?など
ご興味を持っていただけた方は、こちらの記事もご覧になってみてください。
CREチームのメンバーがAdvent Calendarに参加しております
CREチームを設立しました!(@otoyo)
アプリケーションサーバに引きこもるDBを自立させてDocker Composeで開発環境を作る(@upscent)
なれる!CRE(@nukosuke)
フェイルセーフの観点から顧客信頼性を確保しよう(@manji602)
機能の概要
XFLAGスタジオのCSでは、多くのプロダクトでCS対応にZendeskというCRMを使用しています。
Zendeskではお問い合わせ1件1件を「チケット」と呼ばれるものに紐づけて管理しています。
詳細は書けないのですが、今回追加した機能の簡略化したフローは以下です。
- ZendeskからAPIでチケット単位のデータ(JSON形式)を取得
- 取得したチケットのデータをDBへ保存
- 保存したデータを整形し、CSツールで表示
チケットにはお問い合わせの内容やアカウントのID・ニックネーム・ランクなどが記載されたメール本文が含まれており、ここである問題が発生しました。
問題
CSスタッフから連絡があり、CSツールでユーザーの情報が途中から表示されていないというのです。
さらにニックネームに絵文字が含まれていると聞き、嫌な予感がしました…
DBのデータを確認すると、ニックネームから後ろが切れています。
[1] pry(main)> ticket.body
=> "【お問い合わせ内容】\r\nhogehogeについて\r\n\r\n【項目1】\r\ntest\r\n\r\n【項目2】\r\ntest\r\n\r\n【ニックネーム】\r\n"
テーブルの定義を確認すると、
> SHOW CREATE TABLE tickets;
| tickets | CREATE TABLE `tickets` (
`body` text NOT NULL,
...
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
そうですよね。
テーブル作成時にCHARSETをutf8mb4に設定していないことが原因でした。
テーブルやカラムがutf8mb4に対応していない場合、絵文字(4バイト文字)が含まれているとそれ以降がカットされてしまいます。
[1] pry(main)> ticket = Ticket.create(body: "すし🍣すし")
[2] pry(main)> ticket.body
=> "すし"
解決方法
追加した機能がすでに稼働している状況だったため、テーブルの作り直しではなく、CSの業務時間外に change_column
を使ったカラム変更でCHARSETをutf8からutf8mb4へ変更することにしました。
change_column
でCHARSETを変更するための記法がわからず少々苦戦しましたが、以下の記述で変更することができました。
class ChangeColumn < ActiveRecord::Migration
def self.up
change_column :tickets, :body, "text CHARSET utf8mb4"
...
end
end
[1] pry(main)> Ticket.create(body: "すし🍣")
SELECT * FROM tickets;
+----+------------------------------+
| id | body |
+----+------------------------------+
| 1 | すし???? |
+----+------------------------------+
絵文字以降も保存されるようになりましたが、文字化けした状態で保存されてしまいました。
そこで、RailsとMySQLでiOSの絵文字に対応(UTF8MB4化)した話を参考に、ActiveRecordでMySQLへ接続する際のCHARSETをutf8mb4に設定することで解決しました。
development:
encoding: utf8mb4
test:
encoding: utf8mb4
production:
encoding: utf8mb4
[1] pry(main)> Ticket.create(body: "すしすし🍣🍣")
SELECT * FROM tickets;
+----+------------------------------+
| id | body |
+----+------------------------------+
| 1 | すし???? |
| 2 | すしすし🍣🍣 |
+----+------------------------------+
文字化けせずに保存できました。
終わりに
CSツールに不具合が発生しCSツールが停止すると、CSスタッフは対応ができなくなり、それはそのままユーザーさんへの返信の遅れに直結します。
CREチームのメンバーとして、より速く・正確なCS対応のサポートをしていけるように、CSツールの開発についても「より速く・正確な」を意識して取り組んでいきたいと思います。