salix/back/methods/osticket/closeTicket.js

159 lines
6.2 KiB
JavaScript
Raw Normal View History

2022-07-21 11:11:24 +00:00
const jsdom = require('jsdom');
2022-07-29 09:59:03 +00:00
const mysql = require('mysql');
const FormData = require('form-data');
2022-07-29 09:59:03 +00:00
2022-07-19 09:20:08 +00:00
module.exports = Self => {
Self.remoteMethodCtx('closeTicket', {
description: 'Close tickets without response from the user',
accessType: 'READ',
returns: {
type: 'object',
2022-07-19 09:20:08 +00:00
root: true
},
http: {
path: `/closeTicket`,
verb: 'POST'
2022-07-19 09:20:08 +00:00
}
});
Self.closeTicket = async ctx => {
const models = Self.app.models;
2022-07-21 11:11:24 +00:00
const config = await models.OsTicketConfig.findOne();
2022-09-16 09:46:55 +00:00
const ostUri = `${config.host}/login.php`;
2022-07-21 11:11:24 +00:00
2022-09-16 09:46:55 +00:00
if (!config.user || !config.password || !config.userDb || !config.passwordDb)
return false;
2022-07-29 09:59:03 +00:00
const con = mysql.createConnection({
2023-01-05 13:32:14 +00:00
host: config.hostDb,
user: config.userDb,
password: config.passwordDb,
port: config.portDb
2022-07-29 09:59:03 +00:00
});
const sql = `SELECT ot.ticket_id, ot.number
FROM osticket.ost_ticket ot
2022-12-20 07:45:14 +00:00
JOIN osticket.ost_ticket_status ots ON ots.id = ot.status_id
2022-07-29 09:59:03 +00:00
JOIN osticket.ost_thread ot2 ON ot2.object_id = ot.ticket_id AND ot2.object_type = 'T'
JOIN (
SELECT sub2.thread_id, sub2.type, sub2.updated, sub2.created
FROM (
SELECT ote.thread_id, ote.created, ote.updated, ote.type
FROM osticket.ost_thread_entry ote
WHERE ote.staff_id
ORDER BY ote.id DESC
LIMIT 10000000000000000000) sub2
GROUP BY sub2.thread_id
2022-12-20 07:45:14 +00:00
) sub ON sub.thread_id = ot2.id
2023-01-05 13:32:14 +00:00
WHERE ot.isanswered
AND ots.id IN (?)
AND sub.type = 'R'
AND IF(sub.updated > sub.created, sub.updated, sub.created) < DATE_SUB(CURDATE(), INTERVAL ? DAY);`;
2022-07-29 09:59:03 +00:00
2023-01-05 13:32:14 +00:00
const ticketsId = [];
2023-01-13 07:38:03 +00:00
const statusIdToClose = config.oldStatus.split(',');
2022-07-29 09:59:03 +00:00
con.connect(err => {
if (err) throw err;
2023-01-13 07:38:03 +00:00
con.query(sql, [statusIdToClose, config.day],
2023-01-05 13:32:14 +00:00
(err, results) => {
if (err) throw err;
for (const result of results)
ticketsId.push(result.ticket_id);
});
2022-07-29 09:59:03 +00:00
});
await getRequestToken();
2022-07-21 11:11:24 +00:00
async function getRequestToken() {
2022-07-21 11:11:24 +00:00
const response = await fetch(ostUri);
2022-07-19 09:20:08 +00:00
2022-07-21 11:11:24 +00:00
const result = response.headers.get('set-cookie');
const [firtHeader] = result.split(' ');
const firtCookie = firtHeader.substring(0, firtHeader.length - 1);
const body = await response.text();
const dom = new jsdom.JSDOM(body);
const token = dom.window.document.querySelector('[name="__CSRFToken__"]').value;
await login(token, firtCookie);
}
2022-07-19 09:20:08 +00:00
2022-07-21 11:11:24 +00:00
async function login(token, firtCookie) {
const data = {
__CSRFToken__: token,
do: 'scplogin',
userid: config.user,
passwd: config.password,
ajax: 1
};
const params = {
method: 'POST',
body: new URLSearchParams(data),
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Cookie': firtCookie
}
};
const response = await fetch(ostUri, params);
const result = response.headers.get('set-cookie');
const [firtHeader] = result.split(' ');
const secondCookie = firtHeader.substring(0, firtHeader.length - 1);
await close(token, secondCookie);
}
2023-01-05 13:32:14 +00:00
async function close(token, secondCookie) {
for (const ticketId of ticketsId) {
try {
2023-01-09 10:42:16 +00:00
const lock = await getLockCode(token, secondCookie, ticketId);
if (!lock.code) {
let error = `Can't get lock code`;
if (lock.msg) error += `: ${lock.msg}`;
throw new Error(error);
}
2023-01-05 13:32:14 +00:00
let form = new FormData();
form.append('__CSRFToken__', token);
form.append('id', ticketId);
form.append('a', config.responseType);
2023-01-09 10:42:16 +00:00
form.append('lockCode', lock.code);
2023-01-05 13:32:14 +00:00
form.append('from_email_id', config.fromEmailId);
form.append('reply-to', config.replyTo);
form.append('cannedResp', 0);
form.append('response', config.comment);
form.append('signature', 'none');
form.append('reply_status_id', config.newStatusId);
const ostUri = `${config.host}/tickets.php?id=${ticketId}`;
const params = {
method: 'POST',
body: form,
headers: {
'Cookie': secondCookie
}
};
await fetch(ostUri, params);
} catch (e) {
2023-01-05 14:01:29 +00:00
const err = new Error(`${ticketId} Ticket close failed: ${e.message}`);
err.stack += e.stack;
2023-01-05 13:54:43 +00:00
console.error(err);
2023-01-05 13:32:14 +00:00
}
}
}
async function getLockCode(token, secondCookie, ticketId) {
const ostUri = `${config.host}/ajax.php/lock/ticket/${ticketId}`;
const params = {
method: 'POST',
headers: {
'X-CSRFToken': token,
'Cookie': secondCookie
}
};
const response = await fetch(ostUri, params);
const body = await response.text();
const json = JSON.parse(body);
2023-01-09 10:42:16 +00:00
return json;
}
2022-07-19 09:20:08 +00:00
};
};