Reorg third party services & config

This commit is contained in:
Max Isom 2021-09-19 19:50:25 -04:00
parent 79e7e88fab
commit efcdeb78c8
No known key found for this signature in database
GPG key ID: 25C9B1A7F6798880
10 changed files with 99 additions and 64 deletions

36
src/services/config.ts Normal file
View file

@ -0,0 +1,36 @@
import dotenv from 'dotenv';
import {injectable} from 'inversify';
import path from 'path';
dotenv.config();
export const DATA_DIR = path.resolve(process.env.DATA_DIR ? process.env.DATA_DIR : './data');
const CONFIG_MAP = {
DISCORD_TOKEN: process.env.DISCORD_TOKEN,
YOUTUBE_API_KEY: process.env.YOUTUBE_API_KEY,
SPOTIFY_CLIENT_ID: process.env.SPOTIFY_CLIENT_ID,
SPOTIFY_CLIENT_SECRET: process.env.SPOTIFY_CLIENT_SECRET,
DATA_DIR,
CACHE_DIR: path.join(DATA_DIR, 'cache')
} as const;
@injectable()
export default class Config {
readonly DISCORD_TOKEN!: string;
readonly YOUTUBE_API_KEY!: string;
readonly SPOTIFY_CLIENT_ID!: string;
readonly SPOTIFY_CLIENT_SECRET!: string;
readonly DATA_DIR!: string;
readonly CACHE_DIR!: string;
constructor() {
for (const [key, value] of Object.entries(CONFIG_MAP)) {
if (typeof value === 'undefined') {
console.error(`Missing environment variable for ${key}`);
process.exit(1);
}
this[key as keyof typeof CONFIG_MAP] = value;
}
}
}

View file

@ -11,6 +11,8 @@ import {Except} from 'type-fest';
import {QueuedSong, QueuedPlaylist} from '../services/player';
import {TYPES} from '../types';
import {cleanUrl} from '../utils/url';
import ThirdParty from './third-party';
import Config from './config';
type QueuedSongWithoutChannel = Except<QueuedSong, 'addedInChannelId'>;
@ -20,10 +22,10 @@ export default class {
private readonly youtubeKey: string;
private readonly spotify: Spotify;
constructor(@inject(TYPES.Lib.YouTube) youtube: YouTube, @inject(TYPES.Config.YOUTUBE_API_KEY) youtubeKey: string, @inject(TYPES.Lib.Spotify) spotify: Spotify) {
this.youtube = youtube;
this.youtubeKey = youtubeKey;
this.spotify = spotify;
constructor(@inject(TYPES.ThirdParty) thirdParty: ThirdParty, @inject(TYPES.Config) config: Config) {
this.youtube = thirdParty.youtube;
this.youtubeKey = config.YOUTUBE_API_KEY;
this.spotify = thirdParty.spotify;
}
async youtubeVideoSearch(query: string): Promise<QueuedSongWithoutChannel|null> {
@ -214,7 +216,7 @@ export default class {
private async spotifyToYouTube(track: SpotifyApi.TrackObjectSimplified, _: QueuedPlaylist | null): Promise<QueuedSongWithoutChannel | null> {
try {
const {items} = await this.youtube.videos.search({q: `"${track.name}" "${track.artists[0].name}"`, maxResults: 10});
const videoResult = items[0]; // Items.find(item => item.type === 'video');
const videoResult = items[0];
if (!videoResult) {
throw new Error('No video found for query.');

View file

@ -0,0 +1,36 @@
import {inject, injectable} from 'inversify';
import SpotifyWebApi from 'spotify-web-api-node';
import Youtube from 'youtube.ts';
import {TYPES} from '../types';
import Config from './config';
@injectable()
export default class ThirdParty {
readonly youtube: Youtube;
readonly spotify: SpotifyWebApi;
private spotifyTokenTimerId?: NodeJS.Timeout;
constructor(@inject(TYPES.Config) config: Config) {
this.youtube = new Youtube(config.YOUTUBE_API_KEY);
this.spotify = new SpotifyWebApi({
clientId: config.SPOTIFY_CLIENT_ID,
clientSecret: config.SPOTIFY_CLIENT_SECRET
});
void this.refreshSpotifyToken();
}
cleanup() {
if (this.spotifyTokenTimerId) {
clearTimeout(this.spotifyTokenTimerId);
}
}
private async refreshSpotifyToken() {
const auth = await this.spotify.clientCredentialsGrant();
this.spotify.setAccessToken(auth.body.access_token);
this.spotifyTokenTimerId = setTimeout(this.refreshSpotifyToken, (auth.body.expires_in / 2) * 1000);
}
}