IPFactory Advent Calendar 2023 16日目の記事です。
はじめに
今回は Google App Script (GAS) を使ったYoutubeの動画投稿をDiscordへ通知するスクリプトを作ってみたので解説していきます。
ソースコードが欲しい方は最後まで飛ばしてください。
筆者はGASやjsの経験が浅いです。参考程度にご覧ください。
環境
Google App Script
利用サービス
- YouTube Data API v3
- Drive API
Youtubeから動画を取得する
GASで使えるサービスのYoutube Data APIを使うことで以下のように動画を取得できます。
@から始まるハンドルではなくIDが必要な点に注意してください。
var results = YouTube.Search.list('id,snippet', {
"maxResults": 1, // 取得する動画の数
"channelId": channel, // チャンネルID
"order": "date", // 並べ替え
"type": "video", // 動画の種類
"eventType": "none", // 配信タイプ
});
取得した動画IDをGoogle Driveに保存する
GASで使えるサービスのGoogle Drive APIを使います。
繰り返し実行すると重複して取得してしまうのでファイルにメモしておきます。
const files = folder.getFilesByName(config.filename)
file = files.next()
const result = getYouTubeData(channel);
const detail = result.items[0]
var text = file.getBlob().getDataAsString("utf8");
var jsonobj = JSON.parse(text);
if (jsonobj.includes(detail.id.videoId)) {
return
}
jsonobj.push(detail.id.videoId)
file.setContent(JSON.stringify(jsonobj))
Discordに通知を投稿する
Webhookを使って投稿します。
const webhook_url = "https://discord.com/api/webhooks/**********/**********"
const payload = {
"username": "ユーザー名",
"avatar_url": "アイコンurl",
"content": "メッセージ"
}
UrlFetchApp.fetch(webhook_url, {
"method": "post",
"contentType": "application/json",
"payload": JSON.stringify(payload)
})
コード
以上を組み合わせたコードが以下になります。
config.jsonを使って設定が行えるように手を加えています。
トリガーを利用して15分間隔で動かすのがおススメです。
const folder_name = "gas_youtube_discord";
const folders = DriveApp.getFoldersByName(folder_name);
let folder;
if (!folders.hasNext()) {
folder = DriveApp.createFolder("gas_youtube_discord");
} else {
folder = folders.next()
}
const config_files = folder.getFilesByName("config.json")
let config_file;
if (!config_files.hasNext()) {
config_file = folder.createFile("config.json",JSON.stringify({
"channels": ["UC3qJ7qxc3hDnftTYetCkSaw"],
"webhook_url": "",
"icon_url": "",
"message": "新しい動画です!",
"filename": "videoid.json"
}))
} else {
config_file = config_files.next()
}
const config = JSON.parse(config_file.getBlob().getDataAsString("utf8"))
// YouTubeのデータ取得設定
function getYouTubeData(channel) {
//YouTube Data API リストのgetリクエスト
var results = YouTube.Search.list('id,snippet', {
"maxResults": 1,
"channelId": channel,
"order": "date",
"type": "video",
"eventType": "none",
});
return results
}
function post(payload) {
UrlFetchApp.fetch(config.webhook_url, {
"method": "post",
"contentType": "application/json",
"payload": JSON.stringify(payload)
})
}
function main() {
const files = folder.getFilesByName(config.filename)
let file;
if (!files.hasNext()) {
file = folder.createFile(config.filename,"[]")
} else {
file = files.next()
}
for (var channel of config.channels) {
const result = getYouTubeData(channel);
const detail = result.items[0]
var text = file.getBlob().getDataAsString("utf8");
var jsonobj = JSON.parse(text);
if (jsonobj.includes(detail.id.videoId)) {
return
}
jsonobj.push(detail.id.videoId)
file.setContent(JSON.stringify(jsonobj))
var snippet = detail.getSnippet()
var payload = {
"username": snippet.channelTitle,
"avatar_url": config.icon_url,
"content": `${config.message}\nhttps://www.youtube.com/watch?v=${detail.id.videoId}`
}
post(payload)
}
}
まとめ
ちゃんとGASに触ったのはこれが初めてでしたが、簡単に作成できました。
APIなんかもGASで作れるらしいので今後やってみたいと思います。
参考文献