diff --git a/fgfm.TODO b/fgfm.TODO index 5f0417f..6babb46 100755 --- a/fgfm.TODO +++ b/fgfm.TODO @@ -1,11 +1,15 @@ TODO: ☐ Spotify integration - ✔ !song -- display current song + link @done (18-12-04 11:24) - ✔ !playlist -- display current context / album @done (18-12-04 11:24) - ✔ !skip -- mods auto-skip @done (18-12-04 11:47) - ☐ !volume -- volume adjustment - ✔ !pause / !resume @done (18-12-04 11:49) + ✔ song -- display current song + link @done (18-12-04 11:24) + ✔ playlist -- display current context / album @done (18-12-04 11:24) + ✔ skip -- mods auto-skip @done (18-12-04 11:47) + ✔ volume -- volume adjustment @done (18-12-04 19:49) + ✔ pause / resume @done (18-12-04 11:49) + ✔ ability to change the playlist (setplaylist ) @done (18-12-11 10:52) + ✔ shuffle on/off @done (18-12-11 11:22) + ✔ repeat mode control @done (18-12-11 11:22) ☐ Web interface for viewers to issue commands + ☐ Organized room / video list, one-click add-to-queue ☐ Admin panel on website for control ☐ Add support for a command to mute/unmute audio sources ☐ Don't re-create queue on start if it already exists @@ -32,9 +36,9 @@ TODO: ☐ Stats tracking for games ☐ Most won/lost gambling ☐ Most trivia answered + ☐ Allow %'s for !gamble -Ideas: - ☐ Support songrequests -- play through discord? +Ideas: StreamWebRemote: - OBS Websocket Connection Mgmt diff --git a/fgfm.js b/fgfm.js index a536731..af8a10c 100755 --- a/fgfm.js +++ b/fgfm.js @@ -318,6 +318,76 @@ const streamInit = (config, twitch) => { .catch(err => twitch.botChat.say(cmd.to, `Error setting spotify volume: ${JSON.stringify(err)}`)); }, + songplay: (cmd) => { + let url = cmd.args[1] || false; + if (url === false) { + return twitch.botChat.say(cmd.to, `You must provide a link to a spotify playlist or album!`); + } + + // parse+validate url + let spotifyUri = false; + + // check for native spotify URI first + if (url.includes('spotify:')) { + let parsedUrl = url.match(/spotify:(playlist|album):([A-Za-z0-9]{22})/); + if (parsedUrl !== null) { + spotifyUri = parsedUrl[0]; + } + } else if (url.includes('spotify.com')) { + // determine if it's an album or playlist + if (!url.includes('/playlist/') && !url.includes('/album/')) { + return twitch.botChat.say(cmd.to, `Spotify URL must be a playlist or album!`); + } + + // parse the URL to get the resource type and ID + let parsedUrl = url.match(/(playlist|album)\/([A-Za-z0-9]{22})/); + if (parsedUrl !== null) { + spotifyUri = `spotify:${parsedUrl[1]}:${parsedUrl[2]}`; + } else { + return twitch.botChat.say(cmd.to, `Unable to parse spotify URL!`); + } + } else { + return twitch.botChat.say(cmd.to, `Invalid spotify URL!`); + } + + if (spotifyUri !== false) { + spotify.playContext(spotifyUri) + .then(res => twitch.botChat.say(cmd.to, `Changed playlist!`)) + .catch(err => twitch.botChat.say(cmd.to, `Error changing playlist: ${JSON.stringify(err)}`)); + } else { + return twitch.botChat.say(cmd.to, `Unable to parse Spotify URL!`); + } + }, + + songshuffle: (cmd) => { + let state = cmd.args[1] || true; + + if (state === 'off' || state === 'false') { + state = false; + } else { + state = true; + } + + spotify.shuffle(state) + .then(res => twitch.botChat.say(cmd.to, `Updated shuffle state!`)) + .catch(err => twitch.botChat.say(cmd.to, `Error changing shuffle state: ${JSON.stringify(err)}`)) + }, + + songrepeat: (cmd) => { + let state = cmd.args[1] || false; + if (state === false) { + return twitch.botChat.say(cmd.to, `You must provide a repeat mode (track, context, or off)!`); + } + + if (!['track', 'context', 'off'].includes(state)) { + return twitch.botChat.say(cmd.to, `You must provide a valid repeat mode (track, context, or off)!`); + } + + spotify.repeat(state) + .then(res => twitch.botChat.say(cmd.to, `Updated repeat mode!`)) + .catch(err => twitch.botChat.say(cmd.to, `Error changing repeat mode: ${JSON.stringify(err)}`)) + }, + reboot: (cmd) => { console.log('Received request from admin to reboot...'); twitch.botChat.say(cmd.to, 'Rebooting...'); diff --git a/lib/spotify.js b/lib/spotify.js index b76b8e0..031817e 100755 --- a/lib/spotify.js +++ b/lib/spotify.js @@ -99,6 +99,10 @@ function Spotify(config) { }); }; + this.playContext = (uri) => { + return spotifyApi.play({"context_uri": uri}); + }; + this.skip = () => { return spotifyApi.skipToNext(); }; @@ -117,6 +121,14 @@ function Spotify(config) { if (volume > 100) volume = 100; return spotifyApi.setVolume(volume); }; + + this.shuffle = (state) => { + return spotifyApi.setShuffle({"state": state}); + }; + + this.repeat = (state) => { + return spotifyApi.setRepeat({"state": state}); + }; } module.exports = Spotify;