commit
1b10071d4a
@ -0,0 +1,92 @@ |
||||
import { ApiClient } from 'twitch'; |
||||
import { ClientCredentialsAuthProvider } from 'twitch-auth'; |
||||
import { NgrokAdapter } from 'twitch-webhooks-ngrok'; |
||||
import { SimpleAdapter, WebHookListener } from 'twitch-webhooks'; |
||||
import fetch from 'node-fetch'; |
||||
|
||||
const bearer = process.env.BEARER |
||||
const instance = process.env.INSTANCE |
||||
|
||||
const clientId = process.env.CLIENT_ID; |
||||
const clientSecret = process.env.CLIENT_SECRET; |
||||
const userName = process.env.USER; |
||||
const hostName = process.env.HOSTNAME; |
||||
|
||||
if (!(clientId && clientSecret && userName)) process.exit(1) |
||||
|
||||
const post = async ({ |
||||
status, spoiler_text, visibility = 'direct', content_type = 'text/plain' |
||||
}) => await fetch(`https://${instance}/api/v1/statuses`, { |
||||
"headers": { |
||||
"accept": '*/*', |
||||
"accept-language": 'en-US,en;q=0.9', |
||||
"authorization": `Bearer ${bearer}`, |
||||
"cache-control": 'no-cache', |
||||
"content-type": 'application/json', |
||||
"pragma": 'no-cache', |
||||
"sec-fetch-dest": 'empty', |
||||
"sec-fetch-mode": 'cors', |
||||
"sec-fetch-site": 'same-origin' |
||||
}, |
||||
"referrerPolicy": "same-origin", |
||||
"body": JSON.stringify({ |
||||
spoiler_text, status, source: 'HJ\'s twitch bot', visibility, content_type |
||||
}), |
||||
"method": "POST", |
||||
"mode": "cors", |
||||
"credentials": "include" |
||||
}); |
||||
|
||||
const authProvider = new ClientCredentialsAuthProvider(clientId, clientSecret); |
||||
const apiClient = new ApiClient({ authProvider }); |
||||
|
||||
console.info('Getting userid...') |
||||
const userId = await apiClient.helix.users.getUserByName(userName); |
||||
|
||||
const adapter = hostName |
||||
? new SimpleAdapter({ |
||||
hostName, |
||||
listenerPort: 8090 |
||||
}) |
||||
: new NgrokAdapter() |
||||
|
||||
const listener = new WebHookListener(apiClient, adapter); |
||||
console.info('Starting listener...') |
||||
await listener.listen(); |
||||
|
||||
// we need to track the previous status of the stream because there are other state changes than the live/offline switch
|
||||
let prevStream = await apiClient.helix.streams.getStreamByUserId(userId); |
||||
|
||||
console.info('Subscribing to events...') |
||||
console.log(prevStream) |
||||
const subscription = await listener.subscribeToStreamChanges(userId, async stream => { |
||||
if (stream) { |
||||
console.log(stream) |
||||
if (!prevStream) { |
||||
console.log(`${stream.userDisplayName} just went live with title: ${stream.title}`); |
||||
const status = [ |
||||
'Hej, hj just went live on twitch :annoying_dog_hole:', |
||||
'', |
||||
`Streaming ${stream.gameName}: ${stream.title}`, |
||||
'https://www.twitch.tv/hjkos', |
||||
'', |
||||
'Follow this bot and hit the bell to get notifications when hj is live' |
||||
].join('\n') |
||||
await post({ |
||||
spoiler_text: 'Stream announcment', |
||||
status |
||||
}) |
||||
} |
||||
} else { |
||||
// no stream, no display name
|
||||
const user = await apiClient.helix.users.getUserById(userId); |
||||
console.log(`${user.displayName} just went offline`); |
||||
} |
||||
prevStream = stream ?? null; |
||||
}); |
||||
console.info('Ready!') |
||||
|
||||
process.on('SIGINT', function() { |
||||
subscription.stop() |
||||
process.exit() |
||||
}); |
@ -0,0 +1,17 @@ |
||||
{ |
||||
"name": "hj-twitch-bot", |
||||
"version": "0.1.0", |
||||
"description": "HJ's twitch bot", |
||||
"main": "index.js", |
||||
"author": "twitch-bot@hjkos.com", |
||||
"license": "WTFPL", |
||||
"private": true, |
||||
"type": "module", |
||||
"dependencies": { |
||||
"node-fetch": "^2.6.1", |
||||
"twitch": "^4.5.5", |
||||
"twitch-auth": "^4.5.5", |
||||
"twitch-webhooks": "^4.5.5", |
||||
"twitch-webhooks-ngrok": "^4.5.5" |
||||
} |
||||
} |
Loading…
Reference in new issue