7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

バッチ処理だけどYoutube Auth認証が必要だったので楽に何とかする

Last updated at Posted at 2019-11-20

はじめに

趣味でこんなものを作りました。
https://www.youtube.com/channel/UCArxaN-Q-rsW3TCgW3NhW2A/playlists

Youtubeのプレイリストを自動生成するスクリプトをcron的な感じで走らせているのですが、プレイリスト作成のためにはAuth認証してAPIを叩く必要がありました。

自分のYoutubeアカウントで認証したいだけで不特定多数のユーザが認証するわけでは無いので、真面目にAuth認証を作るのは面倒だなと思い、いい方法無いかなと思っていたらいい方法があったのでそのメモです。

前知識

やったこと

サンプルコードはjsですが別になんでも良いです。

その1: client_id, client_secretを生成する

認証情報_-_nijisanji-playlist_-_Google_API_コンソール.png

↑画像のような タイプ: ウェブアプリケーション, OAuth2.0クライアント のIDを発行しておきます。

その2: 認証URLを叩く

//
// script1.js
//

// その1で取得したclient_id
const clientId = "xxx.apps.googleusercontent.com";

// redirectUrlは実際にサーバを立てる必要はない。localhostならまあなんでも良い
const redirectUrl = "http://localhost:8000";

const scope = "https://www.googleapis.com/auth/youtube";

const url = [
  "https://accounts.google.com/o/oauth2/auth?",
  `client_id=${clientId}&`,
  `redirect_uri=${encodeURIComponent(redirectUrl)}&`,
  `scope=${scope}&`,
  "response_type=code&",
  "access_type=offline"
].join("");

console.log(url);
$ node script1.js
https://accounts.google.com/o/oauth2/auth?client_id=xxx.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Flocalhost%3A8000&scope=https://www.googleapis.com/auth/youtube&response_type=code&access_type=offline

↑このURLをブラウザで開く。

その3: refresh_tokenを取得する

その2で生成したURLを叩いてYoutube認証すると、下記のようなlocalhostにリダイレクトされます。

http://localhost:8000/?code=aaa&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyoutube#

サーバは立ててないのでブラウザのエラー画面になりますが特に問題ないです。
URLバーに含まれるcodeをコピーして、下記のスクリプトを走らせます。

//
// script2.js
//

const body = {
  code: "aaa", // 先程取得したcode
  client_id: "xxx.apps.googleusercontent.com", // その1で取得したclient_id
  client_secret: "yyy",  // その1で取得したclient_secret
  redirect_uri: "http://localhost:8000", // その2と同じくサーバを立てる必要はない
  grant_type: "authorization_code"
};

const command = [
  "curl -X POST",
  '-H "Content-Type: application/json"',
  "-d",
  `'${JSON.stringify(body)}'`,
  "https://accounts.google.com/o/oauth2/token"
].join(" ");

console.log(command);
$ node script2.js
curl -X POST -H "Content-Type: application/json" -d '{"code":"aaa","client_id":"xxx.apps.googleusercontent.com","client_secret":"yyy","redirect_uri":"http://localhost:8000","grant_type":"authorization_code"}' https://accounts.google.com/o/oauth2/token

# ↑このコマンドをコピペして実行すると下記のレスポンスが返ってくる

{
  "access_token": "xxx",
  "expires_in": 3600,
  "refresh_token": "zzz", // これが欲しかった!!
  "scope": "https://www.googleapis.com/auth/youtube",
  "token_type": "Bearer"
}%

その4: refresh_tokenを使って認証が必要なAPIを叩く

//
// script3.js
//

import { google } from "googleapis";

const getAuthorizedYoutubeClient = () => {
  const OAuth2 = google.auth.OAuth2;
  const clientId = "xxx.apps.googleusercontent.com";
  const clientSecret = "yyy";
  const refreshToken = "zzz";
  const authClient = new OAuth2(
    clientId,
    clientSecret,
    "http://localhost:8000"
  );

  authClient.setCredentials({ refresh_token: refreshToken });
  return google.youtube({
    version: "v3",
    auth: authClient
  });
};

const client = getAuthorizedYoutubeClient();
client.playlists.insert({
  part: "snippet,status",
  requestBody: {
    snippet: {
      title: "playlist title",
      description: "playlist description"
    },
    status: {
      privacyStatus: "public"
    }
  }
}).then(result => {
  console.log(result);
});

これで勝手にrefresh_tokenを使って認証してAPIを叩いてくれるようになります。
このライブラリとても便利ですね。 :pray:

その他感想

  • バッチ処理用にserver_key的なtokenを発行してくれたら楽なんだけど、そういう仕組みは無さそうだったので、今回みたいな方法をとった
  • Youtube Data APIのクォータの使用量の制限がシビアすぎて泣ける
  • 根本的な問題だけどrefresh_tokenのexpireがどれくらいなのか不明
  • 記事書いてから気づいたけど、本家にも似たようなドキュメントがあった
7
7
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
7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?