2022-03-03 11:23:22 -05:00
|
|
|
const { App: SlackApp } = require('@slack/bolt')
|
|
|
|
const config = require('../config')
|
2023-06-29 10:41:55 -04:00
|
|
|
const fs = require('fs')
|
|
|
|
const { addReactions, saveGame, setSlackAppClientChatUpdate, parseOr } = require('../games/hvacoins/utils')
|
2022-03-03 11:23:22 -05:00
|
|
|
|
|
|
|
const temperatureChannelId = 'C034156CE03'
|
2023-06-29 10:41:55 -04:00
|
|
|
const dailyStandupChannelId = 'C03L533AU3Z'
|
2022-03-03 11:23:22 -05:00
|
|
|
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
const pollingMinutes = 5
|
2022-03-03 11:23:22 -05:00
|
|
|
const pollingPeriod = 1000 * 60 * pollingMinutes
|
|
|
|
|
2023-06-29 10:41:55 -04:00
|
|
|
const MAX_POLLS = 3
|
|
|
|
const HOURS_PER_WINDOW = 2
|
|
|
|
|
2022-03-03 11:23:22 -05:00
|
|
|
const colderEmoji = 'snowflake'
|
|
|
|
const hotterEmoji = 'fire'
|
|
|
|
const goodEmoji = '+1'
|
|
|
|
|
2023-06-29 10:41:55 -04:00
|
|
|
const app = new SlackApp({
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
token: config.slackBotToken,
|
|
|
|
signingSecret: config.slackSigningSecret,
|
|
|
|
appToken: config.slackAppToken,
|
|
|
|
socketMode: true
|
|
|
|
})
|
|
|
|
// app.client.conversations.list({types: 'private_channel'}).then(fetched => {
|
|
|
|
// temperatureChannelId = fetched.channels.filter(channel => channel.name === 'thermo-posting')[0].id
|
|
|
|
// console.log('techThermostatChannelId', temperatureChannelId)
|
|
|
|
// })
|
2022-03-03 11:23:22 -05:00
|
|
|
|
2022-05-19 11:09:16 -04:00
|
|
|
const pollTriggers = ['!temp', '!temperature', '!imhot', '!imcold', '!imfreezing', '!idonthavemysweater']
|
2022-03-03 11:23:22 -05:00
|
|
|
const halfTriggers = ['change temperature', "i'm cold", "i'm hot", 'quack', 'hvacker', '<@U0344TFA7HQ>']
|
|
|
|
|
|
|
|
const sendHelp = async (say, prefix) => {
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
if (prefix) {
|
|
|
|
prefix = prefix + '\n'
|
|
|
|
} else {
|
|
|
|
prefix = ''
|
|
|
|
}
|
2022-03-03 11:23:22 -05:00
|
|
|
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
await say({
|
|
|
|
text: prefix +
|
|
|
|
`Sending a message matching any of \`${pollTriggers.join('`, `')}\` will start a temperature poll.\n` +
|
2022-04-20 12:05:02 -04:00
|
|
|
'\'Hotter\' and \'Colder\' votes offset. E.g. with votes Hotter - 4, Colder - 3, and Content - 2, the temp won\'t change.\n' +
|
2023-08-03 10:49:02 -04:00
|
|
|
`At this time I am not capable of actually changing the temperature. Go bug ${users.ThermoController}.`
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
})
|
2022-03-03 11:23:22 -05:00
|
|
|
}
|
|
|
|
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
const getMessage = async ({ channel, ts }) => app.client.conversations.history({
|
|
|
|
channel: channel,
|
|
|
|
latest: ts,
|
|
|
|
inclusive: true,
|
|
|
|
limit: 1
|
2022-03-03 11:23:22 -05:00
|
|
|
})
|
|
|
|
|
|
|
|
app.event('reaction_added', async ({ event, context, client, say }) => {
|
2022-05-19 11:09:16 -04:00
|
|
|
console.log('reaction_added', event)
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
for (const listener of reactionListeners) {
|
|
|
|
listener({ event, say })
|
|
|
|
}
|
2022-03-03 11:23:22 -05:00
|
|
|
})
|
|
|
|
|
2023-06-29 10:41:55 -04:00
|
|
|
const users = parseOr(fs.readFileSync('./users.json', 'utf-8'),
|
|
|
|
() => ({}))
|
2022-03-03 11:23:22 -05:00
|
|
|
|
2022-05-19 11:09:16 -04:00
|
|
|
const buildSayPrepend = ({ say, prepend }) => async msg => {
|
|
|
|
if (typeof(msg) === 'string') {
|
|
|
|
return say(prepend + msg)
|
|
|
|
}
|
|
|
|
return say({
|
|
|
|
...msg,
|
|
|
|
text: prepend + msg.text
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
process.once('SIGINT', code => {
|
2023-08-03 10:49:02 -04:00
|
|
|
saveGame('SIGINT', true)
|
2022-05-19 11:09:16 -04:00
|
|
|
process.exit()
|
|
|
|
})
|
|
|
|
|
2023-06-29 10:41:55 -04:00
|
|
|
let pollHistory = []
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
const activePolls = {}
|
|
|
|
const testId = 'U028BMEBWBV_TEST'
|
|
|
|
let testMode = false
|
2022-03-03 11:23:22 -05:00
|
|
|
app.event('message', async ({ event, context, client, say }) => {
|
2022-05-19 11:09:16 -04:00
|
|
|
if (event.subtype !== 'message_changed' && event?.text !== '!') {
|
|
|
|
console.log('message.event', {
|
|
|
|
...event,
|
|
|
|
userName: users[event.user]
|
|
|
|
})
|
2022-04-20 12:05:02 -04:00
|
|
|
}
|
2023-06-29 10:41:55 -04:00
|
|
|
if (event?.user === users.Admin) {
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
if (event?.text.startsWith('!')) {
|
|
|
|
if (testMode) {
|
2023-06-29 10:41:55 -04:00
|
|
|
await messageAdmin('Currently in test mode!')
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
}
|
2022-03-03 11:23:22 -05:00
|
|
|
}
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
if (event?.text === '!test') {
|
|
|
|
testMode = !testMode
|
2023-06-29 10:41:55 -04:00
|
|
|
await messageAdmin(`TestMode: ${testMode} with ID ${testId}`)
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
} else if (event?.text === '!notest') {
|
|
|
|
testMode = false
|
2023-06-29 10:41:55 -04:00
|
|
|
await messageAdmin(`TestMode: ${testMode}`)
|
2022-03-03 11:23:22 -05:00
|
|
|
}
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
if (testMode) {
|
|
|
|
event.user = testId
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (const listener of messageListeners) {
|
|
|
|
listener({ event, say })
|
|
|
|
}
|
2022-04-20 12:05:02 -04:00
|
|
|
if (event.user) {
|
|
|
|
console.log('MSG', users[event.user], "'" + event.text + "'", new Date().toLocaleTimeString())
|
|
|
|
}
|
2023-06-29 10:41:55 -04:00
|
|
|
if (event.user === users.Admin && event.channel === 'D0347Q4H9FE') {
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
if (event.text === '!!kill') {
|
2023-08-03 10:49:02 -04:00
|
|
|
saveGame('!!kill', true)
|
2022-05-19 11:09:16 -04:00
|
|
|
process.exit(1)
|
|
|
|
} else if (event.text === '!!restart') {
|
2023-06-29 10:41:55 -04:00
|
|
|
if (Object.entries(activePolls).length === 0) {
|
2023-08-03 10:49:02 -04:00
|
|
|
saveGame('!!restart', true)
|
2023-06-29 10:41:55 -04:00
|
|
|
process.exit(0)
|
|
|
|
} else {
|
|
|
|
await messageAdmin('Restart pending poll completion...')
|
|
|
|
pendingRestart = true
|
|
|
|
}
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
}
|
|
|
|
if (event.text?.startsWith('!say ') || event.text?.startsWith('!say\n')) {
|
2023-06-29 10:41:55 -04:00
|
|
|
await postToTechThermostatChannel(event.text.substring(4).trim().replace('@here', '<!here>'))
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const eventText = event.text?.toLowerCase() || ''
|
|
|
|
|
2022-04-20 12:05:02 -04:00
|
|
|
if (eventText === '!help') {
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
await sendHelp(say)
|
|
|
|
return
|
|
|
|
}
|
2022-03-03 11:23:22 -05:00
|
|
|
|
2023-06-29 10:41:55 -04:00
|
|
|
if (!pollTriggers.includes(eventText) || event.user === users.John) {
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
if (halfTriggers.includes(eventText)) {
|
|
|
|
await sendHelp(say, 'It looks like you might want to change the temperature.')
|
2022-03-03 11:23:22 -05:00
|
|
|
}
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
return
|
|
|
|
}
|
2023-06-29 10:41:55 -04:00
|
|
|
|
|
|
|
if (event.channel !== temperatureChannelId) {
|
|
|
|
return say(`Please request polls in the appropriate channel.`)
|
|
|
|
}
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
|
|
|
|
if (activePolls[event.channel]) {
|
|
|
|
await postToTechThermostatChannel({ text: "There's already an active poll in this channel!" })
|
|
|
|
return
|
|
|
|
}
|
2023-06-29 10:41:55 -04:00
|
|
|
const now = new Date()
|
|
|
|
const windowStart = new Date()
|
|
|
|
windowStart.setHours(now.getHours() - HOURS_PER_WINDOW)
|
|
|
|
|
|
|
|
const pollsInWindow = pollHistory.filter(pollTime => pollTime > windowStart)
|
|
|
|
const pollText = MAX_POLLS === 1 ? 'poll' : 'polls'
|
|
|
|
const hourText = HOURS_PER_WINDOW === 1 ? 'hour' : 'hours'
|
|
|
|
|
|
|
|
if (pollsInWindow.length >= MAX_POLLS) {
|
|
|
|
await postToTechThermostatChannel({ text: `You have exceeded the limit of ${MAX_POLLS} ${pollText} per ${HOURS_PER_WINDOW} ${hourText}!` })
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pollHistory.push(now) > MAX_POLLS) {
|
|
|
|
[, ...pollHistory] = pollHistory
|
|
|
|
}
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
|
|
|
|
activePolls[event.channel] = true
|
|
|
|
const pollTs = await startPoll()
|
|
|
|
setTimeout(async () => {
|
|
|
|
const reactions = await app.client.reactions.get({
|
|
|
|
channel: temperatureChannelId,
|
|
|
|
timestamp: pollTs,
|
|
|
|
full: true
|
|
|
|
})
|
2022-04-20 12:05:02 -04:00
|
|
|
|
|
|
|
const reactPosters = {}
|
|
|
|
reactions.message.reactions.forEach(r => r.users.forEach(user => {
|
|
|
|
reactPosters[user] ??= []
|
|
|
|
reactPosters[user].push(r.name)
|
|
|
|
}))
|
|
|
|
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
const reactCounts = {}
|
2022-04-20 12:05:02 -04:00
|
|
|
Object.entries(reactPosters).forEach(([id, votes]) => {
|
2022-05-03 09:56:10 -04:00
|
|
|
console.log(`VOTES FROM ${id}:`, votes)
|
|
|
|
votes = votes.filter(v => [goodEmoji, hotterEmoji, colderEmoji].find(emoji => v.startsWith(emoji)))
|
2022-04-20 12:05:02 -04:00
|
|
|
if (votes.length === 1) {
|
2022-05-03 09:56:10 -04:00
|
|
|
const name = votes[0].replace(/:.*/g, '')
|
|
|
|
reactCounts[name] ??= 0
|
|
|
|
reactCounts[name] += 1
|
2022-04-20 12:05:02 -04:00
|
|
|
}
|
|
|
|
})
|
2022-05-19 11:09:16 -04:00
|
|
|
console.log('REACT COUNTS', JSON.stringify(reactCounts))
|
2022-03-03 11:23:22 -05:00
|
|
|
|
2022-04-20 12:05:02 -04:00
|
|
|
const contentVotes = reactCounts[goodEmoji] || 0
|
|
|
|
let hotterVotes = reactCounts[hotterEmoji] || 0
|
|
|
|
let colderVotes = reactCounts[colderEmoji] || 0
|
|
|
|
console.log('before contentVotes', contentVotes)
|
|
|
|
console.log('before colderVotes', colderVotes)
|
|
|
|
console.log('before hotterVotes', hotterVotes)
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
|
2022-04-20 12:05:02 -04:00
|
|
|
if (hotterVotes > colderVotes) {
|
|
|
|
hotterVotes -= colderVotes
|
|
|
|
colderVotes = 0
|
|
|
|
} else if (colderVotes > hotterVotes) {
|
|
|
|
colderVotes -= hotterVotes
|
|
|
|
hotterVotes = 0
|
|
|
|
}
|
|
|
|
console.log('after contentVotes', contentVotes)
|
|
|
|
console.log('after colderVotes', colderVotes)
|
|
|
|
console.log('after hotterVotes', hotterVotes)
|
|
|
|
|
|
|
|
let text
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
if (hotterVotes > colderVotes && hotterVotes > contentVotes) {
|
2023-08-03 10:49:02 -04:00
|
|
|
text = `<@${users[users.ThermoController]}> The people have spoken, and would like to `
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
text += 'raise the temperature, quack.'
|
|
|
|
requestTempChange('Hotter')
|
|
|
|
} else if (colderVotes > hotterVotes && colderVotes > contentVotes) {
|
2023-08-03 10:49:02 -04:00
|
|
|
text = `<@${users[users.ThermoController]}> The people have spoken, and would like to `
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
text += 'lower the temperature, quack quack.'
|
|
|
|
requestTempChange('Colder')
|
|
|
|
} else {
|
2022-04-20 12:05:02 -04:00
|
|
|
text = `The people have spoken, and would like to `
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
text += 'keep the temperature as-is, quaaack.'
|
|
|
|
requestTempChange('Good')
|
2022-03-03 11:23:22 -05:00
|
|
|
}
|
|
|
|
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
await postToTechThermostatChannel({ text })
|
|
|
|
delete activePolls[event.channel]
|
2023-06-29 10:41:55 -04:00
|
|
|
if (pendingRestart && Object.entries(activePolls).length === 0) {
|
|
|
|
await messageAdmin('Performing pending restart!')
|
|
|
|
saveGame(null, true)
|
|
|
|
process.exit(0)
|
|
|
|
}
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
}, pollingPeriod)
|
2022-03-03 11:23:22 -05:00
|
|
|
})
|
|
|
|
|
2023-06-29 10:41:55 -04:00
|
|
|
let pendingRestart = false
|
|
|
|
|
2022-03-03 11:23:22 -05:00
|
|
|
;(async () => {
|
2023-06-29 10:41:55 -04:00
|
|
|
await app.start()
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
console.log('Slack Bolt has started')
|
|
|
|
})()
|
2022-03-03 11:23:22 -05:00
|
|
|
|
|
|
|
const postToTechThermostatChannel = async optionsOrText => {
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
if (optionsOrText === null || typeof optionsOrText !== 'object') {
|
|
|
|
optionsOrText = {
|
|
|
|
text: optionsOrText
|
2022-03-03 11:23:22 -05:00
|
|
|
}
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
}
|
|
|
|
return app.client.chat.postMessage({ ...optionsOrText, channel: temperatureChannelId })
|
2022-03-03 11:23:22 -05:00
|
|
|
}
|
|
|
|
|
2023-06-29 10:41:55 -04:00
|
|
|
const messageAdmin = async optionsOrText => messageIn(users.Admin, optionsOrText)
|
2022-03-03 11:23:22 -05:00
|
|
|
|
|
|
|
const messageIn = async (channel, optionsOrText) => {
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
if (optionsOrText === null || typeof optionsOrText !== 'object') {
|
|
|
|
optionsOrText = {
|
|
|
|
text: optionsOrText
|
2022-03-03 11:23:22 -05:00
|
|
|
}
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
}
|
|
|
|
return app.client.chat.postMessage({ ...optionsOrText, channel })
|
2022-03-03 11:23:22 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
const startPoll = async () => {
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
const sent = await postToTechThermostatChannel({
|
2023-08-03 10:49:02 -04:00
|
|
|
text: `<!here> Temperature poll requested! In ${pollingMinutes} minutes the temperature will be adjusted.
|
|
|
|
Pick :${colderEmoji}: if you want it colder, :${hotterEmoji}: if you want it hotter, or :${goodEmoji}: if you like it how it is.
|
|
|
|
(Note that I can't actually change the temperature yet. Make ${users.ThermoController} do it!)`
|
2022-04-20 12:05:02 -04:00
|
|
|
})
|
|
|
|
await addReactions({
|
|
|
|
app,
|
|
|
|
channelId: temperatureChannelId,
|
|
|
|
timestamp: sent.ts,
|
|
|
|
reactions: [colderEmoji, hotterEmoji, goodEmoji]
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
})
|
|
|
|
return sent.ts
|
2022-03-03 11:23:22 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
const tempChangeListeners = []
|
|
|
|
const messageListeners = []
|
|
|
|
const reactionListeners = []
|
|
|
|
|
|
|
|
const requestTempChange = change => {
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
tempChangeListeners.forEach(listener => listener(change))
|
2022-03-03 11:23:22 -05:00
|
|
|
}
|
|
|
|
|
2023-06-29 10:41:55 -04:00
|
|
|
// noinspection HttpUrlsUsage
|
2022-03-03 11:23:22 -05:00
|
|
|
const encodeData = (key, data) =>
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
`<http://${key}ZZZ${Buffer.from(JSON.stringify(data), 'utf-8').toString('base64')}| >`
|
2022-03-03 11:23:22 -05:00
|
|
|
|
|
|
|
const decodeData = (key, message) => {
|
2023-06-29 10:41:55 -04:00
|
|
|
try {
|
|
|
|
const regex = new RegExp(`http://${key}ZZZ[^|]*`)
|
|
|
|
let match = message.match(regex)
|
|
|
|
if (!match) {
|
|
|
|
return match
|
|
|
|
}
|
|
|
|
match = match[0].substring(10 + key.length) // 10 === 'http://'.length + 'ZZZ'.length
|
|
|
|
return JSON.parse(Buffer.from(match, 'base64').toString('utf-8'))
|
|
|
|
} catch (e) {
|
|
|
|
console.error(e)
|
|
|
|
return null
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
}
|
2022-03-03 11:23:22 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
const onReaction = listener => reactionListeners.push(listener)
|
|
|
|
|
2022-05-19 11:09:16 -04:00
|
|
|
const channelIsIm = async channel => (await app.client.conversations.info({ channel }))?.channel?.is_im
|
|
|
|
|
2023-06-29 10:41:55 -04:00
|
|
|
const wasMyMessage = async event => {
|
|
|
|
const text = (await app.client.conversations.history({
|
|
|
|
channel: event.item.channel,
|
|
|
|
latest: event.item.ts,
|
|
|
|
limit: 1,
|
|
|
|
inclusive: true
|
|
|
|
})).messages[0].text
|
|
|
|
|
|
|
|
const decoded = decodeData('commandPayload', text)
|
|
|
|
return decoded.event.user === event.user
|
|
|
|
}
|
|
|
|
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
onReaction(async ({ event }) => {
|
2023-06-29 10:41:55 -04:00
|
|
|
console.log({ event })
|
|
|
|
if (event.reaction === 'x' && (event.user === users.Admin || (await wasMyMessage(event)) || await channelIsIm(event.item.channel))) {
|
2022-05-19 11:09:16 -04:00
|
|
|
try {
|
|
|
|
await app.client.chat.delete({ channel: event.item.channel, ts: event.item.ts })
|
|
|
|
} catch (e) {
|
2022-03-03 11:23:22 -05:00
|
|
|
}
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
}
|
2022-03-03 11:23:22 -05:00
|
|
|
})
|
|
|
|
|
2023-06-29 10:41:55 -04:00
|
|
|
setSlackAppClientChatUpdate(app.client.chat.update)
|
|
|
|
|
2022-03-03 11:23:22 -05:00
|
|
|
module.exports = {
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
app,
|
|
|
|
temperatureChannelId,
|
2023-06-29 10:41:55 -04:00
|
|
|
dailyStandupChannelId,
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
onAction: app.action,
|
|
|
|
getMessage,
|
|
|
|
updateMessage: app.client.chat.update,
|
|
|
|
postToTechThermostatChannel,
|
|
|
|
onTempChangeRequested: listener => tempChangeListeners.push(listener),
|
|
|
|
onMessage: listener => messageListeners.push(listener),
|
|
|
|
onReaction,
|
|
|
|
encodeData,
|
|
|
|
decodeData,
|
2023-06-29 10:41:55 -04:00
|
|
|
messageAdmin,
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
messageIn,
|
|
|
|
testMode,
|
|
|
|
testId,
|
2022-05-19 11:09:16 -04:00
|
|
|
users,
|
2023-06-29 10:41:55 -04:00
|
|
|
buildSayPrepend,
|
|
|
|
pollTriggers,
|
|
|
|
pendingRestart
|
Many improvements and additions.
Several new achievements.
Separate files for buy route, webapi, and shared utils.
Add Creator buyable item.
Access control now object-based.
Toying with Trivia and a lottery system.
!cleanusers, !setpw, !rach, !myupgrades, !squad, !gimme, !prestige,
!quack, !whois, !ngift, !message, !!kill,
Add simple test user system.
Add several oneShot commands.
2022-03-14 08:37:38 -04:00
|
|
|
}
|