Skip to content

Commit

Permalink
Migrate juice-chat-bot to import
Browse files Browse the repository at this point in the history
Fixes related typescript issues & race-conditions
  • Loading branch information
J12934 committed May 6, 2023
1 parent f7df1d4 commit c35e026
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 48 deletions.
10 changes: 3 additions & 7 deletions lib/startup/validateChatBot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
* SPDX-License-Identifier: MIT
*/

import config = require('config')
import config from 'config'
import logger from '../logger'
import colors from 'colors/safe'
import * as utils from '../utils'

const validateChatBot = (trainingData: any, exitOnFailure = true) => {
export default function validateChatBot (trainingData: any, exitOnFailure = true) {
let success = true
success = checkIntentWithFunctionHandlerExists(trainingData, 'queries.couponCode', 'couponCode') && success
success = checkIntentWithFunctionHandlerExists(trainingData, 'queries.productPrice', 'productPrice') && success
Expand All @@ -26,7 +26,7 @@ const validateChatBot = (trainingData: any, exitOnFailure = true) => {
return success
}

const checkIntentWithFunctionHandlerExists = (trainingData: any, intent: string, handler: string) => {
export const checkIntentWithFunctionHandlerExists = (trainingData: any, intent: string, handler: string) => {
let success = true
const intentData = trainingData.data.filter((data: any) => data.intent === intent)
if (intentData.length === 0) {
Expand All @@ -40,7 +40,3 @@ const checkIntentWithFunctionHandlerExists = (trainingData: any, intent: string,
}
return success
}

validateChatBot.checkIntentWithFunctionHandlerExists = checkIntentWithFunctionHandlerExists

module.exports = validateChatBot
84 changes: 47 additions & 37 deletions routes/chatbot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,16 @@ import config from 'config'
import download from 'download'
import * as utils from '../lib/utils'
import { isString } from 'lodash'
import { Bot } from 'juicy-chat-bot'
import validateChatBot from '../lib/startup/validateChatBot'

const { Bot } = require('juicy-chat-bot')
const security = require('../lib/insecurity')
const botUtils = require('../lib/botUtils')
const challenges = require('../data/datacache').challenges

let trainingFile = config.get<string>('application.chatBot.trainingData')
let testCommand: string, bot: any
let testCommand: string
let bot: Bot | null = null

async function initialize () {
if (utils.isUrl(trainingFile)) {
Expand All @@ -37,7 +39,7 @@ async function initialize () {

trainingFile = utils.extractFilename(trainingFile)
const trainingSet = await fs.readFile(`data/chatbot/${trainingFile}`, 'utf8')
require('../lib/startup/validateChatBot')(JSON.parse(trainingSet))
validateChatBot(JSON.parse(trainingSet))

testCommand = JSON.parse(trainingSet).data[0].utterances[0]
bot = new Bot(config.get('application.chatBot.name'), config.get('application.chatBot.greeting'), trainingSet, config.get('application.chatBot.defaultResponse'))
Expand All @@ -47,6 +49,10 @@ async function initialize () {
void initialize()

async function processQuery (user: User, req: Request, res: Response, next: NextFunction) {
if (!bot) {
res.status(503).send()
return
}
const username = user.username
if (!username) {
res.status(200).json({
Expand Down Expand Up @@ -88,7 +94,7 @@ async function processQuery (user: User, req: Request, res: Response, next: Next
}

try {
const response = await bot.respond(req.body.query, user.id)
const response = await bot.respond(req.body.query, `${user.id}`)
if (response.action === 'function') {
if (response.handler && botUtils[response.handler]) {
res.status(200).json(await botUtils[response.handler](req.body.query, user))
Expand All @@ -103,7 +109,7 @@ async function processQuery (user: User, req: Request, res: Response, next: Next
}
} catch (err) {
try {
await bot.respond(testCommand, user.id)
await bot.respond(testCommand, `${user.id}`)
res.status(200).json({
action: 'response',
body: config.get('application.chatBot.defaultResponse')
Expand All @@ -119,6 +125,9 @@ async function processQuery (user: User, req: Request, res: Response, next: Next
}

async function setUserName (user: User, req: Request, res: Response) {
if (!bot) {
return
}
try {
const userModel = await UserModel.findByPk(user.id)
if (!userModel) {
Expand All @@ -129,8 +138,9 @@ async function setUserName (user: User, req: Request, res: Response) {
return
}
const updatedUser = await userModel.update({ username: req.body.query })
const updatedToken = security.authorize(updatedUser)
security.authenticatedUsers.put(updatedToken, utils.queryResultToJson(updatedUser))
const updatedUserResponse = utils.queryResultToJson(updatedUser)
const updatedToken = security.authorize(updatedUserResponse)
security.authenticatedUsers.put(updatedToken, updatedUserResponse)
bot.addUser(`${updatedUser.id}`, req.body.query)
res.status(200).json({
action: 'response',
Expand All @@ -157,41 +167,41 @@ module.exports.status = function status () {
return
}
const token = req.cookies.token || utils.jwtFrom(req)
if (token) {
const user = await getUserFromJwt(token)
if (!user) {
res.status(401).json({
error: 'Unauthenticated user'
})
return
}
if (!token) {
res.status(200).json({
status: bot.training.state,
body: `Hi, I can't recognize you. Sign in to talk to ${config.get('application.chatBot.name')}`
})
return
}

const username = user.username
const user = await getUserFromJwt(token)
if (!user) {
res.status(401).json({
error: 'Unauthenticated user'
})
return
}

if (!username) {
res.status(200).json({
action: 'namequery',
body: 'I\'m sorry I didn\'t get your name. What shall I call you?'
})
return
}
const username = user.username

try {
bot.addUser(`${user.id}`, username)
res.status(200).json({
status: bot.training.state,
body: bot.training.state ? bot.greet(`${user.id}`) : `${config.get('application.chatBot.name')} isn't ready at the moment, please wait while I set things up`
})
} catch (err) {
next(new Error('Blocked illegal activity by ' + req.socket.remoteAddress))
}
if (!username) {
res.status(200).json({
action: 'namequery',
body: 'I\'m sorry I didn\'t get your name. What shall I call you?'
})
return
}

res.status(200).json({
status: bot.training.state,
body: `Hi, I can't recognize you. Sign in to talk to ${config.get('application.chatBot.name')}`
})
try {
bot.addUser(`${user.id}`, username)
res.status(200).json({
status: bot.training.state,
body: bot.training.state ? bot.greet(`${user.id}`) : `${config.get('application.chatBot.name')} isn't ready at the moment, please wait while I set things up`
})
} catch (err) {
next(new Error('Blocked illegal activity by ' + req.socket.remoteAddress))
}
}
}

Expand All @@ -204,7 +214,7 @@ module.exports.process = function respond () {
})
}
const token = req.cookies.token || utils.jwtFrom(req)
if (!bot.training.state || !token) {
if (!token) {
res.status(400).json({
error: 'Unauthenticated user'
})
Expand Down
6 changes: 2 additions & 4 deletions test/server/chatBotValidationSpec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@
*/

import chai = require('chai')
import validateChatBot, { checkIntentWithFunctionHandlerExists } from '../../lib/startup/validateChatBot'
const sinonChai = require('sinon-chai')
const expect = chai.expect
chai.use(sinonChai)

const validateChatBot = require('../../lib/startup/validateChatBot')
const { checkIntentWithFunctionHandlerExists } = require('../../lib/startup/validateChatBot')

describe('chatBotValidation', () => {
describe('checkIntentWithHandlerExists', () => {
it('should accept training data with the expected intent and handler', () => {
Expand Down Expand Up @@ -40,7 +38,7 @@ describe('chatBotValidation', () => {
]
}

expect(checkIntentWithFunctionHandlerExists(trainingData, 'queries.test')).to.equal(false)
expect(checkIntentWithFunctionHandlerExists(trainingData, 'queries.test', 'testFunction')).to.equal(false)
})

it('should fail if the training data lacks the expected handler for the given intent', () => {
Expand Down

0 comments on commit c35e026

Please sign in to comment.