Improve chat flow with answers
This commit is contained in:
@@ -1,6 +0,0 @@
|
|||||||
const intents = require('./intents')
|
|
||||||
|
|
||||||
module.exports = async (message, recipient) => {
|
|
||||||
const run = intents.get(message)
|
|
||||||
run(message, recipient)
|
|
||||||
}
|
|
||||||
@@ -7,7 +7,7 @@ FB.setAccessToken(process.env.FB_ACCESS_TOKEN)
|
|||||||
const fbParser = require('claudia-bot-builder/lib/facebook/parse')
|
const fbParser = require('claudia-bot-builder/lib/facebook/parse')
|
||||||
const fbValidate = require('claudia-bot-builder/lib/facebook/validate-integrity')
|
const fbValidate = require('claudia-bot-builder/lib/facebook/validate-integrity')
|
||||||
|
|
||||||
const conversation = require('./conversation')
|
const {run} = require('./intents')
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In-Memory cache for FB graph results
|
* In-Memory cache for FB graph results
|
||||||
@@ -63,7 +63,7 @@ const respond = async (req, res) => {
|
|||||||
recipients[message.sender] = recipient
|
recipients[message.sender] = recipient
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await conversation(message, recipient)
|
await run(message, recipient)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
res.end(err.message)
|
res.end(err.message)
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ const fbReply = require('claudia-bot-builder/lib/facebook/reply')
|
|||||||
const send = (recipientId, message) =>
|
const send = (recipientId, message) =>
|
||||||
fbReply(recipientId, message, process.env.FB_ACCESS_TOKEN)
|
fbReply(recipientId, message, process.env.FB_ACCESS_TOKEN)
|
||||||
|
|
||||||
|
const noop = () => {}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
send,
|
send,
|
||||||
|
noop,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,20 @@
|
|||||||
|
const flatten = require('flatten')
|
||||||
const fbTemplate = require('claudia-bot-builder/lib/facebook/format-message')
|
const fbTemplate = require('claudia-bot-builder/lib/facebook/format-message')
|
||||||
const {send} = require('./common')
|
const {send} = require('./common')
|
||||||
|
|
||||||
const run = (msg, recipient) => {
|
const INTENT_DEBUG_START = 'intent_debug_start'
|
||||||
const reply = new fbTemplate.Text(`
|
|
||||||
This is a \`Text\` message
|
const run = (msg, recipient, data) => {
|
||||||
`).get()
|
const text = flatten(data)
|
||||||
send(recipient.id, reply)
|
.map(d => JSON.stringify(d, null, 2))
|
||||||
|
.join(', ')
|
||||||
|
send(recipient.id, new fbTemplate.Text(`DEBUG: \`${text}\``).get())
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = [
|
||||||
keywords: ['debug'],
|
{
|
||||||
|
id: 'debug',
|
||||||
|
keywords: [INTENT_DEBUG_START, 'debug'],
|
||||||
run,
|
run,
|
||||||
}
|
},
|
||||||
|
]
|
||||||
|
|||||||
@@ -1,16 +1,32 @@
|
|||||||
|
const huh = require('huh')
|
||||||
const fbTemplate = require('claudia-bot-builder/lib/facebook/format-message')
|
const fbTemplate = require('claudia-bot-builder/lib/facebook/format-message')
|
||||||
const {send} = require('./common')
|
const {send} = require('./common')
|
||||||
|
|
||||||
|
const uncapitalize = str => str.charAt(0).toLowerCase() + str.slice(1)
|
||||||
|
|
||||||
const run = (msg, recipient) => {
|
const run = (msg, recipient) => {
|
||||||
const reply = new fbTemplate.Text(
|
send(recipient.id, [
|
||||||
|
new fbTemplate.ChatAction('mark_seen').get(),
|
||||||
|
new fbTemplate.ChatAction('typing_on').get(),
|
||||||
|
new fbTemplate.Text(
|
||||||
`Sorry, ${
|
`Sorry, ${
|
||||||
recipient.first_name
|
recipient.first_name
|
||||||
}. I am a young Bot and still learning. Type "Start" to show the start over.`
|
}. I didn't understand that, probably because of ${uncapitalize(
|
||||||
).get()
|
huh.get()
|
||||||
send(recipient.id, reply)
|
)}`
|
||||||
|
).get(),
|
||||||
|
new fbTemplate.ChatAction('typing_on').get(),
|
||||||
|
new fbTemplate.Pause(1000).get(),
|
||||||
|
new fbTemplate.Text(
|
||||||
|
`I'll improve in time, don't worry. Meanwhile, you can type 'start' to start the show over.`
|
||||||
|
).get(),
|
||||||
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = [
|
||||||
|
{
|
||||||
|
id: 'default',
|
||||||
keywords: [],
|
keywords: [],
|
||||||
run,
|
run,
|
||||||
}
|
},
|
||||||
|
]
|
||||||
|
|||||||
@@ -1,17 +1,90 @@
|
|||||||
const fbTemplate = require('claudia-bot-builder/lib/facebook/format-message')
|
const fbTemplate = require('claudia-bot-builder/lib/facebook/format-message')
|
||||||
const {send} = require('./common')
|
const {send} = require('./common')
|
||||||
|
|
||||||
|
const INTENT_DRINK_START = 'intent_drink_start'
|
||||||
|
const INTENT_DRINK_YES = 'intent_drink_yes'
|
||||||
|
const INTENT_DRINK_NO = 'intent_drink_no'
|
||||||
|
const INTENT_DRINK_FAVORITE = 'intent_drink_favorite'
|
||||||
|
|
||||||
const run = (msg, recipient) => {
|
const run = (msg, recipient) => {
|
||||||
const reply = new fbTemplate.Text(`
|
send(recipient.id, [
|
||||||
|
new fbTemplate.ChatAction('mark_seen').get(),
|
||||||
|
new fbTemplate.ChatAction('typing_on').get(),
|
||||||
|
new fbTemplate.Pause(500).get(),
|
||||||
|
new fbTemplate.Text(`
|
||||||
So, you'd like to drink?
|
So, you'd like to drink?
|
||||||
`)
|
`)
|
||||||
.addQuickReply('YES!', 'YES')
|
.addQuickReply('YES!', INTENT_DRINK_YES)
|
||||||
.addQuickReply('No, not particulary', 'NO')
|
.addQuickReply('No, not particulary', INTENT_DRINK_NO)
|
||||||
.get()
|
.get(),
|
||||||
send(recipient.id, reply)
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
const runYes = (msg, recipient) => {
|
||||||
keywords: ['drink', 'dring', 'water', 'gimmme'],
|
send(recipient.id, [
|
||||||
run,
|
new fbTemplate.ChatAction('mark_seen').get(),
|
||||||
|
new fbTemplate.ChatAction('typing_on').get(),
|
||||||
|
new fbTemplate.Pause(500).get(),
|
||||||
|
new fbTemplate.Text(`
|
||||||
|
YEAH, me too.
|
||||||
|
`).get(),
|
||||||
|
new fbTemplate.ChatAction('mark_seen').get(),
|
||||||
|
new fbTemplate.ChatAction('typing_on').get(),
|
||||||
|
new fbTemplate.Pause(1000).get(),
|
||||||
|
new fbTemplate.Text(`
|
||||||
|
What's your favorite drink?
|
||||||
|
`)
|
||||||
|
.addQuickReply('Absinthe', INTENT_DRINK_FAVORITE)
|
||||||
|
.addQuickReply('Beer', INTENT_DRINK_FAVORITE)
|
||||||
|
.addQuickReply('Brandy', INTENT_DRINK_FAVORITE)
|
||||||
|
.addQuickReply('Cachaça', INTENT_DRINK_FAVORITE)
|
||||||
|
.addQuickReply('Gin', INTENT_DRINK_FAVORITE)
|
||||||
|
.addQuickReply('Ouzo', INTENT_DRINK_FAVORITE)
|
||||||
|
.addQuickReply('Rum', INTENT_DRINK_FAVORITE)
|
||||||
|
.addQuickReply('Sake', INTENT_DRINK_FAVORITE)
|
||||||
|
.get(),
|
||||||
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const runFavorite = (msg, recipient) => {
|
||||||
|
send(recipient.id, [
|
||||||
|
new fbTemplate.ChatAction('mark_seen').get(),
|
||||||
|
new fbTemplate.ChatAction('typing_on').get(),
|
||||||
|
new fbTemplate.Pause(500).get(),
|
||||||
|
new fbTemplate.Text(
|
||||||
|
`Hmmm... I don't like ${
|
||||||
|
msg.originalRequest.message.text
|
||||||
|
}, but I like water!`
|
||||||
|
).get(),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
const runNo = (msg, recipient) => {
|
||||||
|
send(recipient.id, [
|
||||||
|
new fbTemplate.ChatAction('mark_seen').get(),
|
||||||
|
new fbTemplate.ChatAction('typing_on').get(),
|
||||||
|
new fbTemplate.Pause(500).get(),
|
||||||
|
new fbTemplate.Text(`
|
||||||
|
That's a shame, but do drink water!
|
||||||
|
`).get(),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = [
|
||||||
|
{
|
||||||
|
keywords: [INTENT_DRINK_START, 'drink', 'dring', 'water', 'gimmme'],
|
||||||
|
run,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
keywords: [INTENT_DRINK_YES],
|
||||||
|
run: runYes,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
keywords: [INTENT_DRINK_NO],
|
||||||
|
run: runNo,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
keywords: [INTENT_DRINK_FAVORITE],
|
||||||
|
run: runFavorite,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|||||||
@@ -1,20 +1,40 @@
|
|||||||
|
const flatten = require('flatten')
|
||||||
|
|
||||||
|
const load = intents => flatten(intents.map(name => require(`./${name}`)))
|
||||||
|
|
||||||
|
const intents = load(['default', 'start', 'drink', 'debug'])
|
||||||
|
|
||||||
const normalize = str => str.toLowerCase()
|
const normalize = str => str.toLowerCase()
|
||||||
|
|
||||||
const intents = {
|
const matchIntent = str =>
|
||||||
default: require('./default'),
|
intents
|
||||||
start: require('./start'),
|
.map(i => (i.keywords.indexOf(normalize(str)) > -1 ? i.run : false))
|
||||||
drink: require('./drink'),
|
.find(f => f !== false)
|
||||||
debug: require('./debug'),
|
|
||||||
}
|
|
||||||
|
|
||||||
const get = msg => {
|
const get = msg => {
|
||||||
const text = normalize(msg.text)
|
const defaultIntent = intents.find(i => i.id === 'default').run
|
||||||
const intent = Object.keys(intents).find(
|
let intent = matchIntent(msg.text)
|
||||||
k => intents[k].keywords.indexOf(text) !== -1
|
|
||||||
)
|
if (!intent) {
|
||||||
return intent ? intents[intent].run : intents.default.run
|
if (msg.quick_reply) {
|
||||||
|
intent = matchIntent(msg.quick_reply.payload)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return intent || defaultIntent
|
||||||
|
}
|
||||||
|
|
||||||
|
const run = (msg, recipient) => {
|
||||||
|
const debugIntent = intents.find(i => i.id === 'debug').run
|
||||||
|
const intent = get(msg)
|
||||||
|
|
||||||
|
if (intent === debugIntent) {
|
||||||
|
return debugIntent(msg, recipient, intents)
|
||||||
|
}
|
||||||
|
|
||||||
|
return intent(msg, recipient)
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
get,
|
run,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,64 @@
|
|||||||
const fbTemplate = require('claudia-bot-builder/lib/facebook/format-message')
|
const fbTemplate = require('claudia-bot-builder/lib/facebook/format-message')
|
||||||
const {send} = require('./common')
|
const {send, noop} = require('./common')
|
||||||
|
|
||||||
|
const INTENT_START_START = 'intent_start_start'
|
||||||
|
const INTENT_START_ABOUT = 'intent_start_about'
|
||||||
|
const INTENT_START_CHANGE_ALERTS = 'intent_change_alert'
|
||||||
|
|
||||||
const run = (msg, recipient) => {
|
const run = (msg, recipient) => {
|
||||||
const reply = new fbTemplate.Text(`
|
send(recipient.id, [
|
||||||
|
new fbTemplate.ChatAction('mark_seen').get(),
|
||||||
|
new fbTemplate.ChatAction('typing_on').get(),
|
||||||
|
new fbTemplate.Pause(500).get(),
|
||||||
|
new fbTemplate.Text(`
|
||||||
This is your menu. You can reach it by writing Menu, or Help, or Start
|
This is your menu. You can reach it by writing Menu, or Help, or Start
|
||||||
`).get()
|
`)
|
||||||
send(recipient.id, reply)
|
.addQuickReply('About vodopija-bot', INTENT_START_ABOUT)
|
||||||
|
.addQuickReply('Change alerts', INTENT_START_CHANGE_ALERTS)
|
||||||
|
.get(),
|
||||||
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
const runAbout = (msg, recipient) => {
|
||||||
keywords: ['start', 'menu', 'help'],
|
send(recipient.id, [
|
||||||
run,
|
new fbTemplate.ChatAction('mark_seen').get(),
|
||||||
|
new fbTemplate.ChatAction('typing_on').get(),
|
||||||
|
new fbTemplate.Text(`Thanks for asking 🙂`).get(),
|
||||||
|
new fbTemplate.ChatAction('typing_on').get(),
|
||||||
|
new fbTemplate.Pause(500).get(),
|
||||||
|
new fbTemplate.Text(
|
||||||
|
`vodolija-bot was created by Marko Marković as a test for SPARTANS AI LTD.`
|
||||||
|
).get(),
|
||||||
|
new fbTemplate.ChatAction('typing_on').get(),
|
||||||
|
new fbTemplate.Pause(1000).get(),
|
||||||
|
new fbTemplate.Text(
|
||||||
|
`Its goal is to help you drink more water for a healthier life.`
|
||||||
|
).get(),
|
||||||
|
new fbTemplate.ChatAction('typing_on').get(),
|
||||||
|
new fbTemplate.Pause(1000).get(),
|
||||||
|
new fbTemplate.Text(`
|
||||||
|
It features:
|
||||||
|
☑ Daily water reminders
|
||||||
|
☑ Personalized AI recommendations
|
||||||
|
☑ Number of cups of water drank this week
|
||||||
|
☑ Tips about water drinking
|
||||||
|
`)
|
||||||
|
.addQuickReply('Back', INTENT_START_START)
|
||||||
|
.get(),
|
||||||
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module.exports = [
|
||||||
|
{
|
||||||
|
keywords: [INTENT_START_START, 'start', 'menu', 'help'],
|
||||||
|
run,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
keywords: [INTENT_START_ABOUT],
|
||||||
|
run: runAbout,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
keywords: [INTENT_START_CHANGE_ALERTS],
|
||||||
|
run: noop,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|||||||
@@ -14,6 +14,8 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"claudia-bot-builder": "4.0.0",
|
"claudia-bot-builder": "4.0.0",
|
||||||
|
"flatten": "1.0.2",
|
||||||
|
"huh": "2.0.1",
|
||||||
"micro": "9.1.4",
|
"micro": "9.1.4",
|
||||||
"microrouter": "3.1.2"
|
"microrouter": "3.1.2"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1127,6 +1127,10 @@ flat-cache@^1.2.1:
|
|||||||
graceful-fs "^4.1.2"
|
graceful-fs "^4.1.2"
|
||||||
write "^0.2.1"
|
write "^0.2.1"
|
||||||
|
|
||||||
|
flatten@1.0.2:
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782"
|
||||||
|
|
||||||
for-in@^1.0.2:
|
for-in@^1.0.2:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
|
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
|
||||||
@@ -1384,6 +1388,10 @@ http-signature@~1.2.0:
|
|||||||
jsprim "^1.2.2"
|
jsprim "^1.2.2"
|
||||||
sshpk "^1.7.0"
|
sshpk "^1.7.0"
|
||||||
|
|
||||||
|
huh@2.0.1:
|
||||||
|
version "2.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/huh/-/huh-2.0.1.tgz#08d5836a47e3f301ad50899d4788721b0ac15486"
|
||||||
|
|
||||||
iconv-lite@0.4.19:
|
iconv-lite@0.4.19:
|
||||||
version "0.4.19"
|
version "0.4.19"
|
||||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b"
|
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b"
|
||||||
|
|||||||
Reference in New Issue
Block a user