Upload files to Discord as streams for speed
This commit is contained in:
parent
fff8f0d94c
commit
9c3f1abd3a
3 changed files with 25 additions and 25 deletions
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
const assert = require("assert").strict
|
const assert = require("assert").strict
|
||||||
const DiscordTypes = require("discord-api-types/v10")
|
const DiscordTypes = require("discord-api-types/v10")
|
||||||
|
const {Readable} = require("stream")
|
||||||
const passthrough = require("../../passthrough")
|
const passthrough = require("../../passthrough")
|
||||||
const {discord, db, select} = passthrough
|
const {discord, db, select} = passthrough
|
||||||
|
|
||||||
|
@ -51,7 +52,7 @@ async function withWebhook(channelID, callback) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} channelID
|
* @param {string} channelID
|
||||||
* @param {DiscordTypes.RESTPostAPIWebhookWithTokenJSONBody & {files?: {name: string, file: Buffer}[]}} data
|
* @param {DiscordTypes.RESTPostAPIWebhookWithTokenJSONBody & {files?: {name: string, file: Buffer | Readable}[]}} data
|
||||||
* @param {string} [threadID]
|
* @param {string} [threadID]
|
||||||
*/
|
*/
|
||||||
async function sendMessageWithWebhook(channelID, data, threadID) {
|
async function sendMessageWithWebhook(channelID, data, threadID) {
|
||||||
|
@ -64,7 +65,7 @@ async function sendMessageWithWebhook(channelID, data, threadID) {
|
||||||
/**
|
/**
|
||||||
* @param {string} channelID
|
* @param {string} channelID
|
||||||
* @param {string} messageID
|
* @param {string} messageID
|
||||||
* @param {DiscordTypes.RESTPatchAPIWebhookWithTokenMessageJSONBody & {files?: {name: string, file: Buffer}[]}} data
|
* @param {DiscordTypes.RESTPatchAPIWebhookWithTokenMessageJSONBody & {files?: {name: string, file: Buffer | Readable}[]}} data
|
||||||
* @param {string} [threadID]
|
* @param {string} [threadID]
|
||||||
*/
|
*/
|
||||||
async function editMessageWithWebhook(channelID, messageID, data, threadID) {
|
async function editMessageWithWebhook(channelID, messageID, data, threadID) {
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
// @ts-check
|
// @ts-check
|
||||||
|
|
||||||
const assert = require("assert").strict
|
|
||||||
const crypto = require("crypto")
|
|
||||||
const {pipeline} = require("stream")
|
|
||||||
const {promisify} = require("util")
|
|
||||||
const Ty = require("../../types")
|
const Ty = require("../../types")
|
||||||
const DiscordTypes = require("discord-api-types/v10")
|
const DiscordTypes = require("discord-api-types/v10")
|
||||||
|
const {Readable} = require("stream")
|
||||||
|
const assert = require("assert").strict
|
||||||
|
const crypto = require("crypto")
|
||||||
|
const fetch = require("node-fetch").default
|
||||||
const passthrough = require("../../passthrough")
|
const passthrough = require("../../passthrough")
|
||||||
const {sync, discord, db, select} = passthrough
|
const {sync, discord, db, select} = passthrough
|
||||||
|
|
||||||
|
@ -17,13 +17,12 @@ const eventToMessage = sync.require("../converters/event-to-message")
|
||||||
const api = sync.require("../../matrix/api")
|
const api = sync.require("../../matrix/api")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {DiscordTypes.RESTPostAPIWebhookWithTokenJSONBody & {files?: {name: string, file: Buffer}[], pendingFiles?: ({name: string, url: string} | {name: string, url: string, key: string, iv: string} | {name: string, buffer: Buffer})[]}} message
|
* @param {DiscordTypes.RESTPostAPIWebhookWithTokenJSONBody & {files?: {name: string, file: Buffer | Readable}[], pendingFiles?: ({name: string, url: string} | {name: string, url: string, key: string, iv: string} | {name: string, buffer: Buffer | Readable})[]}} message
|
||||||
* @returns {Promise<DiscordTypes.RESTPostAPIWebhookWithTokenJSONBody & {files?: {name: string, file: Buffer}[]}>}
|
* @returns {Promise<DiscordTypes.RESTPostAPIWebhookWithTokenJSONBody & {files?: {name: string, file: Buffer | Readable}[]}>}
|
||||||
*/
|
*/
|
||||||
async function resolvePendingFiles(message) {
|
async function resolvePendingFiles(message) {
|
||||||
if (!message.pendingFiles) return message
|
if (!message.pendingFiles) return message
|
||||||
const files = await Promise.all(message.pendingFiles.map(async p => {
|
const files = await Promise.all(message.pendingFiles.map(async p => {
|
||||||
let fileBuffer
|
|
||||||
if ("buffer" in p) {
|
if ("buffer" in p) {
|
||||||
return {
|
return {
|
||||||
name: p.name,
|
name: p.name,
|
||||||
|
@ -31,21 +30,22 @@ async function resolvePendingFiles(message) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ("key" in p) {
|
if ("key" in p) {
|
||||||
// Encrypted
|
// Encrypted file
|
||||||
const d = crypto.createDecipheriv("aes-256-ctr", Buffer.from(p.key, "base64url"), Buffer.from(p.iv, "base64url"))
|
const d = crypto.createDecipheriv("aes-256-ctr", Buffer.from(p.key, "base64url"), Buffer.from(p.iv, "base64url"))
|
||||||
fileBuffer = await fetch(p.url).then(res => res.arrayBuffer()).then(x => {
|
// @ts-ignore
|
||||||
return Buffer.concat([
|
fetch(p.url).then(res => res.body.pipe(d))
|
||||||
d.update(Buffer.from(x)),
|
|
||||||
d.final()
|
|
||||||
])
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
// Unencrypted
|
|
||||||
fileBuffer = await fetch(p.url).then(res => res.arrayBuffer()).then(x => Buffer.from(x))
|
|
||||||
}
|
|
||||||
return {
|
return {
|
||||||
name: p.name,
|
name: p.name,
|
||||||
file: fileBuffer // TODO: Once SnowTransfer supports ReadableStreams for attachment uploads, pass in those instead of Buffers
|
file: d
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Unencrypted file
|
||||||
|
/** @type {Readable} */ // @ts-ignore
|
||||||
|
const body = await fetch(p.url).then(res => res.body)
|
||||||
|
return {
|
||||||
|
name: p.name,
|
||||||
|
file: body
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
const newMessage = {
|
const newMessage = {
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
const Ty = require("../../types")
|
const Ty = require("../../types")
|
||||||
const DiscordTypes = require("discord-api-types/v10")
|
const DiscordTypes = require("discord-api-types/v10")
|
||||||
|
const {Readable} = require("stream")
|
||||||
const chunk = require("chunk-text")
|
const chunk = require("chunk-text")
|
||||||
const TurndownService = require("turndown")
|
const TurndownService = require("turndown")
|
||||||
const assert = require("assert").strict
|
const assert = require("assert").strict
|
||||||
|
@ -9,8 +10,6 @@ const entities = require("entities")
|
||||||
|
|
||||||
const passthrough = require("../../passthrough")
|
const passthrough = require("../../passthrough")
|
||||||
const {sync, db, discord, select, from} = passthrough
|
const {sync, db, discord, select, from} = passthrough
|
||||||
/** @type {import("../../matrix/file")} */
|
|
||||||
const file = sync.require("../../matrix/file")
|
|
||||||
/** @type {import("../converters/utils")} */
|
/** @type {import("../converters/utils")} */
|
||||||
const utils = sync.require("../converters/utils")
|
const utils = sync.require("../converters/utils")
|
||||||
/** @type {import("./emoji-sheet")} */
|
/** @type {import("./emoji-sheet")} */
|
||||||
|
@ -245,7 +244,7 @@ async function uploadEndOfMessageSpriteSheet(content, attachments, pendingFiles)
|
||||||
* @param {{api: import("../../matrix/api")}} di simple-as-nails dependency injection for the matrix API
|
* @param {{api: import("../../matrix/api")}} di simple-as-nails dependency injection for the matrix API
|
||||||
*/
|
*/
|
||||||
async function eventToMessage(event, guild, di) {
|
async function eventToMessage(event, guild, di) {
|
||||||
/** @type {(DiscordTypes.RESTPostAPIWebhookWithTokenJSONBody & {files?: {name: string, file: Buffer}[]})[]} */
|
/** @type {(DiscordTypes.RESTPostAPIWebhookWithTokenJSONBody & {files?: {name: string, file: Buffer | Readable}[]})[]} */
|
||||||
let messages = []
|
let messages = []
|
||||||
|
|
||||||
let displayName = event.sender
|
let displayName = event.sender
|
||||||
|
|
Loading…
Reference in a new issue