updating proactive agent to support both copilot and messenger front-ends
This commit is contained in:
parent
403c73fc83
commit
39d03d4b3a
@ -0,0 +1,26 @@
|
||||
[
|
||||
{
|
||||
"v_username": "Peter.Morton@verint.com",
|
||||
"copilot_settings": {
|
||||
"ops": {
|
||||
"token": "eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJ3b3Jrc3BhY2VJZCI6IjY4OWE2MjlkZmI3NjYyMzI3YWMyNWFhMSIsInNlcnZpY2UiOiJPcHMiLCJpc0FwaVRva2VuIjp0cnVlLCJpYXQiOjE3NTQ5NDgyNTN9.tGEWgFbvioKs7y9pi9pCkl_OGRy2YmyMvOaCpWFlo_9HvWUAaFeGL5phfGw8gDlPzcBlFbr1RxmEbCZaiRs1rHlGZJnpXHU9klKj_1tj6Cg7PfA-BA7YhPnZAOTpbKxeV8NYAc3SoWYZuy4l3NoXOaD3_f5FtpgmcEmUu7pvKWl4t4Q9DhXtHYnzAEoR9N3pA9jVVpcyZV9RG491mP_XOpjtP1sh3TgyGeakyBAwzOfJZn17Yzs2faqwfbP7Hy3shzCCEWkLy-3MMukDPOkL6D7Yx_NCM-P8Rdi3rCWJLpAk9Xsql8uPdOOlW78evUTXbDtZl4tndJdwK9VFmVjG2w"
|
||||
},
|
||||
"nlu": {
|
||||
"apiBaseURL": "https://router.ivastudio.verint.live/"
|
||||
},
|
||||
"channel": "copilot",
|
||||
"messengerRouteName": "messenger_667ef98d3ee8930a5debcbdb"
|
||||
},
|
||||
"req": {
|
||||
"params": {
|
||||
"workspaceId": "67bca862210071627d32ef12",
|
||||
"branch": "current"
|
||||
}
|
||||
},
|
||||
"event": {
|
||||
"params": {
|
||||
"modelName": "main"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
@ -0,0 +1,21 @@
|
||||
{
|
||||
"messenger": {
|
||||
"user": {
|
||||
"name": "Proactive Agent",
|
||||
"avatar": "https://storage.googleapis.com/speakeasyai-agent-desktop/img/verint-logo.png",
|
||||
"userId": "d4de56b5-3fac-4a42-892f-ebec914b6aa3",
|
||||
"type": "bot"
|
||||
}
|
||||
},
|
||||
"modelName": "proactiveAgent",
|
||||
"copilot": {
|
||||
"customerId": "78ab8a80-88a3-4db0-a3f9-36e7aeef18db",
|
||||
"tokenUrl": "https://api.verint.com/vcp/identity-dev/integration/auth/v2/oauth/token",
|
||||
"oauth2": {
|
||||
"grant_type": "client_credentials",
|
||||
"clientId": "XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
|
||||
"clientSecret": "XXXXXXXXXXXX",
|
||||
"audience": "api://vcp/wa-cloudevent"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,10 +1,52 @@
|
||||
/*
|
||||
Proxy Script for CoPilot integration with IVAS
|
||||
*/
|
||||
console.log({ script: "copilot", body: req.body});
|
||||
console.log({ script: "copilot", body: req.body });
|
||||
|
||||
let copilot_settings = copilot_settings;
|
||||
|
||||
if (req.headers.authorization) {
|
||||
try {
|
||||
console.log("decoding authorization ...");
|
||||
let bearer = req.headers.authorization.replace("Bearer ", "");
|
||||
|
||||
req.body.event.metadata = {
|
||||
...req.body.event.metadata,
|
||||
...{
|
||||
bearer: jwt.decode(bearer),
|
||||
},
|
||||
};
|
||||
|
||||
console.log("applying copilot overrides ...");
|
||||
const found = copilot_overrides.find(
|
||||
(element) =>
|
||||
element.v_username === req.body.event.metadata.bearer.v_username
|
||||
);
|
||||
if (found) {
|
||||
console.log("found copilot overrides for user: " + found.v_username);
|
||||
copilot_settings = {
|
||||
...copilot_settings,
|
||||
...found.copilot_settings,
|
||||
};
|
||||
req.params = { ...req.params, ...found.req.params };
|
||||
req.body.event.params = {
|
||||
...req.body.event.params,
|
||||
...found.event.params,
|
||||
};
|
||||
} else {
|
||||
console.log(
|
||||
"no copilot overrides found for user: " +
|
||||
req.body.event.metadata.bearer.v_username
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
console.log("Error decoding authorization:");
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
req.body.event.metadata = _.merge(req.body.event.metadata, {
|
||||
channel: copilot_settings.channel
|
||||
channel: copilot_settings.channel,
|
||||
});
|
||||
|
||||
const messengerUrl = `${copilot_settings.nlu.apiBaseURL}ProxyScript/run/${req.params.workspaceId}/${req.params.branch}/${copilot_settings.messengerRouteName}`;
|
||||
@ -14,44 +56,16 @@ const messengerUrl = `${copilot_settings.nlu.apiBaseURL}ProxyScript/run/${req.pa
|
||||
url: messengerUrl,
|
||||
method: "post",
|
||||
data: req.body,
|
||||
// headers: {
|
||||
// Authorization: `Bearer ${copilot_settings.ops.token}`
|
||||
// }
|
||||
// headers: {
|
||||
// Authorization: `Bearer ${copilot_settings.ops.token}`
|
||||
// }
|
||||
});
|
||||
res.send(recognizedData);
|
||||
} catch (error) {
|
||||
console.log(error.message);
|
||||
res.send({
|
||||
answers: ['Something went wrong. Please try again.'],
|
||||
outputs: {}
|
||||
answers: ["Something went wrong. Please try again."],
|
||||
outputs: {},
|
||||
});
|
||||
}
|
||||
})();/*
|
||||
Proxy Script for CoPilot integration with IVAS
|
||||
*/
|
||||
console.log({ script: "copilot", body: req.body});
|
||||
|
||||
req.body.event.metadata = _.merge(req.body.event.metadata, {
|
||||
channel: copilot_settings.channel
|
||||
});
|
||||
|
||||
const messengerUrl = `${copilot_settings.nlu.apiBaseURL}ProxyScript/run/${req.params.workspaceId}/${req.params.branch}/${copilot_settings.messengerRouteName}`;
|
||||
(async () => {
|
||||
try {
|
||||
const { data: recognizedData } = await axios({
|
||||
url: messengerUrl,
|
||||
method: "post",
|
||||
data: req.body,
|
||||
// headers: {
|
||||
// Authorization: `Bearer ${copilot_settings.ops.token}`
|
||||
// }
|
||||
});
|
||||
res.send(recognizedData);
|
||||
} catch (error) {
|
||||
console.log(error.message);
|
||||
res.send({
|
||||
answers: ['Something went wrong. Please try again.'],
|
||||
outputs: {}
|
||||
});
|
||||
}
|
||||
})();
|
||||
})();
|
||||
|
||||
@ -0,0 +1,175 @@
|
||||
console.log('>>> messenger >>>') ;
|
||||
console.log( { query: req.query, params: req.params, body: req.body }) ;
|
||||
console.log('>>> messenger >>>') ;
|
||||
const external = req.body.event?.external;
|
||||
const sessionId = req.body.event?.conversationId;
|
||||
const input = req.body.event?.input;
|
||||
const params = req.body.event?.params || {};
|
||||
const modelName = params?.modelName || settings_667ef98d3ee8930a5debcbdb.nlu.modelName;
|
||||
const env = params?.env;
|
||||
const postBack = req.body.event?.postBack;
|
||||
const metadata = {
|
||||
...req.body.event?.metadata,
|
||||
userId: req.body.event?.sentBy?.userId
|
||||
};
|
||||
const configuration = req.body.event?.configuration;
|
||||
(async () => {
|
||||
try {
|
||||
const smStr = `session-map-${sessionId}`;
|
||||
if (external) {} else {
|
||||
await axios.post(`${settings_667ef98d3ee8930a5debcbdb.messenger.apiBaseURL}Conversation/join`, {
|
||||
_id: sessionId,
|
||||
participant: {
|
||||
userId: settings_667ef98d3ee8930a5debcbdb.messenger.participantId,
|
||||
type: 'bot',
|
||||
name: settings_667ef98d3ee8930a5debcbdb.messenger.name,
|
||||
avatar: settings_667ef98d3ee8930a5debcbdb.messenger.avatar
|
||||
}
|
||||
}, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${settings_667ef98d3ee8930a5debcbdb.messenger.token}`
|
||||
}
|
||||
}).then(response => {
|
||||
if (response?.data?._id) {} else throw new Error();
|
||||
});
|
||||
axios.post(`${settings_667ef98d3ee8930a5debcbdb.messenger.apiBaseURL}Event/isTyping`, {
|
||||
workspaceId: req.params.workspaceId,
|
||||
conversationId: sessionId,
|
||||
userId: settings_667ef98d3ee8930a5debcbdb.messenger.participantId,
|
||||
typing: true
|
||||
}, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${settings_667ef98d3ee8930a5debcbdb.messenger.token}`
|
||||
}
|
||||
});
|
||||
}
|
||||
const sessionMap = await redis.hGetAll(smStr);
|
||||
console.log(smStr);
|
||||
console.log(sessionMap);
|
||||
const recognizedData = await axios.post(`${settings_667ef98d3ee8930a5debcbdb.nlu.apiBaseURL}Model/run/${req.params.workspaceId}/${req.params.branch}/${modelName}`, {
|
||||
input: input,
|
||||
conversationId: sessionMap.conversationId,
|
||||
settings: settings_667ef98d3ee8930a5debcbdb.nlu.settings,
|
||||
metadata: metadata,
|
||||
postBack: postBack,
|
||||
configuration: configuration
|
||||
}).then(response => {
|
||||
return response.data;
|
||||
}).catch(error => {
|
||||
//If we have error handling turned off, don't record the error
|
||||
if (settings_667ef98d3ee8930a5debcbdb.errorHandling === false) {
|
||||
throw error;
|
||||
} else {
|
||||
// Conversation ID is generated by the NLU
|
||||
// Must make sure Conversation ID is created properly for an error transaction
|
||||
// Get it from session map if it exists, or generate it if we got the error at the very first transaction.
|
||||
const conversationId = sessionMap.conversationId || uuidv4();
|
||||
let errorPayload = {
|
||||
id: uuidv4(),
|
||||
workspaceId: req.params.workspaceId,
|
||||
errorInfo: {
|
||||
name: error.name,
|
||||
message: error.message,
|
||||
stack: error.stack
|
||||
},
|
||||
conversationId,
|
||||
input,
|
||||
answers: [settings_667ef98d3ee8930a5debcbdb.responses.modelError],
|
||||
req: {
|
||||
params: req.params,
|
||||
query: req.query,
|
||||
body: req.body,
|
||||
headers: req.headers
|
||||
},
|
||||
metadata,
|
||||
classificationResults: [{
|
||||
label: "Model Error",
|
||||
value: 0.0
|
||||
}],
|
||||
nerResults: {
|
||||
entities: [],
|
||||
sourceEntities: []
|
||||
},
|
||||
// Reporting tags to match GlobalSupport function reporting
|
||||
tag: "ERROR",
|
||||
reporting: {
|
||||
tag: "ERROR",
|
||||
modelResponse: "ERROR"
|
||||
}
|
||||
};
|
||||
|
||||
// Add model name
|
||||
errorPayload.req.params.route = modelName;
|
||||
|
||||
//add any other details you wish to see in transaction data
|
||||
|
||||
return errorPayload;
|
||||
}
|
||||
});
|
||||
// console.log(recognizedData);
|
||||
if (recognizedData.conversationId) {
|
||||
await redis.hSet(smStr, 'conversationId', recognizedData.conversationId);
|
||||
await redis.expire(smStr, 3600);
|
||||
if (sessionMap.conversationId) {} else {
|
||||
db.analytics.addConversation({
|
||||
id: recognizedData.conversationId
|
||||
});
|
||||
}
|
||||
}
|
||||
// NOTE: Additonal logic could be used to provide answer from alternative sources
|
||||
// recognizedData.answers = API_RESPONSE || ['Example'];
|
||||
if (recognizedData.tag === "ERROR") {} else if (recognizedData.classificationResults.length === 0 && recognizedData.answers.length === 0) {
|
||||
recognizedData.answers = [settings_667ef98d3ee8930a5debcbdb.responses.unrecognized];
|
||||
} else if (recognizedData.answers.length === 0) {
|
||||
recognizedData.answers = [settings_667ef98d3ee8930a5debcbdb.responses.unanswered];
|
||||
}
|
||||
recognizedData._id = (await db.analytics.addTransaction(recognizedData)).insertedId;
|
||||
if (external) {} else {
|
||||
new Promise(async resolve => {
|
||||
for (const [index, answer] of recognizedData.answers.entries()) {
|
||||
try {
|
||||
await axios.post(`${settings_667ef98d3ee8930a5debcbdb.messenger.apiBaseURL}Event/create`, {
|
||||
conversationId: sessionId,
|
||||
input: answer,
|
||||
sentBy: {
|
||||
userId: settings_667ef98d3ee8930a5debcbdb.messenger.participantId,
|
||||
name: settings_667ef98d3ee8930a5debcbdb.messenger.name,
|
||||
avatar: settings_667ef98d3ee8930a5debcbdb.messenger.avatar
|
||||
},
|
||||
ping: nanoid(),
|
||||
sentAt: Date.now(),
|
||||
options: recognizedData?.options,
|
||||
metadata: {
|
||||
outputs: recognizedData.answers.length == index + 1 ? recognizedData?.outputs : {},
|
||||
transactionId: recognizedData._id,
|
||||
feedbackable: false
|
||||
}
|
||||
}, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${settings_667ef98d3ee8930a5debcbdb.messenger.token}`
|
||||
}
|
||||
});
|
||||
} catch (e) {}
|
||||
}
|
||||
resolve(true);
|
||||
});
|
||||
axios.post(`${settings_667ef98d3ee8930a5debcbdb.messenger.apiBaseURL}Event/isTyping`, {
|
||||
workspaceId: req.params.workspaceId,
|
||||
conversationId: sessionId,
|
||||
userId: settings_667ef98d3ee8930a5debcbdb.messenger.participantId,
|
||||
typing: false
|
||||
}, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${settings_667ef98d3ee8930a5debcbdb.messenger.token}`
|
||||
}
|
||||
});
|
||||
}
|
||||
res.send(recognizedData);
|
||||
} catch (error) {
|
||||
console.log(error.message);
|
||||
res.send({
|
||||
answers: ['Something went wrong. Please try again.'],
|
||||
outputs: {}
|
||||
});
|
||||
}
|
||||
})();
|
||||
382
copilot/_studio_dependencies/ProxyScript/proactive_agent.js
Normal file
382
copilot/_studio_dependencies/ProxyScript/proactive_agent.js
Normal file
@ -0,0 +1,382 @@
|
||||
console.log({ query: req.query, params: req.params, body: req.body });
|
||||
|
||||
const msgrSettings = settings_667ef98d3ee8930a5debcbdb;
|
||||
const paSettings = proactive_agent_settings;
|
||||
const studioToken = msgrSettings
|
||||
? {
|
||||
Authorization: `Bearer ${msgrSettings.messenger.token}`,
|
||||
}
|
||||
: {};
|
||||
const channel = req.body?.metadata?.channel;
|
||||
|
||||
let bot_user = {
|
||||
...paSettings.messenger.user,
|
||||
};
|
||||
|
||||
const app = {
|
||||
routes: [],
|
||||
route: function (regexp, fn) {
|
||||
this.routes.push({ regexp: new RegExp(regexp), function: fn });
|
||||
},
|
||||
run: function (req, res) {
|
||||
const path =
|
||||
req.params[0].split(
|
||||
`/ProxyScript/run/${req.params.workspaceId}/${req.params.branch}/${req.params.route}`
|
||||
)[1] || "/";
|
||||
|
||||
for (var route of this.routes) {
|
||||
console.log(`Checking route: ${route.regexp}`);
|
||||
console.log(`Against path: ${path}`);
|
||||
if (route.regexp.test(path)) {
|
||||
console.log(`Matched route: ${route.regexp}`);
|
||||
route.function(req, res, route.regexp.exec(path));
|
||||
return;
|
||||
}
|
||||
}
|
||||
// If no route matches, return a 404 status
|
||||
const status = { path: req.params[0], status: 404 };
|
||||
res.status(404).send(status);
|
||||
},
|
||||
};
|
||||
|
||||
const redisKey = (userId) => {
|
||||
return `user-map-${userId}`;
|
||||
};
|
||||
|
||||
const axioshelper = (message, config, callback, retries = 3, delay = 100) => {
|
||||
console.log(config);
|
||||
return new Promise(async (resolve, reject) => {
|
||||
for (let i = 0; i < retries; i++) {
|
||||
try {
|
||||
const response = await axios(config);
|
||||
|
||||
if (response.status < 200 || response.status > 299) {
|
||||
if (callback) {
|
||||
await callback();
|
||||
} else {
|
||||
throw new Error(
|
||||
`Axios Request failed! ${JSON.stringify(response)}`
|
||||
);
|
||||
}
|
||||
}
|
||||
resolve(response);
|
||||
break;
|
||||
} catch (error) {
|
||||
if (error.response) {
|
||||
// The request was made and the server responded with a status code
|
||||
// that falls out of the range of 2xx
|
||||
console.log(error.response.data);
|
||||
console.log(error.response.status);
|
||||
console.log(error.response.headers);
|
||||
} else if (error.request) {
|
||||
// The request was made but no response was received
|
||||
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
|
||||
// http.ClientRequest in node.js
|
||||
console.log(error.request);
|
||||
} else {
|
||||
// Something happened in setting up the request that triggered an Error
|
||||
console.log("Error", error.message);
|
||||
}
|
||||
console.log(error.config);
|
||||
if (i === retries - 1) {
|
||||
if (callback) {
|
||||
await callback();
|
||||
}
|
||||
console.log({
|
||||
retry: i + 1,
|
||||
error: "out of retries",
|
||||
message,
|
||||
url: config.url,
|
||||
});
|
||||
reject(error);
|
||||
} else {
|
||||
console.log({
|
||||
level: "warn",
|
||||
message: `Attempt ${i + 1} failed.`,
|
||||
url: config.url,
|
||||
});
|
||||
await new Promise((resolve) => setTimeout(resolve, delay));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
async function createSessionMap(umStr, sessionMap) {
|
||||
console.log({ method: "createSessionMap", sessionMap });
|
||||
let keys = Object.keys(sessionMap);
|
||||
keys.forEach(async (key) => {
|
||||
await redis.hSet(umStr, key, sessionMap[key]);
|
||||
});
|
||||
await redis.expire(umStr, 3600);
|
||||
}
|
||||
|
||||
async function m2mAuthentication() {
|
||||
let data = new URLSearchParams({
|
||||
grant_type: paSettings.copilot.oauth2.grant_type,
|
||||
client_id: paSettings.copilot.oauth2.clientId,
|
||||
client_secret: paSettings.copilot.oauth2.clientSecret,
|
||||
audience: paSettings.copilot.oauth2.audience,
|
||||
});
|
||||
|
||||
let token = await axioshelper("m2m authentication", {
|
||||
method: "post",
|
||||
url: paSettings.copilot.tokenUrl,
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
},
|
||||
data,
|
||||
})
|
||||
.then((response) => {
|
||||
return response.data.access_token;
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error during M2M authentication:", error);
|
||||
throw error;
|
||||
});
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
app.route("^(?:/userId/([^/]+))(?:/$)?$", async (req, res, match) => {
|
||||
try {
|
||||
console.log(`Received request for userId: ${match[1]}`);
|
||||
const modelName =
|
||||
req.params?.modelName || proactive_agent_settings.modelName;
|
||||
if (match.length > 1) {
|
||||
const userId = match[1];
|
||||
const smStr = redisKey(userId);
|
||||
let sessionMap = await redis.hGetAll(smStr);
|
||||
|
||||
if (!sessionMap || !sessionMap.conversationId) {
|
||||
if (channel === "web") {
|
||||
console.log(`No session found for userId: ${userId} for web channel`);
|
||||
return res.status(404).send({ error: "Session not found" });
|
||||
} else if (channel === "copilot") {
|
||||
// no session data is okay for copilot, create one now
|
||||
sessionMap = {
|
||||
customerId: paSettings.copilot.customerId,
|
||||
upn: userId,
|
||||
userUUID: req.body?.metadata?.userUUID,
|
||||
};
|
||||
await createSessionMap(smStr, sessionMap);
|
||||
}
|
||||
} else {
|
||||
console.log({ sessionMap });
|
||||
}
|
||||
|
||||
const metadata = {
|
||||
userId: bot_user.userId,
|
||||
channel
|
||||
};
|
||||
|
||||
const recognizedData = await axioshelper("run model", {
|
||||
method: "post",
|
||||
url: `${settings_667ef98d3ee8930a5debcbdb.nlu.apiBaseURL}Model/run/${req.params.workspaceId}/${req.params.branch}/${modelName}`,
|
||||
headers: studioToken,
|
||||
data: {
|
||||
input: req.body.input,
|
||||
conversationId: sessionMap.conversationId,
|
||||
settings: settings_667ef98d3ee8930a5debcbdb.nlu.settings,
|
||||
metadata: metadata,
|
||||
},
|
||||
})
|
||||
.then((response) => {
|
||||
return response.data;
|
||||
})
|
||||
.catch((error) => {
|
||||
//If we have error handling turned off, don't record the error
|
||||
if (settings_667ef98d3ee8930a5debcbdb.errorHandling === false) {
|
||||
throw error;
|
||||
} else {
|
||||
// Conversation ID is generated by the NLU
|
||||
// Must make sure Conversation ID is created properly for an error transaction
|
||||
// Get it from session map if it exists, or generate it if we got the error at the very first transaction.
|
||||
const conversationId = sessionMap.conversationId || uuidv4();
|
||||
let errorPayload = {
|
||||
id: uuidv4(),
|
||||
workspaceId: req.params.workspaceId,
|
||||
errorInfo: {
|
||||
name: error.name,
|
||||
message: error.message,
|
||||
stack: error.stack,
|
||||
},
|
||||
conversationId,
|
||||
input: req.body.input,
|
||||
answers: [settings_667ef98d3ee8930a5debcbdb.responses.modelError],
|
||||
req: {
|
||||
params: req.params,
|
||||
query: req.query,
|
||||
body: req.body,
|
||||
headers: req.headers,
|
||||
},
|
||||
metadata,
|
||||
classificationResults: [
|
||||
{
|
||||
label: "Model Error",
|
||||
value: 0.0,
|
||||
},
|
||||
],
|
||||
nerResults: {
|
||||
entities: [],
|
||||
sourceEntities: [],
|
||||
},
|
||||
// Reporting tags to match GlobalSupport function reporting
|
||||
tag: "ERROR",
|
||||
reporting: {
|
||||
tag: "ERROR",
|
||||
modelResponse: "ERROR",
|
||||
},
|
||||
};
|
||||
|
||||
// Add model name
|
||||
errorPayload.req.params.route = modelName;
|
||||
|
||||
//add any other details you wish to see in transaction data
|
||||
|
||||
return errorPayload;
|
||||
}
|
||||
});
|
||||
|
||||
if (recognizedData.conversationId) {
|
||||
await redis.hSet(
|
||||
smStr,
|
||||
"conversationId",
|
||||
recognizedData.conversationId
|
||||
);
|
||||
await redis.expire(smStr, 3600);
|
||||
if (sessionMap.conversationId) {
|
||||
} else {
|
||||
db.analytics.addConversation({
|
||||
id: recognizedData.conversationId,
|
||||
});
|
||||
}
|
||||
}
|
||||
recognizedData._id = (
|
||||
await db.analytics.addTransaction(recognizedData)
|
||||
).insertedId;
|
||||
|
||||
// Send Answers to Messenger
|
||||
new Promise(async (resolve) => {
|
||||
for (const [index, answer] of recognizedData.answers.entries()) {
|
||||
if (channel === "web") {
|
||||
await axioshelper("messenger create", {
|
||||
method: "post",
|
||||
url: `${settings_667ef98d3ee8930a5debcbdb.messenger.apiBaseURL}Event/create`,
|
||||
headers: {
|
||||
Authorization: `Bearer ${settings_667ef98d3ee8930a5debcbdb.messenger.token}`,
|
||||
},
|
||||
data: {
|
||||
conversationId: sessionMap.sessionId,
|
||||
metadata: {
|
||||
channel: "web",
|
||||
},
|
||||
input: answer,
|
||||
sentBy: bot_user,
|
||||
ping: nanoid(),
|
||||
sentAt: Date.now(),
|
||||
options: recognizedData?.options,
|
||||
metadata: {
|
||||
outputs:
|
||||
recognizedData.answers.length == index + 1
|
||||
? recognizedData?.outputs
|
||||
: {},
|
||||
transactionId: recognizedData._id,
|
||||
feedbackable: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
} else if (channel === "copilot") {
|
||||
let bearerAuth = await m2mAuthentication();
|
||||
if (!bearerAuth) {
|
||||
throw Error("Unable to Authenticate M2M");
|
||||
}
|
||||
|
||||
let body = answer;
|
||||
|
||||
if (typeof answer === "string" || answer instanceof String) {
|
||||
// TODO: convert to simple text reply object
|
||||
body = {
|
||||
source: "//wa/us-east-1/int/demo/plain",
|
||||
type: "verint.ui_messages.text.v1",
|
||||
id: "ca5057b8-2c1d-4758-89d6-0370d6f28cc2",
|
||||
time: "2020-07-30T14:44:00+00:00",
|
||||
data: {
|
||||
version: "1.0.0",
|
||||
format: "plain",
|
||||
persona_icon: {
|
||||
id: "Verint-Bot-Head",
|
||||
color: "#007ACC",
|
||||
},
|
||||
title_icon: {
|
||||
id: "message-status-info",
|
||||
color: "#FF5722",
|
||||
},
|
||||
body: answer,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
await axioshelper("copilot cloud-event", {
|
||||
method: "post",
|
||||
url: `https://apigw.us-east-1.wrk-1.aws.hydra.verint.com/int/wa/v1/cloud-event`,
|
||||
headers: {
|
||||
Authorization: `Bearer ${bearerAuth}`,
|
||||
},
|
||||
data: {
|
||||
...body,
|
||||
...sessionMap,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
resolve(true);
|
||||
});
|
||||
res.send(recognizedData);
|
||||
} else {
|
||||
res.status(400).send({ error: "Bad Request" });
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return res.status(500).send({
|
||||
status: 500,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
app.route("/", async (req, res) => {
|
||||
const sessionId = req.body.event?.conversationId;
|
||||
const metadata = {
|
||||
...req.body.event?.metadata,
|
||||
userId: req.body.event?.sentBy?.userId,
|
||||
};
|
||||
|
||||
try {
|
||||
if (sessionId && metadata.userId) {
|
||||
await createSessionMap(redisKey(metadata.userId), { sessionId });
|
||||
|
||||
await axioshelper("messenger join", {
|
||||
method: "post",
|
||||
url: `${msgrSettings.messenger.apiBaseURL}Conversation/join`,
|
||||
headers: studioToken,
|
||||
data: {
|
||||
_id: sessionId,
|
||||
participant: bot_user,
|
||||
},
|
||||
});
|
||||
|
||||
res.send();
|
||||
} else {
|
||||
res.send({ error: "sessionId or userId not found on event." });
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
res.send({
|
||||
answers: ["Something went wrong. Please try again."],
|
||||
outputs: {},
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
app.run(req, res);
|
||||
@ -9,7 +9,7 @@
|
||||
"side_panel": {
|
||||
"default_path": "src/pages/side-panel/index.html"
|
||||
},
|
||||
"permissions": ["sidePanel", "tabs"],
|
||||
"permissions": ["sidePanel", "tabs", "clipboardWrite", "clipboardRead"],
|
||||
"content_security_policy": {
|
||||
"extension_pages": "script-src 'self'; object-src 'self'"
|
||||
},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user