Skip to content
This repository was archived by the owner on Apr 13, 2025. It is now read-only.

Commit a360037

Browse files
committed
Save youtube refresh token in config for re-use
1 parent 6eb967f commit a360037

File tree

2 files changed

+38
-7
lines changed

2 files changed

+38
-7
lines changed

nodecg-io-youtube/extension/index.ts

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import { NodeCG } from "nodecg/types/server";
22
import { Result, emptySuccess, success, error, ServiceBundle } from "nodecg-io-core";
33
import { google, youtube_v3 } from "googleapis";
4+
import type { Credentials } from "google-auth-library/build/src/auth/credentials";
5+
import type { OAuth2Client } from "google-auth-library/build/src/auth/oauth2client";
46
import * as express from "express";
57
import opn = require("open");
68

79
interface YoutubeServiceConfig {
810
clientID: string;
911
clientSecret: string;
12+
refreshToken?: string;
1013
}
1114

1215
export type YoutubeServiceClient = youtube_v3.Youtube;
@@ -26,6 +29,36 @@ class YoutubeService extends ServiceBundle<YoutubeServiceConfig, YoutubeServiceC
2629
clientSecret: config.clientSecret,
2730
redirectUri: "http://localhost:9090/nodecg-io-youtube/oauth2callback",
2831
});
32+
33+
if (config.refreshToken) {
34+
this.nodecg.log.info("Re-using saved refresh token.");
35+
auth.setCredentials({
36+
refresh_token: config.refreshToken,
37+
});
38+
} else {
39+
this.nodecg.log.info("No refresh token found. Starting auth flow to get one...");
40+
auth.setCredentials(await this.initialAuth(auth));
41+
if (auth.credentials.refresh_token) {
42+
config.refreshToken = auth.credentials.refresh_token;
43+
}
44+
}
45+
46+
// Save refresh tokens so they can be used next time to get a access token again
47+
auth.on("tokens", (tokens) => {
48+
if (tokens.refresh_token) {
49+
config.refreshToken = tokens.refresh_token;
50+
}
51+
});
52+
53+
const client = new youtube_v3.Youtube({ auth });
54+
return success(client);
55+
}
56+
57+
stopClient(_client: YoutubeServiceClient): void {
58+
// Cannot stop client
59+
}
60+
61+
private initialAuth(auth: OAuth2Client): Promise<Credentials> {
2962
const authUrl = auth.generateAuthUrl({
3063
access_type: "offline",
3164
scope: "https://www.googleapis.com/auth/youtube",
@@ -41,9 +74,7 @@ class YoutubeService extends ServiceBundle<YoutubeServiceConfig, YoutubeServiceC
4174
res.end("<script>window.close()</script>");
4275
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
4376
const { tokens } = await auth.getToken(params.code!.toString());
44-
auth.credentials = tokens;
45-
const client = new youtube_v3.Youtube({ auth });
46-
resolve(success(client));
77+
resolve(tokens);
4778
} catch (e) {
4879
reject(error(e));
4980
}
@@ -53,8 +84,4 @@ class YoutubeService extends ServiceBundle<YoutubeServiceConfig, YoutubeServiceC
5384
opn(authUrl, { wait: false }).then((cp) => cp.unref());
5485
});
5586
}
56-
57-
stopClient(_client: YoutubeServiceClient): void {
58-
// Cannot stop client
59-
}
6087
}

nodecg-io-youtube/youtube-schema.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
"clientSecret": {
1111
"type": "string",
1212
"description": "The oauth client secret https://console.cloud.google.com/apis/credentials/oauthclient"
13+
},
14+
"refreshToken": {
15+
"type": "string",
16+
"description": "Token that allows the client to refresh access tokens. This is set automatically after first login, you don't need to set it."
1317
}
1418
},
1519
"required": ["clientID", "clientSecret"]

0 commit comments

Comments
 (0)