2022-07-21 11:11:24 +00:00
|
|
|
const jsdom = require('jsdom');
|
2022-07-29 09:59:03 +00:00
|
|
|
const mysql = require('mysql');
|
2022-10-19 08:35:41 +00:00
|
|
|
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: {
|
2022-10-19 08:35:41 +00:00
|
|
|
type: 'object',
|
2022-07-19 09:20:08 +00:00
|
|
|
root: true
|
|
|
|
},
|
|
|
|
http: {
|
|
|
|
path: `/closeTicket`,
|
2022-09-16 08:31:02 +00:00
|
|
|
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)
|
2022-09-16 08:31:02 +00:00
|
|
|
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 (
|
2023-01-12 14:07:48 +00:00
|
|
|
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
|
2023-01-12 14:07:48 +00:00
|
|
|
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
|
|
|
});
|
2022-10-19 08:35:41 +00:00
|
|
|
await getRequestToken();
|
2022-07-21 11:11:24 +00:00
|
|
|
|
2022-10-19 08:35:41 +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(' ');
|
2023-03-29 11:36:23 +00:00
|
|
|
const cookie = firtHeader.substring(0, firtHeader.length - 1);
|
2022-07-21 11:11:24 +00:00
|
|
|
const body = await response.text();
|
|
|
|
const dom = new jsdom.JSDOM(body);
|
|
|
|
const token = dom.window.document.querySelector('[name="__CSRFToken__"]').value;
|
|
|
|
|
2023-03-29 11:36:23 +00:00
|
|
|
await login(token, cookie);
|
2022-07-21 11:11:24 +00:00
|
|
|
}
|
2022-07-19 09:20:08 +00:00
|
|
|
|
2023-03-29 11:36:23 +00:00
|
|
|
async function login(token, cookie) {
|
2022-07-21 11:11:24 +00:00
|
|
|
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',
|
2023-03-29 11:36:23 +00:00
|
|
|
'Cookie': cookie
|
2022-07-21 11:11:24 +00:00
|
|
|
}
|
|
|
|
};
|
2023-03-29 11:36:23 +00:00
|
|
|
await fetch(ostUri, params);
|
2022-07-21 11:11:24 +00:00
|
|
|
|
2023-03-29 11:36:23 +00:00
|
|
|
await close(token, cookie);
|
2022-07-21 11:11:24 +00:00
|
|
|
}
|
|
|
|
|
2023-03-29 11:36:23 +00:00
|
|
|
async function close(token, cookie) {
|
2023-01-05 13:32:14 +00:00
|
|
|
for (const ticketId of ticketsId) {
|
|
|
|
try {
|
2023-03-29 11:36:23 +00:00
|
|
|
const lock = await getLockCode(token, cookie, ticketId);
|
2023-01-09 10:42:16 +00:00
|
|
|
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: {
|
2023-03-29 11:36:23 +00:00
|
|
|
'Cookie': cookie
|
2023-01-05 13:32:14 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
await fetch(ostUri, params);
|
|
|
|
} catch (e) {
|
2023-01-05 14:01:29 +00:00
|
|
|
const err = new Error(`${ticketId} Ticket close failed: ${e.message}`);
|
2023-01-10 07:14:13 +00:00
|
|
|
err.stack += e.stack;
|
2023-01-05 13:54:43 +00:00
|
|
|
console.error(err);
|
2023-01-05 13:32:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-29 11:36:23 +00:00
|
|
|
async function getLockCode(token, cookie, ticketId) {
|
2022-10-19 08:35:41 +00:00
|
|
|
const ostUri = `${config.host}/ajax.php/lock/ticket/${ticketId}`;
|
|
|
|
const params = {
|
|
|
|
method: 'POST',
|
|
|
|
headers: {
|
|
|
|
'X-CSRFToken': token,
|
2023-03-29 11:36:23 +00:00
|
|
|
'Cookie': cookie
|
2022-10-19 08:35:41 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
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;
|
2023-01-05 13:28:35 +00:00
|
|
|
}
|
2022-07-19 09:20:08 +00:00
|
|
|
};
|
|
|
|
};
|