Skip to content

Instantly share code, notes, and snippets.

@Fleker
Created December 18, 2018 22:48
Show Gist options
  • Save Fleker/5778fc3596e4122582770d831f84aafa to your computer and use it in GitHub Desktop.
Save Fleker/5778fc3596e4122582770d831f84aafa to your computer and use it in GitHub Desktop.
YouTube Plays Smart Home - Script
'use strict';
const fetch = require('isomorphic-fetch')
const delay = require('delay')
// Get Google Assistant code from https://github.com/googlesamples/assistant-sdk-nodejs
const {GoogleAssistant} = require('./google-assistant')
// Follow instructions in README to generate a credentials file and refer to it here
const assistant = new GoogleAssistant(require('./prod-credentials.json'))
// Get YouTube API key and place it in this file
const {apiKey} = require('./api-key.json')
const youtubeVideoDetails = 'https://www.googleapis.com/youtube/v3/videos'
const youtubeLiveChat = 'https://www.googleapis.com/youtube/v3/liveChat/messages'
let readChats = new Set()
let totalMessages = 0
let totalAuthors = new Set()
const getChatData = async (videoId) => {
const videoDetailsPart = 'liveStreamingDetails'
const detailsRaw = await fetch(`${youtubeVideoDetails}?part=liveStreamingDetails&id=${videoId}&key=${apiKey}`)
const details = await detailsRaw.json()
const liveChatId = details.items[0].liveStreamingDetails.activeLiveChatId
const chatsRaw = await fetch(`${youtubeLiveChat}?liveChatId=${liveChatId}&part=snippet&key=${apiKey}`)
const chats = await chatsRaw.json()
const chatArray = []
const newChatsArray = []
chats.items.forEach(chatItem => {
const message = chatItem.snippet.displayMessage
const author = chatItem.snippet.authorChannelId
chatArray.push(message)
if (readChats.has(chatItem.id)) {
return // We already processed this one
}
readChats.add(chatItem.id)
totalMessages++
totalAuthors.add(author)
newChatsArray.push({message, author})
});
return {
liveChatId: liveChatId,
allChats: chatArray,
newChats: newChatsArray
}
}
async function asyncForEach(array, callback) {
for (let index = 0; index < array.length; index++) {
await callback(array[index], index, array)
}
}
// Run indefinitely
(async function() {
const videoId = 'ExTljyJWzGY' // Or whatever livestream ID that you have
// Repeat indefinitely
while (true) {
const {newChats} = await getChatData(videoId)
if (newChats && newChats.length > 0) {
await asyncForEach(newChats, async ({message, author}) => {
try {
console.log(` ${message}`)
const response = await assistant.assist(message)
} catch (e) {
console.error(`Error: ${e}`)
}
})
console.log(`Got ${newChats.length} new message(s) of a total ${totalMessages} from ${totalAuthors.size} unique users`)
}
// Add a delay so we don't accidentally exceed quota
await delay(50); // Delay of 0.05s for polling YouTube
}
})()
{
"name": "youtube-plays-smart-home",
"private": true,
"version": "0.1.0",
"description": "One-stopshop!",
"engines": {
"node": "^8.0.0"
},
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"dependencies": {
"dateformat": "^3.0.3",
"delay": "^4.1.0",
"firebase": "^3.1.0",
"ip": "^1.1.3",
"isomorphic-fetch": "^2.2.1",
"pg": "4.x",
"google-auth-library": "0.12.0",
"google-proto-files": "^0.15.0",
"google-protobuf": "^3.3.0",
"grpc": "^1.0.0"
},
"repository": {
"type": "git"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment