Separated out query for reuse and interactions-flow route

no longer uses sample data
This commit is contained in:
Peter Morton 2023-08-05 16:51:12 -05:00
parent ca011abee5
commit 3f788733c8
3 changed files with 181 additions and 128 deletions

View File

@ -1,12 +1,13 @@
import { Router } from "express"; import { Router } from "express";
import axios from "axios";
import localStorage from "local-storage";
import sampleFlow from "../../utils/sampleFlow.js"; import sampleFlow from "../../utils/sampleFlow.js";
import sampleUDG from "../../utils/sampleUDGresponse.js";
const router = Router(); const router = Router();
import { logger } from "../../utils/index.js"; import { logger } from "../../utils/index.js";
import { referenceIdQuery } from "../../utils/graphQueries.js";
router.get("/", (req, res) => { router.get("/", (req, res) => {
const data = {
var data = {
nodes: [], nodes: [],
links: [], links: [],
}; };
@ -19,70 +20,120 @@ router.get("/", (req, res) => {
chain[filterNames[index] + "-" + filterNames[index + 1]] = true; chain[filterNames[index] + "-" + filterNames[index + 1]] = true;
} }
sampleUDG.data.findContactsCompletedBetween.edges.forEach((value) => { const startTime = new Date(
addNode(filter, "Channel", value.node.interaction.__typename, data); new Date().setFullYear(new Date().getFullYear() - 2)
);
var endTime = new Date();
// FIX for 'endTime' parameter cannot be later than one minute prior to now.
endTime.setMinutes(endTime.getMinutes() - 1);
if (value.node.interaction.subChannel) { const { host, tenant, token } = localStorage(req.query.authKey);
addNode(filter, "SubChannel", value.node.interaction.subChannel, data);
if (chain["Channel-SubChannel"]) { axios
addLink( .post(
data, `${host}/unified-data-gateway/${tenant}/graphql`,
value.node.interaction.__typename, JSON.stringify({
value.node.interaction.subChannel query: referenceIdQuery,
); variables: { startTime, endTime },
}),
{
headers: {
Authorization: `OIDC_id_token ${token}`,
"Content-Type": "application/json",
},
} }
} )
.then((result) => {
if (result.data.errors && result.data.errors.length > 0) {
result.data.errors.forEach(function (error) {
logger.error("ERROR: Errors in results - " + error.message);
});
if (value.node.queue) { // TODO: Should keep errors for filteredContacts
const queueName = `${value.node.queue.name}(${value.node.queue.orgScope})`; result.data.errors = [];
addNode(filter, "Queue", queueName, data);
if (chain["Channel-Queue"]) {
addLink(data, value.node.interaction.__typename, queueName);
} }
if (chain["SubChannel-Queue"]) {
addSubChannelLink(queueName); if (!result.data.data.findContactsCompletedBetween) {
logger.debug("No findContactsCompletedBetween returned.");
res.send(data);
return;
} }
}
if (value.node.outcome) { result.data.data.findContactsCompletedBetween.edges.forEach((value) => {
value.node.outcome.edges.forEach((element) => { // TODO: Should add INBOUND and OUTBOUND Nodes before Channel
addNode(filter, "Outcome", element.node.text, data); addNode(filter, "Channel", value.node.interaction.__typename, data);
if (chain["Channel-Outcome"]) { if (value.node.interaction.subChannel) {
addLink(data, value.node.interaction.__typename, element.node.text); addNode(
filter,
"SubChannel",
value.node.interaction.subChannel,
data
);
if (chain["Channel-SubChannel"]) {
addLink(
data,
value.node.interaction.__typename,
value.node.interaction.subChannel
);
}
} }
if (chain["SubChannel-Outcome"]) { if (value.node.queue) {
addSubChannelLink(element.node.text);
}
if (chain["Queue-Outcome"] && !!value.node.queue) {
const queueName = `${value.node.queue.name}(${value.node.queue.orgScope})`; const queueName = `${value.node.queue.name}(${value.node.queue.orgScope})`;
addLink(data, queueName, element.node.text); addNode(filter, "Queue", queueName, data);
if (chain["Channel-Queue"]) {
addLink(data, value.node.interaction.__typename, queueName);
}
if (chain["SubChannel-Queue"]) {
addSubChannelLink(queueName);
}
}
if (value.node.outcome) {
value.node.outcome.edges.forEach((element) => {
addNode(filter, "Outcome", element.node.text, data);
if (chain["Channel-Outcome"]) {
addLink(
data,
value.node.interaction.__typename,
element.node.text
);
}
if (chain["SubChannel-Outcome"]) {
addSubChannelLink(element.node.text);
}
if (chain["Queue-Outcome"] && !!value.node.queue) {
const queueName = `${value.node.queue.name}(${value.node.queue.orgScope})`;
addLink(data, queueName, element.node.text);
}
});
}
function addSubChannelLink(target) {
if (value.node.interaction.subChannel) {
addLink(data, value.node.interaction.subChannel, target);
} else {
// SubChannel does not exist, revert to Channel if in chain
if (chain["Channel-SubChannel"]) {
addLink(data, value.node.interaction.__typename, target);
}
}
} }
}); });
}
function addSubChannelLink(target) { logger.debug(`Sending data: ${JSON.stringify(data, null, 2)}`);
if (value.node.interaction.subChannel) { res.send(data);
addLink(data, value.node.interaction.subChannel, target); });
} else {
// SubChannel does not exist, revert to Channel if in chain
if (chain["Channel-SubChannel"]) {
addLink(data, value.node.interaction.__typename, target);
}
}
}
});
if (req.query.useSampleData) { if (req.query.useSampleData) {
const data = sampleFlow(filter); const data = sampleFlow(filter);
res.send(data); res.send(data);
return; return;
} }
logger.debug(`Sending data: ${JSON.stringify(data, null, 2)}`);
res.send(data);
}); });
function addLink(data, source, target) { function addLink(data, source, target) {

View File

@ -4,101 +4,29 @@ import { logger } from "../../utils/index.js";
// import { URLSearchParams } from "url"; // import { URLSearchParams } from "url";
import { inspect } from "util"; import { inspect } from "util";
import localStorage from "local-storage"; import localStorage from "local-storage";
import { referenceIdQuery } from "../../utils/graphQueries.js";
const router = Router(); const router = Router();
router.get("/", (req, res, next) => { router.get("/", (req, res, next) => {
query(req.query.referenceId); query(req.query.referenceId);
function query(referenceId) { function query(referenceId) {
logger.info(`Executing Query with ${referenceId}`); logger.info(`Executing Query with ${referenceId}`);
const query = `query ($startTime: DateTime, $endTime: DateTime) {
findContactsCompletedBetween(startTime: $startTime, endTime: $endTime, filter: {interactionTypes : EMAIL}) {
totalCount
edges {
node {
systemId
startTime
endTime
direction
handledBy {
username
firstName
lastName
nickname
orgScope
}
activeDuration
notes {
totalCount
edges {
node {
text
}
}
}
interaction {
systemId
locale
__typename
... on Email {
messageId
threadId
sentDate
receivedDate
subject
fromAddress
toAddresses
ccAddresses
bccAddresses
detectedLanguage
mailboxName
attachmentCount
isDuplicate
}
}
outcome {
totalCount
edges {
node {
text
isActive
isVisible
}
}
}
customer {
totalCount
edges {
node {
ref
firstName
lastName
}
}
}
queue {
name
orgScope
}
}
}
}
}`;
const startTime = new Date( const startTime = new Date(
new Date().setFullYear(new Date().getFullYear() - 2) new Date().setFullYear(new Date().getFullYear() - 2)
); );
const endTime = new Date(new Date().setHours(new Date().getHours() - 1)); var endTime = new Date();
// FIX for 'endTime' parameter cannot be later than one minute prior to now.
endTime.setMinutes(endTime.getMinutes() - 1);
const { host, tenant, token } = localStorage(req.query.authKey); const { host, tenant, token } = localStorage(req.query.authKey);
axios axios
.post( .post(
`${host}/unified-data-gateway/${tenant}/graphql`, `${host}/unified-data-gateway/${tenant}/graphql`,
JSON.stringify({ JSON.stringify({
query, query: referenceIdQuery,
variables: { startTime, endTime }, variables: { startTime, endTime },
}), }),
{ {
@ -109,8 +37,6 @@ router.get("/", (req, res, next) => {
} }
) )
.then((result) => { .then((result) => {
const contacts = result.data.data.findContactsCompletedBetween.edges;
if (result.data.errors && result.data.errors.length > 0) { if (result.data.errors && result.data.errors.length > 0) {
result.data.errors.forEach(function (error) { result.data.errors.forEach(function (error) {
logger.error("ERROR: Errors in results - " + error.message); logger.error("ERROR: Errors in results - " + error.message);
@ -120,6 +46,8 @@ router.get("/", (req, res, next) => {
result.data.errors = []; result.data.errors = [];
} }
const contacts = result.data.data.findContactsCompletedBetween.edges;
const filteredContacts = []; const filteredContacts = [];
contacts.forEach(function (contact) { contacts.forEach(function (contact) {
if (contact.node.interaction.__typename === "Email") { if (contact.node.interaction.__typename === "Email") {
@ -204,7 +132,7 @@ router.get("/", (req, res, next) => {
.catch((err) => { .catch((err) => {
// bin the token on error // bin the token on error
req.session.destroy(); req.session.destroy();
next(err) next(err);
}); });
} }
}); });

74
src/utils/graphQueries.js Normal file
View File

@ -0,0 +1,74 @@
export const referenceIdQuery = `query ($startTime: DateTime, $endTime: DateTime) {
findContactsCompletedBetween(startTime: $startTime, endTime: $endTime) {
totalCount
edges {
node {
systemId
startTime
endTime
direction
handledBy {
username
firstName
lastName
nickname
orgScope
}
activeDuration
notes {
totalCount
edges {
node {
text
}
}
}
interaction {
systemId
locale
__typename
... on Email {
messageId
threadId
sentDate
receivedDate
subject
fromAddress
toAddresses
ccAddresses
bccAddresses
detectedLanguage
mailboxName
attachmentCount
isDuplicate
}
}
outcome {
totalCount
edges {
node {
text
isActive
isVisible
}
}
}
customer {
totalCount
edges {
node {
ref
firstName
lastName
}
}
}
queue {
name
orgScope
}
}
}
}
}`;