Everything you changed seems syntactically correct. But comparing your script to others posted you’re missing functions: getCustomer, createCustomer, etc.
Using a script Jesse posted a few years ago, I think I’ve merged your changes and the number formatting over. You’ll have to test. Also, check the config at the top of the script. I think I copied everything over but please make sure.
var express = require('express');
var request = require('request');
var querystring = require('querystring');
var libphonenumber = require('libphonenumber - js');
var app = express();
var messageServer = 'localhost';
var messageServerPort = 9000;
var gloriaFoodKey = 'XXXXXXX';
var serverKey = '553181';
var timeout = 30000;
var customerEntityType = 'Customers';
var itemTagName = 'Gloria Name';
var ticketType = 'Ticket';
var departmentName = 'pizza';
var userName = 'Administrator';
var terminalName = 'Server';
var printJobName = 'Print Bill';
var additionalPrintJobs = []; // array of additional print job names
var miscProductName = 'Misc';
var deliveryFeeCalculation = 'Delivery Service';
var tipCalculation = 'Tip';
var accessToken = undefined;
var accessTokenExpires = '';
var formatPhoneNumber = true;
var formatPhoneNumberCountry = 'IL'; // set to your ISO country code
var formatPhoneNumberFormat = 'National'; // format type, this should suffice
var formatPhoneNumberHyphen = false;
var formatPhoneNumberNoSpaces = true;
Authorize(loop());
function Authorize(callback) {
accessToken = undefined;
var form = {
grant_type: 'client_credentials',
client_secret: serverKey,
client_id: 'gloria'
};
var formData = querystring.stringify(form);
var contentLength = formData.length;
request({
headers: {
'Content-Length': contentLength,
'Content-Type': 'application/x-www-form-urlencoded'
},
uri: 'http://' + messageServer + ':' + messageServerPort + '/Token',
body: formData,
method: 'POST'
}, function (err, res, body) {
if (err) {
console.log('Error while trying to authorize >', err.message);
} else if (res.statusCode === 400) {
console.log(body);
if (callback) callback();
} else {
var result = JSON.parse(body);
accessToken = result.access_token;
accessTokenExpires = new Date(result['.expires']);
if (callback) callback();
}
});
}
function gql(query, callback) {
if (!accessToken) {
console.log('Valid access Token is needed to execute GQL calls.')
return;
}
var data = JSON.stringify({
query: query
});
request({
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer ' + accessToken
},
uri: 'http://' + messageServer + ':' + messageServerPort + '/api/graphql',
body: data,
method: 'POST'
}, function (err, res, body) {
if (res.statusCode === 401) {
console.log('Should Authorize...');
Authorize(() => gql(query, callback));
} else {
var data = JSON.parse(body).data;
if (callback) callback(data);
}
});
}
function readTickets(callback) {
request({
method: 'POST',
uri: 'https://pos.gloriafood.com/pos/order/pop',
headers: {
'Authorization': gloriaFoodKey,
'Accept': 'application/json',
'Glf-Api-Version': '2'
}
}, function (err, res, body) {
if (err) {
console.log(`problem with request: ${err.message}`);
} else {
callback(JSON.parse(body));
}
});
}
function loop() {
if (!accessToken) {
console.log('There is no valid access token. Skipping...')
Authorize();
} else if (accessTokenExpires < new Date()) {
console.log('Access Token Expired. Reauthenticating...');
Authorize(() => loop());
return;
} else {
console.log('Reading Tickets...');
readTickets((tickets) => processTickets(tickets));
}
setTimeout(loop, timeout);
}
function processTickets(tickets) {
if (tickets.count == 0) return;
tickets.orders.forEach((order) => processOrder(order));
}
function processOrder(order) {
// Format phone number
if (formatPhoneNumber) {
order.client_phone = libphonenumber.formatNumber({
country: formatPhoneNumberCountry,
phone: order.client_phone
}, formatPhoneNumberFormat);
if (formatPhoneNumberHyphen) {
order.client_phone = order.client_phone.replace(/ +/g, '-');
} else {
order.client_phone = order.client_phone.replace(/-+/g, '');
}
if (formatPhoneNumberNoSpaces) {
order.client_phone = order.client_phone.replace(/ +/g, '');
}
}
var street = null;
var bloc = null;
var floor = null;
var apartment = null;
var intercom = null;
var moreAddress = null;
var zipcode = null;
var city = null;
if (order.client_address_parts != null) {
street = order.client_address_parts.street;
bloc = order.client_address_parts.bloc;
floor = order.client_address_parts.floor;
apartment = order.client_address_parts.apartment;
intercom = order.client_address_parts.intercom;
moreAddress = order.client_address_parts.more_address;
zipcode = order.client_address_parts.zipcode;
city = order.client_address_parts.city;
}
var customer = {
firstName: order.client_first_name,
lastName: order.client_last_name,
email: order.client_email,
phone: order.client_phone,
street: street,
city: city,
bloc: bloc,
floor: floor,
apartment: apartment,
intercom: intercom,
moreAddress: moreAddress,
zipcode: zipcode,
newCustomer: false
}
loadCustomer(customer, customer => {
var services = order.items
.filter(x => x.type === 'tip' || x.type === 'delivery_fee' || x.type === 'promo_cart')
.map(x => {
return {
name: getCalculationName(x.type),
amount: Math.abs((x.cart_discount_rate) * 100) || x.price
};
})
.filter(x => x.name);
loadItems(order.items.map(x => processItem(x)), items => {
createTicket(customer, items, order.instructions, order.fulfill_at, services, order.payment, ticketId => {
gql('mutation m {postTicketRefreshMessage(id:0){id}}', () => {
console.log(`Ticket ${ticketId} created...`);
});
});
});
});
}
function getCalculationName(name) {
if (name === 'promo_cart') return promotionDiscount;
if (name === 'tip') return tipCalculation;
if (name === 'delivery_fee') return deliveryFeeCalculation;
return undefined;
}
function loadItems(items, callback) {
var script = getLoadItemsScript(items);
gql(script, data => {
callback(items.filter(x => x.type === 'item').map(item => {
return {
id: item.id,
name: item.name,
type: item.type,
sambaName: data[`i${item.id}`][0] ? data[`i${item.id}`][0].name : miscProductName,
price: item.price,
quantity: item.quantity,
instructions: item.instructions,
options: item.options,
portions: item.portions
}
}));
});
}
function isNewCustomer(customer) {
if (customer.states && customer.states.find(x => x.stateName === 'CStatus')) {
return customer.states.find(x => x.stateName === 'CStatus').state === 'Unconfirmed';
}
return false;
}
function createTicket(customer, items, instructions, fulfill_at, services, payment, callback) {
var newCustomer = isNewCustomer(customer);
gql(getAddTicketScript(items, customer.name, newCustomer, instructions, fulfill_at, services, payment), data => {
if (newCustomer)
callback(data.addTicket.id);
else printTicketToKitchen(data.addTicket.id, () => callback(data.addTicket.id));
});
}
function printTicketToKitchen(ticketId, callback) {
gql(getKitchenPrintScript(ticketId), callback);
}
function loadCustomer(customer, callback) {
gql(getIsEntityExistsScript(customer), (data) => {
if (!data.isEntityExists) {
createCustomer(customer, callback);
} else getCustomer(customer.phone, callback);
});
}
function createCustomer(customer, callback) {
gql(getAddCustomerScript(customer), (data) => {
gql(getNewCustomerStateScript(customer), () => {
getCustomer(data.addEntity.name, callback);
})
});
}
function getCustomer(customerName, callback) {
gql(getCustomerScript(customerName), (data) => {
callback(data.getEntity);
});
}
function getLoadItemsScript(items) {
var part = items.map(item => `i${item.id}: getProducts(itemTag:{name:"${itemTagName}",value:"${item.name}"}){name} `);
return `{${part}}`;
}
function getCustomerScript(name) {
return `{getEntity(type:"${customerEntityType}",name:"${name}"){name,customData{name,value},states{stateName,state}}}`;
}
function getIsEntityExistsScript(customer) {
return `{isEntityExists(type:"${customerEntityType}",name:"${customer.phone}")}`;
}
function getAddCustomerScript(customer) {
return `
mutation m{addEntity(entity:{
entityType:"${customerEntityType}",name:"${customer.phone}",customData:[
{name:"First Name",value:"${customer.firstName}"},
{name:"Last Name",value:"${customer.lastName}"},
{name:"Address",value:"${customer.address}"},
{name:"EMail",value:"${customer.email}"},
{name:"street",value:"${customer.street}"}
]})
{name}
}`;
}
function getNewCustomerStateScript(customer) {
return `mutation m{updateEntityState(entityTypeName:"${customerEntityType}",entityName:"${customer.phone}",state:"Unconfirmed",stateName:"CStatus"){name}}`;
}
function getKitchenPrintScript(ticketId) {
return `mutation m {
executePrintJob(name: "${printJobName}", ticketId: ${ticketId},
orderStateFilters: [{stateName: "Status", state: "New"}],
nextOrderStates:[{stateName:"Status",currentState:"New",state:"Submitted"}])
{name}
}`;
}
function GetOrderTags(order) {
if (order.options) {
var options = order.options.map(x => `{tagName:"${x.group_name}",tag:"${x.name}",price:${x.price},quantity:${x.quantity}}`);
if (order.instructions) {
options.push(`{tagName:"Default",tag:"Instructions",note:"${order.instructions}"}`);
}
var result = options.join();
return `tags:[${result}],`
}
return "";
}
function GetPortions(order) {
if (order.portions) {
var portions = order.portions.map(x => `portion:"${x.name}",`);
var result = portions.join();
return `${result}`
}
return "";
}
function GetOrderPrice(order) {
if (order.portions) {
var price = order.portions.map(x => `price:${Math.abs((x.price) + (order.price))},`);
var result = price.join();
return `${result}`
}
if (order.price > 0)
return `price:${order.price},`;
return "";
}
function getAddTicketScript(orders, customerName, newCustomer, instructions, fulfill_at, services, payment) {
var orderLines = orders.map(order => {
return `{
name:"${order.sambaName ? order.sambaName : order.name}",
menuItemName:"${order.sambaName === miscProductName ? order.name : ''}",
quantity:${order.quantity > 0 ? order.quantity : 1},
${GetPortions(order)}
${GetOrderPrice(order)}
${GetOrderTags(order)}
states:[
{stateName:"Status",state:"Submitted"}
]
}`;
});
var entityPart = customerName ?
`entities:[{entityType:"${customerEntityType}",name:"${customerName}"}],` :
'';
var calculationsPart = services ?
`calculations:[${services.map(x => `{name:"${x.name}",amount:${x.amount}}`).join()}],` :
'';
var result = `
mutation m{addTicket(
ticket:{type:"${ticketType}",
department:"${departmentName}",
user:"${userName}",
terminal:"${terminalName}",
note:"${instructions !== null ? instructions : ''}",
${entityPart}
states:[
{stateName:"Status",state:"Unpaid"},
{stateName:"Source",state:"Gloria"},
{stateName:"Payment",state:"${payment}"}
],
tags:[{tagName:"Cook Time Minutes",tag:"${Math.ceil(Math.abs(new Date(fulfill_at) - Date.now()) / 60000)}"}],
${calculationsPart}
orders:[${orderLines.join()}]
}){id}}`;
return result;
}
function processItem(item) {
var result = {
id: item.id,
name: item.name,
type: item.type,
price: item.price,
quantity: item.quantity,
instructions: item.instructions,
options: item.options.filter(x => x.type === 'option').map(x => {
return {
group_name: x.group_name,
name: x.name,
quantity: x.quantity,
price: x.price
}
}),
portions: item.options.filter(x => x.type === 'size').map(x => {
return {
name: x.name,
price: x.price
}
})
};
return result;
}