Last active
November 19, 2021 19:02
-
-
Save heathermhargreaves/8e69d5cd3e18e98abd22b31a9a0b3329 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require('dotenv').config({ debug: process.env.DEBUG }); | |
const { Client, Intents } = require('discord.js'); | |
const client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES, Intents.FLAGS.DIRECT_MESSAGES], partials: ['MESSAGE', 'CHANNEL'] }); | |
const fetch = require('node-fetch'); | |
const base64 = require('base-64'); | |
const twilioClient = require('twilio')(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN); | |
// --------------------------------------------------------------------------------------------------------------------------- | |
// Discord bot | |
// --------------------------------------------------------------------------------------------------------------------------- | |
let lookupTable = {}; | |
const User = class { | |
constructor(userId, userName, channelSid) { | |
this.userId = userId; | |
this.userName = userName; | |
this.channelSid = channelSid; | |
this.liveAgent = false; | |
} | |
}; | |
// When the client is ready, run this code (only once) | |
client.once('ready', async () => { | |
const channel = await client.channels.fetch(process.env.SUPPORT_CHANNEL_ID); | |
channel.send('I\'m alive!'); | |
console.log('Ready!'); | |
}); | |
client.on('messageCreate', async (message) => { | |
const author = message.author; | |
if (author.id == process.env.BOT_ID) { | |
return; | |
} | |
if (lookupTable[author.id] == undefined) { | |
const newUser = new User(author.id, author.username, undefined); | |
lookupTable[author.id] = newUser; | |
} | |
if (message.channel.type == 'GUILD_TEXT' && message.content.toLowerCase().includes('help')) { | |
message.author.send('** Hello, I\'m here to help.**'); | |
} | |
else if (message.channel.type == 'DM') { | |
if (message.content.toLowerCase().includes('agent')) { | |
lookupTable[author.id].liveAgent = true; | |
message.author.send('** Now connecting you to a live agent.**'); | |
} | |
if (lookupTable[author.id].liveAgent) { | |
if (lookupTable[author.id].channelSid == undefined) { | |
const chatChannelSid = await createNewChannel(author.id); | |
lookupTable[author.id].channelSid = chatChannelSid; | |
await sendChatMessage(chatChannelSid, author.id, message.content); | |
} | |
else { | |
await sendChatMessage(lookupTable[author.id].channelSid, author.id, message.content); | |
} | |
} | |
else { | |
message.author.send('** I don\'t understand. Please try again. **'); | |
} | |
} | |
}); | |
client.login(process.env.DISCORD_TOKEN); | |
// ---------------------------------------------------------------------------------------------------------------- | |
// Twilio | |
// ---------------------------------------------------------------------------------------------------------------- | |
const createNewChannel = async (chatUserName) => { | |
const twilioChannel = await twilioClient.flexApi.channel | |
.create({ | |
flexFlowSid: process.env.TWILIO_FLEX_FLOW_ID, | |
identity: chatUserName, | |
chatUserFriendlyName: lookupTable[chatUserName].userName, | |
chatFriendlyName: 'Flex Custom Chat', | |
target: chatUserName, | |
}); | |
lookupTable[chatUserName].channelSid = twilioChannel.sid; | |
const onMessageSent = await twilioClient | |
.chat | |
.services(process.env.TWILIO_FLEX_CHAT_ID) | |
.channels(twilioChannel.sid) | |
.webhooks | |
.create({ | |
type: 'webhook', | |
'configuration.method': 'POST', | |
'configuration.url': `${process.env.NGROK_URL}/new-message?channel=${twilioChannel.sid}&user=${chatUserName}`, | |
'configuration.filters': ['onMessageSent'], | |
}); | |
const onChannelUpdated = await twilioClient | |
.chat | |
.services(process.env.TWILIO_FLEX_CHAT_ID) | |
.channels(twilioChannel.sid) | |
.webhooks | |
.create({ | |
type: 'webhook', | |
'configuration.method': 'POST', | |
'configuration.url': `${process.env.NGROK_URL}/channel-update?channel=${twilioChannel.sid}&user=${chatUserName}`, | |
'configuration.filters': ['onChannelUpdated'], | |
}); | |
return twilioChannel.sid; | |
}; | |
const sendChatMessage = async (channelSid, userId, body) => { | |
const params = new URLSearchParams(); | |
params.append('Body', body); | |
params.append('From', userId); | |
const response = await fetch(`https://chat.twilio.com/v2/Services/${process.env.TWILIO_FLEX_CHAT_ID}/Channels/${channelSid}/Messages`, | |
{ | |
method: 'post', | |
body: params, | |
headers: { | |
'X-Twilio-Webhook-Enabled': 'true', | |
Authorization: `Basic ${base64.encode(`${process.env.TWILIO_ACCOUNT_SID}:${process.env.TWILIO_AUTH_TOKEN}`)}`, | |
}, | |
}); | |
if (!response.ok) { | |
const message = `An error has occured: ${response.status}`; | |
throw new Error(message); | |
} | |
const msgStatus = await response.text(); | |
return msgStatus; | |
}; | |
const express = require('express'); | |
const app = express(); | |
app.use(express.urlencoded({ extended: false })); | |
app.get('/', (req, res) => { | |
res.send('Hello World!'); | |
}); | |
app.post('/new-message', async (req, res) => { | |
if (req.body.Source == 'API') return; | |
const recipientId = req.query.user; | |
const recipient = await client.users.fetch(recipientId); | |
recipient.send(`**${req.body.Body}**`); | |
}); | |
app.post('/channel-update', async (req, res) => { | |
const attributes = JSON.parse(req.body.Attributes); | |
if (attributes.status == 'INACTIVE') { | |
if (lookupTable[req.query.user].liveAgent) { | |
const recipientId = req.query.user; | |
const recipient = await client.users.fetch(recipientId); | |
recipient.send('***Owl Gaming Agent has left the chat.***'); | |
lookupTable[recipientId].liveAgent = false; | |
lookupTable[recipientId].channelSid = undefined; | |
} | |
else { | |
await twilioClient.chat.services(process.env.TWILIO_FLEX_CHAT_ID) | |
.channels(req.query.channel).remove(); | |
} | |
} | |
}); | |
app.listen(process.env.APP_PORT, () => { | |
console.log(`Proxy app listening at http://localhost:${process.env.APP_PORT}`); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment