improve error-checking and add username to some responses
Previously clippy was left in an unresponsive state if an authentication error occured, or in some cases if the remote server dropped the connection without sending a close() message. Clippy now terminates the socket connection on every connection error or authentication error, waits 5 seconds, and tries again. Also added username to the response function, and added a couple of extra responses.
This commit is contained in:
parent
0ba65f833c
commit
e5728006bc
147
index.js
147
index.js
|
@ -26,8 +26,14 @@ const headers = {
|
||||||
'Authorization' : `Bearer ${access_token}`
|
'Authorization' : `Bearer ${access_token}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resetConnection(socket) {
|
||||||
|
terminate(socket)
|
||||||
|
console.log(`waiting after error`)
|
||||||
|
setTimeout( function() { listen() }, 5000)
|
||||||
|
}
|
||||||
|
|
||||||
// set up bot account with correct settings
|
// set up bot account with correct settings
|
||||||
function initiateSettings() {
|
function initiateSettings(socket) {
|
||||||
|
|
||||||
let account = {
|
let account = {
|
||||||
locked: false,
|
locked: false,
|
||||||
|
@ -40,37 +46,42 @@ function initiateSettings() {
|
||||||
return axios.patch(`https://${domain}/api/v1/accounts/update_credentials`, account, { headers: headers })
|
return axios.patch(`https://${domain}/api/v1/accounts/update_credentials`, account, { headers: headers })
|
||||||
.catch( err => {
|
.catch( err => {
|
||||||
console.error('ERROR applying bot user settings: ', err.message)
|
console.error('ERROR applying bot user settings: ', err.message)
|
||||||
|
terminate(socket)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// return random suggestion string
|
// return random suggestion string
|
||||||
function suggestion() {
|
function suggestion(username) {
|
||||||
|
|
||||||
const n = crypto.randomInt(6)
|
const n = crypto.randomInt(8)
|
||||||
|
|
||||||
switch(n) {
|
switch(n) {
|
||||||
case 0:
|
case 0:
|
||||||
return 'How about logging off instead?';
|
return 'How about logging off instead?';
|
||||||
case 1:
|
case 1:
|
||||||
return 'Would you like to delete your toot?';
|
return `Would you like to delete your toot, ${username}?`;
|
||||||
case 2:
|
case 2:
|
||||||
return 'Can I help you take a walk outside?';
|
return 'Can I help you take a walk outside?';
|
||||||
case 3:
|
case 3:
|
||||||
return 'You may like to reconsider your life choices.';
|
return 'You may like to reconsider your life choices.';
|
||||||
case 4:
|
case 4:
|
||||||
return 'Why not try looking at #CatsOfInstagram instead?';
|
return 'Why not try looking at #CatsOfMastodon instead?';
|
||||||
case 5:
|
case 5:
|
||||||
return `You're better than this, come on.`;
|
return `Come on ${username}, we've talked about this.`;
|
||||||
|
case 6:
|
||||||
|
return `You should go look at some trees. Trees are calming`;
|
||||||
|
case 7:
|
||||||
|
return `I'm not angry. I'm just very disappointed.`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// send a message when someone toots about the topic
|
// send a message when someone toots about the topic
|
||||||
function sendResponse(rip, user) {
|
function sendResponse(rid, user, username) {
|
||||||
|
|
||||||
let payload = {
|
let payload = {
|
||||||
'status' : `@${user} It looks like you're posting about '${topic}'. ${suggestion()}`,
|
'status' : `@${user} It looks like you're posting about '${topic}'. ${suggestion(username)}`,
|
||||||
'spoiler_text' : topic,
|
'spoiler_text' : topic,
|
||||||
'in_reply_to_id' : rip,
|
'in_reply_to_id' : rid,
|
||||||
}
|
}
|
||||||
|
|
||||||
axios.post(`https://${domain}/api/v1/statuses`, payload, { headers: headers })
|
axios.post(`https://${domain}/api/v1/statuses`, payload, { headers: headers })
|
||||||
|
@ -108,66 +119,80 @@ function filterMentions(text, mentions) {
|
||||||
// STREAMING USER TIMELINE
|
// STREAMING USER TIMELINE
|
||||||
// This is where the action is!
|
// This is where the action is!
|
||||||
// ***********************
|
// ***********************
|
||||||
const ws = new WebSocket(`wss://${domain}/api/v1/streaming?access_token=${access_token}&stream=user`)
|
|
||||||
|
|
||||||
// make sure bot is set up correctly each time it starts
|
function terminate(socket) {
|
||||||
initiateSettings()
|
console.error(`Terminating connection...`)
|
||||||
|
socket.terminate()
|
||||||
|
console.log(`Terminated`)
|
||||||
|
}
|
||||||
|
|
||||||
// errors
|
function listen() {
|
||||||
ws.on('error', err => {
|
|
||||||
console.error(`WebSocket error: ${err.message}`)
|
|
||||||
})
|
|
||||||
|
|
||||||
// check updates and notifications in the stream
|
console.log(`Listening...`)
|
||||||
ws.on('message', msg => {
|
const ws = new WebSocket(`wss://${domain}/api/v1/streaming?access_token=${access_token}&stream=user`)
|
||||||
let packet = JSON.parse(msg)
|
|
||||||
let data = JSON.parse(packet.payload)
|
|
||||||
|
|
||||||
// notifications
|
// make sure bot is set up correctly each time it starts
|
||||||
if (packet.event == 'notification') {
|
initiateSettings(ws)
|
||||||
|
|
||||||
// always follow back
|
// errors
|
||||||
if (data.type == 'follow') {
|
ws.on('error', err => {
|
||||||
followAction(data.account.id, 'follow')
|
console.error(`WebSocket error: ${err.message}`)
|
||||||
}
|
resetConnection(ws)
|
||||||
|
})
|
||||||
if (data.type == 'mention') {
|
|
||||||
|
// check updates and notifications in the stream
|
||||||
let post = data.status.content
|
ws.on('message', msg => {
|
||||||
|
let packet = JSON.parse(msg)
|
||||||
// check start requests
|
let data = JSON.parse(packet.payload)
|
||||||
if (post.match(/\bSTART\b/)) {
|
|
||||||
|
// notifications
|
||||||
|
if (packet.event == 'notification') {
|
||||||
|
|
||||||
|
// always follow back
|
||||||
|
if (data.type == 'follow') {
|
||||||
followAction(data.account.id, 'follow')
|
followAction(data.account.id, 'follow')
|
||||||
}
|
}
|
||||||
|
|
||||||
// check stop requests
|
if (data.type == 'mention') {
|
||||||
if (post.match(/\STOP\b/)) {
|
|
||||||
followAction(data.account.id, 'unfollow')
|
let post = data.status.content
|
||||||
|
|
||||||
|
// check start requests
|
||||||
|
if (post.match(/\bSTART\b/)) {
|
||||||
|
followAction(data.account.id, 'follow')
|
||||||
|
}
|
||||||
|
|
||||||
|
// check stop requests
|
||||||
|
if (post.match(/\STOP\b/)) {
|
||||||
|
followAction(data.account.id, 'unfollow')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// updates (posts)
|
||||||
// updates (posts)
|
if (packet.event == 'update') {
|
||||||
if (packet.event == 'update') {
|
let rid = data.id
|
||||||
let rip = data.id
|
let user = data.account.acct
|
||||||
let user = data.account.acct
|
let username = data.account.username
|
||||||
// get just the account names (@name@domain.tld)
|
// get just the account names (@name@domain.tld)
|
||||||
let mentions = data.mentions.map( mention => mention.acct)
|
let mentions = data.mentions.map( mention => mention.acct)
|
||||||
// exclude own toots and @mentions to avoid an infinite loops
|
// exclude own toots and @mentions to avoid an infinite loops
|
||||||
if (data.account.username !== clippy && !mentions.includes(clippy)) {
|
if (username !== clippy && !mentions.includes(clippy)) {
|
||||||
// get rid of mentions in case topic is within a username
|
// get rid of mentions in case topic is within a username
|
||||||
let text = filterMentions(data.content, mentions)
|
let text = filterMentions(data.content, mentions)
|
||||||
if ( text.toLowerCase().includes(topic) ) {
|
if ( text.toLowerCase().includes(topic) ) {
|
||||||
sendResponse(rip, user)
|
sendResponse(rid, user, username)
|
||||||
}
|
}
|
||||||
else if (data.spoiler_text.toLowerCase().includes(topic)) {
|
else if (data.spoiler_text.toLowerCase().includes(topic)) {
|
||||||
sendResponse(rip, user)
|
sendResponse(rid, user, username)
|
||||||
}
|
}
|
||||||
else if (data.tags.map(tag => tag.name.toLowerCase()).includes(topic)) {
|
else if (data.tags.map(tag => tag.name.toLowerCase()).includes(topic)) {
|
||||||
sendResponse(rip, user)
|
sendResponse(rid, user, username)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
})
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// let's go
|
||||||
|
listen()
|
Loading…
Reference in a new issue