YoutubeやTwitchなどのお気に入り配信者の配信状況を確認するChrome拡張機能を作ってみた

# ツールの名前

StreamChecker

- いろいろ考えてもダサくなるのでパッと思いついたやつ
- 実物は[こちら](https://chrome.google.com/webstore/detail/streamchecker/ajacgcidpoialonhkaibicopdjffjglj?hl=ja)からどうぞ。

# 作ったきっかけ
- twitterでフォローしていた人が「見たい人が色んな所で配信してるからまとめて配信状況がわかるものがほしい」という旨のツイートをしていた
- jQueryでDOM取ってくればなんか作れそうじゃね？　と思った
- たまたまchrome拡張機能を調べてて、なんか行けそうじゃね？　と思った
- 何かしら動くものが作りたかった(最近仕事で試験ばっかり・・・)

# 使った技術
- bootstrap4
- javascript
- jQuery
- html
- chrome API
- Youtube Data API v3
- Twitch API

# 処理の流れ
- オプションページで取得したい配信サイト、配信者を設定
    - Youtube/Twitchはキー情報も設定
- 設定は`chrome.storage.sync.set()`に保存
- ポップアップを開くと、jQueryの`$.ajax()`と`$.get()`と`$.getJSON()`がサイトのデータを持ってきて、情報とリンクを表示。
- 以上

# 実装の一部(API使用部分)
- 変数がダサいのには目をつぶってください
    - `confdata`と`config_data`が混在してる

## youtube API
- チャンネルIDをパラメータにして`search`を使用してチャンネルIDを指定して取得したJSONからデータを取り出しています。

```javascript
$.getJSON("https://www.googleapis.com/youtube/v3/search?part=snippet&channelId=" + confdata.config_data[i].config + "&eventType=live&type=video&key=" + confdata.api_key.youtube, function(data){
	data.items.forEach(function(itemdata){
		platform = "Youtube";
		owner = itemdata.snippet.channelTitle;
		title = itemdata.snippet.title;
		link = "https://www.youtube.com/watch?v="+ itemdata.id.videoId;
		addNotice(platform,owner,title,link);
	});
});
```
## Twitch API

- 公式を読んでもAPIの仕様がどうもわかりにくく、jQueryのajax系にも慣れていないのでグチャッとしてしまいました...
- `https://www.twitch.tv/*****`のURLに含まれているユーザ名では`streams`のパラメータには出来ないようなので、一度`users`を挟んでユーザIDを取得してから`streams`を使用しています。
- `undefined`の判定って`typeof`使えばいいんですかね？

```javascript
$.ajax({
	dataType: 'json',
	type: "GET",
	url: "https://api.twitch.tv/helix/users?login=" + confdata.config_data[i].config,
	headers: { "Client-ID" : confdata.api_key.twitch }
}).done(function(userData){
	$.ajax({
		dataType: 'json',
		type: "GET",
		url: "https://api.twitch.tv/helix/streams?user_id=" + userData.data[0].id,
		headers: { "Client-ID" : confdata.api_key.twitch }
	}).done(function(streamData){
		if(typeof streamData.data[0] != "undefined"){
			platform = "twitch";
			owner = streamData.data[0].user_name;
			title = streamData.data[0].title;
			link =  "https://www.twitch.tv/" + streamData.data[0].user_name
			addNotice(platform,owner,title,link);
		}
	});
});
```

### chromeAPI

- `chrome.storage.sync.set()`と`get()`しか使っていません
- syncとlocalの違いはアカウントと同期するか、端末で完結するか、らしいです。
- 保存時のアラートは後述の記事を参考に、というか丸パクリさせていただきました。

```javascript
// 設定保存ボタン押下時
$(function(){
	$("#save_config").on("click",function(){
		let counter = 0;
		let config_data = [];
		$("#config-body .row").each(function(i,e){
			let platform_val = $(e).find("option:selected").val();
			let config_val = $(e).find(".config").val();
			let memo_val = $(e).find(".memo").val();
			if(platform_val != "" && config_val != ""){
				config_data.push({
					platform : platform_val,
 					config : config_val,
					memo : memo_val
				});
			}
		});
		chrome.storage.sync.set({config_data});
		let api_key = {"youtube": $("#youtube-key").val(),
		"twitch": $("#twitch-key").val()}
		chrome.storage.sync.set({api_key});
		$("#alert-area").append("<div class=\"alert alert-success alert-dismissible fade show p-1 m-0\" role=\"alert\">保存しました</div>")
		setTimeout(() => {$(".alert").alert("close");},1000);
	});
});
```

# 技術的な感想
## 「ページにアクセスして、DOMから配信中と判別できる情報取得するだけだから余裕ｗｗｗ」ではなかった
- youtubeとtwitchはオンライン情報がDOMから取得できなかった（動的に書いてる？）のでそれぞれAPIを使って取得することに...
- youtubeはGETのクエリパラメータにAPIキー情報を加えるので`$.getJSON()`で行けた
- Twitchはヘッダー内に`Client-ID : キー情報 `を追加しないといけないので`$.ajax()`になった
- もっとスマートな書き方ができたかもしれないなぁと思いつつ、もっとJQueryのこと知ったほうが良さそう。
 
## chrome拡張はソースが丸見えなのでAPIキーを置きたくない
- 普通のjavascriptでもそうですけど、丸見えだからもらせない情報は書いておけないですよね。
- とはいえ、APIキーなんて聞いたこともないという人が使う(可能性がある)ツールが「APIキー取得して設定してね」って要求するってのはちょっとどうなのかな...上手いことやる方法ってあるんでしょうか...
- ちなみにlinux(Ubuntu 18.04)でのChrome拡張機能の格納ディレクトリは下記でした
    - `~/.config/google-chrome/Default/Extensions/`

## 先にhtmlだけ作っておいて、後からbootstrapを導入。は無理
- 当初は「骨組み(html)と動き(js)だけ作って公開しちゃってもいいかな」と思っていたのですが、デザインがあまりにも無骨過ぎたのでbootstrapを入れようとしてみたらhtmlをほとんど書き直す羽目に。。。
- 当然なんですが、最初からデザインを踏まえてDOM構造を作っていかないとだめですね
- こういう小規模なツールでも軽く適用できるCSSテンプレートとか探したい

## 使い方ページに移動するとフリーズする
- 当初は使い方ページとして`help.html`をツール内に入れていたのですが、オプションページから遷移するとどうやってもツールがフリーズシてしまいました。
- 仕方ないのでQiitaの限定公開記事に使い方を書いてリンクで飛ばすことに。
- `manifest.json`のどこかに宣言しておかないとだめなんですかね？

## その他
- `chrome.storage.sync.get()`が非同期だとなぜか気づかずに、後続処理をコールバックの中に書いてなくてハマった。
- 最低限の動作はできたけれど、バックグラウンドで定期的に確認して配信中の番組数を通知するとか、そういう機能もつけてみたい。
- git/githubについて
    - 今回始めてgithubに登録してソース管理をしました。無料でもプライベートリポジトリ使えるの本当にありがたい。
    - masterから接続先追加するときとかUI変更とかでブランチ切って開発してみましたが、一人でしか触ってないのにコンフリクトが発生したりとgit初心者であることを痛感しました。
    - 自分が今どのブランチにいるのかを常に意識しないとですかね。`git branch`大切。
    - というか、仕事では長いことSVNしか触っていなかったのでもっとgitを使い倒したいですね
- javaScript、jQueryについてあまり自信がないまま作ったので、変なところが多いかも……
- この記事を書いてて思ったけれども、ソースにコメント書かなすぎですね。
- 「とりあえず公開」になっているので、改良しつつ思いついたら別のツールも作ったりして技術高めたいです。 
- 作るのに10日位かな。これくらいの規模だったらもっとサクッと作れるようになりたい...

# 参考にさせて頂いた記事

- [Bootstrap4でアラート表示](https://qiita.com/reflet/items/2a02996440f9605d2932)
- [Chrome拡張機能のソースが丸見えな件。](https://qiita.com/samuraijap/items/56baecaeda730e8a6e5c)