3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

IPFactoryAdvent Calendar 2023

Day 16

GASでYoutubeの動画投稿をDiscordに通知する

Last updated at Posted at 2023-12-15

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で作れるらしいので今後やってみたいと思います。

参考文献

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?