Skip to content
This repository has been archived by the owner on Jun 1, 2024. It is now read-only.

Commit

Permalink
next push
Browse files Browse the repository at this point in the history
  • Loading branch information
dhawton committed Dec 1, 2020
1 parent aa88c96 commit 114230b
Show file tree
Hide file tree
Showing 12 changed files with 242 additions and 82 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
dist
config.json
node_modules
node_modules
log.txt
28 changes: 24 additions & 4 deletions config.sample.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,30 @@
{
"discord": {
"token": "",
"announceChannel": "promote-your-content",
"role": ""
"token": ""
},
"applications": [
{
"type": "",
"docId": "",
"sheetId": "",
"announce": {
"column": 0,
"values": {
"term": "channelId"
}
}
}
],
"googleapi": {

"type": "",
"project_id": "",
"private_key_id": "",
"private_key": "",
"client_email": "",
"client_id": "",
"auth_url": "",
"token_uri": "",
"auth_provider_x509_cert_url": "",
"client_x509_cert_url": ""
}
}
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,13 @@
"dependencies": {
"axios": "^0.21.0",
"babel-preset-minify": "^0.5.1",
"csv-parse": "^4.14.1",
"csv-parser": "^2.3.3",
"discord.js": "^12.5.1",
"get-stream": "^6.0.0",
"google-auth-library": "^6.1.3",
"googleapis": "65"
"googleapis": "65",
"to-readable-stream": "^2.1.0"
},
"devDependencies": {
"@types/axios": "^0.14.0",
Expand Down
74 changes: 70 additions & 4 deletions src/ApplicationHandler.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,79 @@
import googleapi from "./index";
import csvParser from "csv-parser";
import toReadableStream from "to-readable-stream";
import getStream from "get-stream";

import { googleapi, guild } from "./index";
import Log from "./Log";
import LiveEmbed from "./LiveEmbed";
import Utils from "./Utils";

class ApplicationHandler {
config: Config["applications"];
config: ApplicationConfig;
intTimer: NodeJS.Timer;

constructor(config) {
constructor(config: ApplicationConfig) {
this.config = config;
this.intTimer = setInterval(() => {
try {
this.handle();
} catch (err) {
Log.error(`Error running application handle ${err}`);
}
}, 5 * 60 * 1000);
this.handle();
}

async handle(): Promise<void> {
let doc;
try {
doc = await googleapi.loadSheet(this.config.docId, this.config.sheetId);
Log.info(`Caught new log entry for ${this.config.type}: ${Buffer.from(JSON.stringify(doc)).toString("base64")}`);
let streamData = toReadableStream(doc);
let data: any = await getStream.array(streamData.pipe(csvParser({ headers: false })));
const appquestions = [];
data.forEach((v: string[], idx: number) => {
if (idx === 0) {
Object.keys(v).forEach((key) => {
appquestions.push(v[key]);
});
} else {
const channel = this.findChannel(v);
if (channel !== null) {
googleapi.deleteRow(idx, this.config.docId, this.config.sheetId);
let msg = LiveEmbed.createFromApplication(this.config.type, appquestions, v);
Utils.sendMessage(guild, channel, `NEW APPLICATION RECEIVED:`, msg);
}
}
});
} catch (err) {
Log.error(`Error loading sheet: ${err}`);
console.trace(err);
return;
}
}

findChannel(appdata: string[]): string {
if (typeof this.config.announce === "string") {
return this.config.announce;
} else if (typeof this.config.announce.values === "string") {
return this.config.announce.values;
} else if (typeof this.config.announce === "object") {
let channel: string;
Object.keys(this.config.announce.values).forEach((key) => {
if (appdata[this.config.announce.column].toLowerCase() === key.toLowerCase()) {
channel = this.config.announce.values[key];
}
});

if (channel) {
return channel;
} else if (this.config.announce.values["rest"]) {
return this.config.announce.values["rest"];
}
}

return null;
}

}

export default ApplicationHandler;
51 changes: 33 additions & 18 deletions src/google.ts → src/GoogleAPI.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
/* eslint-disable @typescript-eslint/lines-between-class-members */
import fs from "fs";
import path from "path";
import { google } from "googleapis";
import { JWT } from "google-auth-library";
import axios from "axios";
import Log from "./log";
import Log from "./Log";

const GOOGLE_PATH = path.resolve(__dirname, "google");
const TOKEN_PATH = path.resolve(__dirname, "google", "token.json");
const SCOPE = ["https://www.googleapis.com/auth/spreadsheets"];

class GoogleAPI {
Expand All @@ -16,9 +11,6 @@ class GoogleAPI {
jwtInterval: NodeJS.Timer;

constructor(config: Config["googleapi"]) {
if (fs.existsSync(GOOGLE_PATH)) {
fs.mkdirSync(GOOGLE_PATH);
}
this.credentials = config;
}

Expand Down Expand Up @@ -48,27 +40,50 @@ class GoogleAPI {
await this.jwtClient.authorize();
}

async loadSheet(id: string): Promise<{ [key: string]: string }[]> {
async loadSheet(id: string, sheet?: string): Promise<string> {
let res;
Log.info(
JSON.stringify({
access_token: this.jwtClient.credentials.access_token,
expires: this.jwtClient.credentials.expiry_date,
}),
);
try {
res = await axios({
method: "GET",
url: `https://docs.google.com/spreadsheets/d/${id}/gviz/tq?tqx=out:csv`,
url: `https://docs.google.com/spreadsheets/d/${id}/gviz/tq?tqx=out:csv${ sheet ? `&sheet=${sheet}` : "" }`,
headers: {
Authorization: `Bearer ${this.jwtClient.credentials.access_token}`,
},
});
} catch (err) {
Log.error(`Error fetching application CSV for ${id}: ${err}`);
Log.error(`Error fetching application CSV for ${id}: ${err} - ${JSON.stringify(err.response.data)}`);
}
return res?.data;
}

async deleteRow(id: number, docId: string, sheet: string): Promise<void> {
try {
await axios({
method: "POST",
url: `https://sheets.googleapis.com/v4/spreadsheets/${docId}:batchUpdate`,
headers: {
Authorization: `Bearer ${this.jwtClient.credentials.access_token}`,
},
data: {
requests: [
{
"deleteDimension": {
"range": {
"sheetId": sheet,
"dimension": "ROWS",
"startIndex": id,
"endIndex": id+1
}
}
}
]
}
});
} catch (err: any) {
Log.error(`Error deleting row ${id} from ${docId}: ${err} - ${JSON.stringify(err.response.data)}`);
Log.error(err.stack);
}
}
}

export default GoogleAPI;
17 changes: 17 additions & 0 deletions src/LiveEmbed.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import Discord from "discord.js";


class LiveEmbed {
static createFromApplication(apptype: string, appquestions: string[], appdata: string[]): Discord.MessageEmbed {
const msgEmbed = new Discord.MessageEmbed();
msgEmbed.setColor("#ff0000");
msgEmbed.setTitle(`APPLICATION TYPE: ${apptype.toUpperCase()}`);
appquestions.forEach((_,idx) => {
msgEmbed.addField(appquestions[idx], appdata[idx], false);
});
msgEmbed.setFooter("END OF LINE.");
return msgEmbed;
}
}

export default LiveEmbed;
2 changes: 1 addition & 1 deletion src/util.ts → src/Utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class Utils {
msg: string,
embeddedmsg: Discord.MessageEmbed,
): void {
const channel = guild.channels.cache.find((ch) => ch.name === announceChannel);
const channel = guild.channels.cache.find((ch) => (ch.name === announceChannel || ch.id === announceChannel));
if (!channel) return;
(channel as Discord.TextChannel).send(msg, { embed: embeddedmsg });
}
Expand Down
32 changes: 0 additions & 32 deletions src/embed.ts

This file was deleted.

20 changes: 12 additions & 8 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,35 @@
import Discord from "discord.js";
import fs from "fs";
import path from "path";
import GoogleAPI from "./google";
import ApplicationHandler from "./ApplicationHandler";
import GoogleAPI from "./GoogleAPI";

import Log from "./log";
import Log from "./Log";

if (!fs.existsSync(path.resolve(__dirname, "config.json"))) {
if (!fs.existsSync(path.resolve("config.json"))) {
Log.error("Config not found");
process.exit(1);
}

const config: Config = JSON.parse(fs.readFileSync(path.resolve(__dirname, "config.json")).toString());
const config: Config = JSON.parse(fs.readFileSync(path.resolve("config.json")).toString());

const client = new Discord.Client();
const googleapi = new GoogleAPI(config.googleapi);
let guild: Discord.Guild;
googleapi.authentication();
const applicationhanders = {};

Log.info("MASTER CONTROL PROGRAM");

client.on("ready", async () => {
Log.info(`Logged in as ${client.user.tag}`);
client.user.setActivity("VBRP Whitelist Apps", { type: "WATCHING" });
const doc = await googleapi.loadSheet("1cPjVoiO3KvhjmWu_Fc86FWGxUaUYAoyCHxghne6af9A");
Log.info(JSON.stringify(doc));
//buildHandlers(googleapi);
guild = client.guilds.cache.first();
config.applications.forEach((v) => {
applicationhanders[v.type] = new ApplicationHandler(v);
});
});

client.login(config.discord.token);

export default googleapi;
export { googleapi, guild };
15 changes: 13 additions & 2 deletions src/log.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
import fs from "fs";

class Log {
static lastDate: string;

static write(message: string, error: boolean | null): void {
// eslint-disable-next-line no-console
console.log(`[${new Date().toISOString()}] ${error ? " ERROR - " : " INFO - "} ${message}`);
const d = new Date();
const today = `${d.getFullYear()}-${d.getMonth()+1}-${d.getDate()}`;
if (today !== this.lastDate && fs.existsSync("log.txt")) {
fs.renameSync("log.txt", `log-${this.lastDate}.txt`);
this.lastDate = today;
}
let msg = `[${d.toISOString()}] ${error ? " ERROR - " : " INFO - "} ${message}`
console.log(msg);
fs.appendFile("log.txt", `${msg}\n`, () => {});
}

static info(message: string): void {
Expand Down
20 changes: 11 additions & 9 deletions src/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,7 @@ declare interface Config {
discord: {
token: string;
};
applications: {
type: string;
docId: string;
sheetId: string;
announce: {
column: number;
values: { [key: string]: string };
};
}[];
applications: ApplicationConfig[];
googleapi: {
type: string;
project_id: string;
Expand All @@ -25,6 +17,16 @@ declare interface Config {
};
}

declare interface ApplicationConfig {
type: string;
docId: string;
sheetId: string;
announce: {
column: number;
values: { [key: string]: string } | string;
};
}

declare interface ApplicationData {
docid: string;
name: string;
Expand Down
Loading

0 comments on commit 114230b

Please sign in to comment.