LIFFのおともにSentryはいかが？

こちらの記事は「[LINEBot&Clova Advent Calendar 2018](https://qiita.com/advent-calendar/2018/linebot)」 10日目の記事としてお送りします。


# はじめに
今年(2018年)の6月に、LINE Messaging APIで[LIFF](https://developers.line.biz/ja/docs/liff/)というものが発表されました。
LIFFを用いることで、LINE Botとwebサイトを紐付け、シームレスにWEBを開き、WEBサイトに対して、LINEのUserIDを渡したり、WEBからLINE側にメッセージを送る、ということができるようになりました。
今回は、LIFFについての簡単な紹介と、LIFFとセットで使うと個人的に便利だったイベント監視ツール「Sentry」について、ご紹介できたらと思います。

# LIFFとは
LIFFは、今年6月ごろにLINEから発表された「LINE Front-end Framework」の略です。
このLIFFを用いることで、以下のようなことができるようになります。

- LINE Botと指定したWEBサイトを紐付けできる
- 紐付けしたWEBサイトに対してシームレスに遷移ができる
- 紐付けしたWEBサイト上から、アクセスしたユーザのLINEのUserID、表示名やプロフィール画像を取得できる
- WEBサイト上からLINEに対してメッセージを送れる

実際の紐付け画面はこちらのようになっています。
※ 以前は、LINE BotのアクセストークンとWEBサイトのドメインを直接curlで紐づける必要があったのですが、2018/10/30よりLINE Developersコンソールに設定画面が追加され、より簡単にLIFFを使えるようになりました。

<img width="500" alt="スクリーンショット 2018-12-09 2.31.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/203817/44a66d81-e835-702a-1a90-c0d7ab918ae6.png">


「追加」ボタンより、紐付けするurlと、名前、サイズを決めます。

<img width="400" alt="スクリーンショット 2018-12-08 23.33.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/203817/7669683d-f10a-b3c8-b042-5e303d38dd91.png">


LIFFはLINE内で下から現れるブラウザ上で扱われるのですが、サイズはCompact、Tall、Fullから選ぶことができます。好きなサイズで作成しましょう。(下記はtallサイズでのサンプルです。)

こうしてLIFFの設定が完成すると、 `line://app/xxxxxxxxx` といった独自のドメインが与えられます。
このドメインを紐付けたBot内から呼び出すと、LIFFを利用することが可能です。


<img width="500" alt="スクリーンショット 2018-12-09 2.31.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/203817/21b6e53b-9666-7db6-e4f3-052d560974cf.png">

`line://app/xxxxxxxxx` をそのままトーク上でタップしても起動しますが、見た目的にボタンタイプなどのリンク先として設定しておく方が良さげです。

さて、上記のサンプル画像は、以前趣味で作った品川区のゴミ収集日把握Botのものです。LIFFで住所を登録すると、その地域のゴミ収集日が分かります。(品川区民じゃないですが、オープンデータを扱ってみたくて作りました。)
こちらから友だち登録できるので、よかったら触ってみてください。

[LINE Bot トラッシュくん(品川区版)](https://line.me/R/ti/p/%40sbc2086z)

# Sentryとは
本題です。今回はイベントログ監視ツール「Sentry」をトラッシュくんに追加してみます。

[Sentry](https://sentry.io/)とは、イベントログ監視ツールであり、アプリ上にセットすることで、アプリで発生した例外処理などをイベントごと、ユーザごとにsentryに送り、ダッシュボードから一元管理することができます。
フロントエンドで起きているエラーやユーザごと、OSごとの違いなどが把握しやすくなるため、一般的なフロントエンドだけでなく、LIFFを使う場合にも便利だなと思いました。

## オススメどころ
- 設定の追加が容易。ドキュメントが丁寧
- 扱えるSDKの種類が多い
- イベントごとに、発生元のOS・IPアドレス・ブラウザとバージョンが分かる
- 同様の例外イベントなど、同じイベントは一つにまとめられ、カウントが自動で取れる
- チケットのようにまとまるため、優先度などを決めて各エラーの対応がしやすい
- 自分で設定した付加情報(ユーザ情報など)も同様にログとして取得できる

設置と実際の利用の流れをおって、オススメどころをみていきましょう。

## 設置方法とSentryの概要
まず、[Sentry](https://sentry.io/)にログインし、新規Projectを作成します。
この際に利用するSDKのリストが出ます。非常に多くの言語・フレームワークから選ぶことができます。

<img width="600" alt="スクリーンショット 2018-12-08 23.38.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/203817/46048526-a3ee-6e13-7452-5b469239dfc5.png">

何かしらたの言語を選択すると、sdkごとにインストールする手順が丁寧に表示されます。これを追っていくだけでも問題なく設定できるかと思います。

この記事では、JavascriptでCDNを使ったインストール方法をみていきます。
まず、以下のようにjs内にCDNを設定し、作成したProjectごとに与えられているClientKeyを設定します。

```js
<script src="https://cdn.ravenjs.com/3.26.4/raven.min.js" crossorigin="anonymous"></script>
<script>        
 Raven.config('https://xxxxxxxxx@sentry.io/yyyyy').install()
</script>
```

※ 現在(2018年12月)だと、新しく統合された新SDKがあるようなのですが、そちらだとうまくLIFFから読み取れなかったので、[旧型のもの](https://docs.sentry.io/clients/)を使っています。

次に、try...catchなどの例外処理でエラーをSentryに送る処理を加えます。

```js
try {
  //something to do
} catch(error) {
   Raven.captureException(error);
}
```

エラーでなく、単純なメッセージを送ることも可能です。

```js
Raven.captureMessage("メッセージを送るよ！");
```

このようにしてエラーを発生させると、Sentry側にチケットが追加されます。
いつ何回発生したか、がグラフで分かるのがいいですね。

<img width="700" alt="スクリーンショット 2018-12-09 1.40.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/203817/ef1080e8-ad91-69ee-afab-6b1fa9fee292.png">

次に、それぞれのチケットの中身をみてみます。

<img width="700" alt="スクリーンショット 2018-12-09 1.47.17.png" src="https://qiita-image-store.s3.amazonaws.com/0/203817/c7099e8a-271d-0089-df8e-8ea228a5f362.png">

イベント発生元のIPアドレス、ブラウザ、OSとそのバージョンを確認できます。

<img width="901" alt="スクリーンショット 2018-12-09 1.55.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/203817/d0f81299-c38c-73a7-5505-6cc4fde10294.png">

また、ソースのどこで発生したか、ユーザがどんな行動を取ったかなどが把握できます。
今回は何も入力がなかった場合に意図的にエラーを起こしています。

次に、カスタマイズしたユーザ情報の取得です。 `Raven.setUserContext` というメソッドを使います。
LIFFは `liff.init()`　、 `liff.getProfile()` でLINEのUserIDや表示名の取得をすることができるため、LIFFでSentryを使う場合はぜひ入れておきましょう。

```js
window.onload = () => {
 liff.init((data) => {
  getProfile();
 });
};

function getProfile() {
 liff.getProfile().then((profile) => {
   Raven.setUserContext({
    userId: profile.userId,
    displayName: profile.displayName
   });
 }).catch((error) => {
   Raven.captureException(error);
 });
}
```

上記のように取得した表示名とUserIdをsetすると、Sentryの各イベント上で誰がそのエラーになったかが把握できます。

<img width="403" alt="スクリーンショット 2018-12-09 2.06.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/203817/fee72f73-549d-1d48-af4a-a8fa4f6ac4b1.png">

他にも、オプションでタグをつけたり、Slack連携したりと様々なことができるので、色々試してみると面白いかと思います。
ドキュメントはとても分かりやすい印象でした。

## まとめ
このようにLIFF上にSentryを入れておくことで、LIFF上でエラーが発生した際に、どんなユーザがどんな行動をしてエラーがおきたのか、エラーごとの端末依存、OS依存などの問題はないか、など障害特定に一役買えそうですね。
LIFFを使う場合、ログイン情報を扱うことが多いかと思うので、ご興味がある方はLIFFのおともにぜひ取り入れてみてください！