【スケジューラ】YouTubeのチャンネル内動画の情報を自動取得してみる

# はじめに #
自身のYouTubeチャンネルに投稿した動画のID等の情報を自動で取得する処理を作ってみようかなと思い、[Sharperlight](https://sharperlight.jp/)のスケジューラを使用し作成してみました。

処理としては、先ずGoogle API Keyを準備してYouTubeのAPIにアクセスします。ページング等も行いチャンネル内の全ての画像の情報を取得します。取得したデータはcsvファイルとして一時保存。
Sharperlightクエリで一時保存したcsvを読みとり、予め準備しておいたデータベーステーブルに書き込みます。

# スケジュールタスクの作成 #
Sharperlightアプリケーションメニューからスケジューラを起動します。
`新規`ボタンを利用してスケジュールタスクの作成を開始します。
## 一般タブ ##
ここでは初めに、グループやコード等の詳細を記入します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/c0d93018-8515-fc90-2903-6016afeabc7d.png)

## アクションタブ ##
アクションタブではその名のとおり、このタスクに遂行させる処理を記入していきます。
`新規`アイコンでアクション一覧を表示して、使用するアクションを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/7691e492-2423-4d7b-3da3-18952b9b7e47.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/fd7d2000-be9d-19aa-a836-b3c0b5e5d576.png)
### データの取得 ###
最初にAPIから情報を取得するアクションを作成します。JavaScriptで作成するのが便利そうなのでアクション一覧より**JavaScript**を選択します。
JavaScriptアクションが追加されたエディタが表示されるので、以下のコードを書いてみました。
コード中のこのようなSharperlight関数 `lib_task.ParamGet('xxxxx')`は、このタスクに渡される引数を参照するためのものです。
基礎となるURLアドレスやGoogle API Key等は引数で渡せるようにしておきました。
ページング処理は、戻り値の`nextPageToken`属性を利用しています。
また今回は10ページまでと直接指定しています。ここも引数でもいいかもね。
(エラーハンドリングは省略)
```
var nextPageToken = "";
var url = lib_task.ParamGet('BaseAPIUrl') + "&maxResults=" + lib_task.ParamGet('MaxResultPerPage') + "&playlistId=" + lib_task.ParamGet('PlayListId') + "&key=" + lib_task.ParamGet('GoogleAPIKey');
var xUrl = "";

var path = "{_Task.Param.FilePath}";
for (var p=0; p<10; p++){
       if (nextPageToken == ""){
              xUrl = url;
       }else{
              xUrl = url + "&pageToken=" + nextPageToken;
       }
       console.log("P=" + p + ":  " + xUrl);
       let ytSnippet = lib_sys.urlContent.Get(xUrl);
       let ytSnippetObj = JSON.parse(ytSnippet);
       nextPageToken = ytSnippetObj.nextPageToken;
       let content = "";
       if (ytSnippetObj.items.length == 0) { break; }
       for (var i=0; i<ytSnippetObj.items.length; i++){
              content += lib_app.expression.Eval( "ChCRLF()" ) + ytSnippetObj.items[i].id;
              content += "," + ytSnippetObj.items[i].snippet.position;
              content += "," + ytSnippetObj.items[i].snippet.publishedAt;
              content += "," + ytSnippetObj.items[i].snippet.channelId;
              content += "," + ytSnippetObj.items[i].snippet.title.replace(',','@@@');
              content += "," + ytSnippetObj.items[i].snippet.channelTitle.replace(',','@@@');
              content += "," + ytSnippetObj.items[i].snippet.playlistId;
              content += "," + ytSnippetObj.items[i].snippet.resourceId.kind;
              content += "," + ytSnippetObj.items[i].snippet.resourceId.videoId;
       }

       lib_sys.io.file.AppendAllText(path,content);
       if (typeof nextPageToken === "undefined") { break; }

}
```
以上で主となるアクションが完成。取得された情報はcsvファイルとして保存されるので、そのファイルをクエリしてデータベースに書き込むアクションを作成します。
### データの書き戻し ###
ここでは`書き戻し`アクションを選択します。このアクションは先のJavaScriptアクションの次に実行される必要があるので、すぐ真下に定義します。
`書き戻し`アクションでは、下記の情報を定義します。
 - 書込み先のデータベースの接続情報の指定
 - ソースデータを準備するためのクエリの定義

今回使用するデータベースは、Sharperlightマテリアライズクエリで作成されるデータベースを利用しました。その中にあらかじめデーブルも作成しておきました。
`製品コード`に作成しておいたマテリアライズクエリのコードを指定します。こうすることでSharperlightエンジンは、そのデータベース接続情報を取得できます。
更に書込み先テーブルの指定を行います。その他の属性はそのままでいいでしょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/5ecadb2d-1492-3f73-d2c7-67dcf69d1cd7.png)
次に、書込むデータを準備するクエリを定義します。これは単にAPIから取得した情報が記されているcsvファイルを読み、全レコードを返すという単純なクエリです。`クエリを編集`ボタンでクエリビルダを起動して作成します。
このような定義になります。**Title**と**ChannelTitle**に関して、拡張表現が定義されています。これらは、TitleやChannelTitle内にカンマが含まれていた場合、csvファイルを作成する時点で読み取り時の誤作動を防ぐという意味で特殊な記号に変換していたものを、元のカンマに戻すという処理をしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/fd908b1b-3c21-6f6a-f75e-7153dcef1a33.png)
### テーブルの初期化 ###
UPDATEとINSERTを併用したSQL文で書き戻し処理を記してデータの重複を防ぐことも可能ですが、今回は単に書き戻しアクションでINSERTのみを行うようにしたので、書き戻し前にテーブルを初期化するアクションが必要です。
アクション一覧からSQLステートメントを選択し、Truncate Table構文を実行するようにします。
そして書き戻しアクションのひとつ前に配置します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/390773cb-4102-35b7-428b-d55c9b465f64.png)
### csvファイルの初期化 ###
最後にAPIから取得したデータを一時保存するためのcsvファイルの初期化アクションを二つ追加します。
ひとつはcsvファイルを削除するアクション、もうひとつはcsvファイルを作成しヘッダー行を追加するアクションです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/71dad36b-4d91-7cff-38ef-64ada4f141da.png)

以上で全てのアクションが作成できました。`OK`ボタンで保存します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/54610cb4-93ae-4f93-44f6-009f420429c5.png)

## スケジュールタスクの実行 ##
スケジュールタスクの一覧ダイアログから作成したばかりのタスクを選択し、右クリックメニューより**実行**を選択します。
実行後エラーが発生しなければ、指定したデータベーステーブルを確認してみます。エラーが発生した場合は、定義したアクションを確認していきます。JavaScriptアクションは単体でデバッグができるようになっています。
このようなデータが確認できれば成功ですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/a134e61a-de72-c35b-f9ee-0ce30564e03b.png)

# スケジューリング #
上記では手動でタスクを実行しましたが、タスクの`トリガ`タブで実行時間のスケジューリングが可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/4b8f9735-c524-d4d2-7e36-70484f03fa29.png)

# あとがき #
これでYouTube動画の情報が取得されました。こんどはこの情報を利用して、自分オリジナルの動画メニューでも作ってみます。
この記事が何かのお役に立てればなによりです。では失礼します。