-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
126 lines (105 loc) · 3.9 KB
/
index.js
File metadata and controls
126 lines (105 loc) · 3.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/*
* The aim of this script is to pull all ticket openers for a given gmodstore product
* So that it can be used on Machine Learning to build a classification model.
* It is intended to be used with liner.ai, but the output data can be adapted or imported to pretty much any data set.
*/
require('dotenv').config()
const env = process.env;
const axios = require('axios');
const fs = require('fs');
const allTickets = [];
// Get a GmodStore's Product's Tickets
async function getGmodstoreProductTickets(productID, cursor) {
return (await axios.get('https://www.gmodstore.com/api/v3/products/' + productID + '/tickets', {
headers: {
Authorization: 'Bearer ' + env.GMS_TOKEN
},
params: {
cursor
}
}))?.data
}
// Get the opener message for a given ticket
async function getGmodstoreTicketFirstOpener(ticketID) {
return (await axios.get('https://www.gmodstore.com/api/v3/tickets/' + ticketID + '/messages', {
headers: {
Authorization: 'Bearer ' + env.GMS_TOKEN
},
params: {
perPage: 1
}
}))?.data
}
// Get the labels for a given ticket.
async function getGmodstoreTicketTags(ticketID) {
return (await axios.get('https://www.gmodstore.com/api/v3/tickets/' + ticketID + '/tags', {
headers: {
Authorization: 'Bearer ' + env.GMS_TOKEN
},
params: {
perPage: 1
}
}))?.data
}
// Used to prevent API rate limiting
async function sleep() {
await new Promise(r => setTimeout(r, 1000));
}
// The main process loop
async function main() {
// Set up files
await fs.rmSync('data', { recursive: true, force: true });
await fs.mkdirSync('data');
await fs.mkdirSync('data/unlabelled'); // Used for tickets without tags
// Build a recursive list of all tickets for the given addon.
let curCursor = true;
while (curCursor) {
console.log('Processing with cursor', curCursor)
let ticketSet = await getGmodstoreProductTickets(env.GMS_ADDON_ID, curCursor)
// Add them to the list
ticketSet.data.forEach(ticket => {
allTickets.push(ticket.id);
});
// Set the next cursor.
curCursor = ticketSet.cursors.next;
await sleep();
}
console.log('Now processing', allTickets.length, 'tickets');
let count = 0;
for (const ticket of allTickets) {
count++; // So we can do pretty counting in the console for progress.
console.log('Processing ticket', ticket, '('+ count + '/' + allTickets.length + ')')
let ticketTags = await getGmodstoreTicketTags(ticket);
// Pull the ticket from gmodstore's API
let ticketReply = await getGmodstoreTicketFirstOpener(ticket);
const messageData = JSON.parse(ticketReply.data[0].body)
// Because the ticket is given as Delta, we need to essentially brute merge the message together. It's not perfect, but it works (mostly)
let message = ''
messageData.ops.forEach(data => {
message = message + data.insert;
});
// Write the file to its given labels
if (ticketTags?.data?.length > 0) {
for (const tag of ticketTags.data) {
// Make the label if it doesn't already exist
if (!fs.existsSync(tag.name)){
await fs.mkdirSync('data/' + tag.name);
}
// Save the file
fs.writeFile('data/' + tag.name + '/' + ticket + '.txt', message, err => {
if (err) console.error(err);
});
}
} else {
// No label, put it in the unlabeled section
fs.writeFile('data/unlabelled/' + ticket + '.txt', message, err => {
if (err) console.error(err);
});
}
await sleep();
}
}
// Top level await is goated, sue me.
(async () => {
await main();
})();