Post: add support for !posting files
This commit is contained in:
parent
ee3a64cafa
commit
d3c3b65db6
4 changed files with 93 additions and 8 deletions
19
package-lock.json
generated
19
package-lock.json
generated
|
@ -39,6 +39,12 @@
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.0.tgz",
|
||||||
"integrity": "sha512-3TUHC3jsBAB7qVRGxT6lWyYo2v96BMmD2PTcl47H25Lu7UXtFH/2qqmKiVrnel6Ne//0TFYf6uvNX+HW2FRkLQ=="
|
"integrity": "sha512-3TUHC3jsBAB7qVRGxT6lWyYo2v96BMmD2PTcl47H25Lu7UXtFH/2qqmKiVrnel6Ne//0TFYf6uvNX+HW2FRkLQ=="
|
||||||
},
|
},
|
||||||
|
"@types/tmp": {
|
||||||
|
"version": "0.0.33",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/tmp/-/tmp-0.0.33.tgz",
|
||||||
|
"integrity": "sha1-EHPEvIJHVK49EM+riKsCN7qWTk0=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"abbrev": {
|
"abbrev": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
|
||||||
|
@ -2932,6 +2938,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"os-tmpdir": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
|
||||||
|
"integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
|
||||||
|
},
|
||||||
"p-finally": {
|
"p-finally": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
|
||||||
|
@ -3726,6 +3737,14 @@
|
||||||
"resolved": "https://registry.npmjs.org/tlds/-/tlds-1.203.1.tgz",
|
"resolved": "https://registry.npmjs.org/tlds/-/tlds-1.203.1.tgz",
|
||||||
"integrity": "sha512-7MUlYyGJ6rSitEZ3r1Q1QNV8uSIzapS8SmmhSusBuIc7uIxPPwsKllEP0GRp1NS6Ik6F+fRZvnjDWm3ecv2hDw=="
|
"integrity": "sha512-7MUlYyGJ6rSitEZ3r1Q1QNV8uSIzapS8SmmhSusBuIc7uIxPPwsKllEP0GRp1NS6Ik6F+fRZvnjDWm3ecv2hDw=="
|
||||||
},
|
},
|
||||||
|
"tmp": {
|
||||||
|
"version": "0.0.33",
|
||||||
|
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
|
||||||
|
"integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
|
||||||
|
"requires": {
|
||||||
|
"os-tmpdir": "~1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"to-object-path": {
|
"to-object-path": {
|
||||||
"version": "0.3.0",
|
"version": "0.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
"mysql": "^2.16.0",
|
"mysql": "^2.16.0",
|
||||||
"reflect-metadata": "^0.1.12",
|
"reflect-metadata": "^0.1.12",
|
||||||
"tlds": "^1.203.1",
|
"tlds": "^1.203.1",
|
||||||
|
"tmp": "0.0.33",
|
||||||
"ts-node": "^3.3.0",
|
"ts-node": "^3.3.0",
|
||||||
"typeorm": "^0.2.8",
|
"typeorm": "^0.2.8",
|
||||||
"typescript": "^3.2.2",
|
"typescript": "^3.2.2",
|
||||||
|
@ -50,6 +51,7 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^10.12.0",
|
"@types/node": "^10.12.0",
|
||||||
|
"@types/tmp": "0.0.33",
|
||||||
"husky": "^0.14.3",
|
"husky": "^0.14.3",
|
||||||
"lint-staged": "^7.2.0",
|
"lint-staged": "^7.2.0",
|
||||||
"nodemon": "^1.17.5",
|
"nodemon": "^1.17.5",
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
import { Plugin, decorators as d } from "knub";
|
import { Plugin, decorators as d } from "knub";
|
||||||
import { Channel, Message, TextChannel } from "eris";
|
import { Channel, Message, TextChannel } from "eris";
|
||||||
import { errorMessage } from "../utils";
|
import { errorMessage, downloadFile } from "../utils";
|
||||||
import { GuildSavedMessages } from "../data/GuildSavedMessages";
|
import { GuildSavedMessages } from "../data/GuildSavedMessages";
|
||||||
import { ISavedMessageData } from "../data/entities/SavedMessage";
|
|
||||||
|
import fs from "fs";
|
||||||
|
const fsp = fs.promises;
|
||||||
|
|
||||||
export class PostPlugin extends Plugin {
|
export class PostPlugin extends Plugin {
|
||||||
public static pluginName = 'post';
|
public static pluginName = "post";
|
||||||
|
|
||||||
protected savedMessages: GuildSavedMessages;
|
protected savedMessages: GuildSavedMessages;
|
||||||
|
|
||||||
|
@ -33,18 +35,39 @@ export class PostPlugin extends Plugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Post a message as the bot to the specified channel
|
* COMMAND: Post a message as the bot to the specified channel
|
||||||
*/
|
*/
|
||||||
@d.command("post", "<channel:channel> <content:string$>")
|
@d.command("post", "<channel:channel> [content:string$]")
|
||||||
@d.permission("post")
|
@d.permission("post")
|
||||||
async postCmd(msg: Message, args: { channel: Channel; content: string }) {
|
async postCmd(msg: Message, args: { channel: Channel; content?: string }) {
|
||||||
if (!(args.channel instanceof TextChannel)) {
|
if (!(args.channel instanceof TextChannel)) {
|
||||||
msg.channel.createMessage(errorMessage("Channel is not a text channel"));
|
msg.channel.createMessage(errorMessage("Channel is not a text channel"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const createdMsg = await args.channel.createMessage(args.content);
|
const content = args.content || undefined;
|
||||||
|
let downloadedAttachment;
|
||||||
|
let file;
|
||||||
|
|
||||||
|
if (msg.attachments.length) {
|
||||||
|
downloadedAttachment = await downloadFile(msg.attachments[0].url);
|
||||||
|
file = {
|
||||||
|
name: msg.attachments[0].filename,
|
||||||
|
file: await fsp.readFile(downloadedAttachment.path)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (content == null && file == null) {
|
||||||
|
msg.channel.createMessage(errorMessage("Text content or attachment required"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const createdMsg = await args.channel.createMessage(content, file);
|
||||||
await this.savedMessages.setPermanent(createdMsg.id);
|
await this.savedMessages.setPermanent(createdMsg.id);
|
||||||
|
|
||||||
|
if (downloadedAttachment) {
|
||||||
|
downloadedAttachment.deleteFn();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
43
src/utils.ts
43
src/utils.ts
|
@ -1,9 +1,15 @@
|
||||||
import at = require("lodash.at");
|
import at from "lodash.at";
|
||||||
import { Emoji, Guild, GuildAuditLogEntry, TextableChannel } from "eris";
|
import { Emoji, Guild, GuildAuditLogEntry, TextableChannel } from "eris";
|
||||||
import url from "url";
|
import url from "url";
|
||||||
import tlds from "tlds";
|
import tlds from "tlds";
|
||||||
import emojiRegex from "emoji-regex";
|
import emojiRegex from "emoji-regex";
|
||||||
|
|
||||||
|
import fs from "fs";
|
||||||
|
const fsp = fs.promises;
|
||||||
|
|
||||||
|
import https from "https";
|
||||||
|
import tmp from "tmp";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Turns a "delay string" such as "1h30m" to milliseconds
|
* Turns a "delay string" such as "1h30m" to milliseconds
|
||||||
* @param {String} str
|
* @param {String} str
|
||||||
|
@ -287,6 +293,41 @@ export async function createChunkedMessage(channel: TextableChannel, messageText
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Downloads the file from the given URL to a temporary file, with retry support
|
||||||
|
*/
|
||||||
|
export function downloadFile(attachmentUrl: string, retries = 3): Promise<{ path: string; deleteFn: () => void }> {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
tmp.file((err, path, fd, deleteFn) => {
|
||||||
|
if (err) throw err;
|
||||||
|
|
||||||
|
const writeStream = fs.createWriteStream(path);
|
||||||
|
|
||||||
|
https
|
||||||
|
.get(attachmentUrl, res => {
|
||||||
|
res.pipe(writeStream);
|
||||||
|
writeStream.on("finish", () => {
|
||||||
|
writeStream.end();
|
||||||
|
resolve({
|
||||||
|
path,
|
||||||
|
deleteFn
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.on("error", httpsErr => {
|
||||||
|
fsp.unlink(path);
|
||||||
|
|
||||||
|
if (retries === 0) {
|
||||||
|
throw httpsErr;
|
||||||
|
} else {
|
||||||
|
console.warn("File download failed, retrying. Error given:", httpsErr.message);
|
||||||
|
resolve(downloadFile(attachmentUrl, retries - 1));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function noop() {
|
export function noop() {
|
||||||
// IT'S LITERALLY NOTHING
|
// IT'S LITERALLY NOTHING
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue