#AttachmentBuilder and channel.send

7 messages · Page 1 of 1 (latest)

glacial roost

Hello everyone, what I am attempting to do is build an attachment from a Readable stream and send it to a channel.

So, everything starts with a createFile method which receives a stream and pipes it into a stream that splits the file into chunks of 25mb each. If the file for example is 26 mb I am going to end up with two chunks, one of 25mb and other one of 1mb. In my code i call them "parts".

public createFile(filePath: string, fileStream: FileStream): Promise<stream.Writable> {
        let j = 0;

        return pump(
            fileStream,
            new SizeStream(25e+6, (s) => {
                if (this.aesKey != null) {
                    let iv = crypto.randomBytes(16);
                    this.createFileImpl(filePath + (j == 0 ? "" : ".part" + j), s.pipe(this.getCipher(iv)), iv);
                } else {
                    this.createFileImpl(filePath + (j == 0 ? "" : ".part" + j), s);
                }
    
                j++;
            })
        );
    };

Here's the code for createFileImpl:

    private createFileImpl(filePath: string, content: stream.Readable, iv: Buffer = null): FileJournalEntry {
        let that = this;
       
        let directoryName = that.normalizePath(path.dirname(filePath));
        let fileName = path.basename(filePath);
        let directory = that.directories.find(d => d.name == directoryName);

        /* There's some unrelated commented out code in between... */

        const entry = this.createFileOnDiscord(fileName, directory, content, iv);

        return entry;
    }

//I am hitting the character limit so i'll continue in a comment.

solemn palmBOT
  • Consider reading #how-to-get-help to improve your question!
  • Explain what exactly your issue is.
  • Post the full error stack trace, not just the top part!
  • Show your code!
  • Issue solved? Press the button!
glacial roost

Finally, there's createFileOnDiscord which handles posting the "part" to discord.

    private createFileOnDiscord(fileName: string, directory: DirectoryJournalEntry, content: stream.Readable, iv: Buffer) {
        let entry: FileJournalEntry = new FileJournalEntry();
        
        if (iv != null) {
            entry.iv = iv.toString("hex");
        }

        entry.directory = directory.id;
        entry.name = fileName;

        let text = JSON.stringify(entry);
        let attachmentName = fileName;

        if (this.aesKey != null) {
            text = this.encrypt(text);
            attachmentName = this.encrypt(attachmentName);
        }

        let a = new Discord.AttachmentBuilder(content, {name: attachmentName});

        console.log('text: ', text);
        console.log('attachment: ', a);

        this.channel.send({
            content: text,
            files: [a]
        }).then((message: Discord.Message) => { 
            let attachment = message.attachments.first();
            entry.size = attachment.size;
            entry.url = attachment.url;
            entry.mid = message.id;
            this.files.push(entry);
            console.log('part sent to discord');
        });

        return entry;
    }

As you might see I use Discord.AttachmentBuilder and the channel.send method to send my message to the server. However, in the case of my file only the first 2 parts of a total of 3 parts are sent. Even though I tried writing all of the chunks to the filesystem and all of them get written properly.
Any clues?

vapid mortarBOT

If you aren't getting any errors, try to place console.log checkpoints throughout your code to find out where execution stops.

  • Once you do, log relevant values and if-conditions
  • More sophisticated debugging methods are breakpoints and runtime inspections: learn more
glacial roost

The console.log statements before this.channel.send log three times. That's the amount of parts I am expecting. However, the console.log statement inside .then log only twice which corresponds to the number of files sent.

There's a lot of noise going around in the logs, so I've cut only the relevant part. Since the stream comes from a socket it's hard to debug with breakpoints as the connection gets aborted.

text:  {"type":0,"directory":"f856240a-0fbf-4f4e-9017-aa7b54fe25c5","name":"freetube-0.19.1-setup-x64.exe"}
attachment:  AttachmentBuilder {attachment: Readable, name: 'freetube-0.19.1-setup-x64.exe', description: undefined}
OK: 226 Transfer complete
> PASV 
OK: 227 Entering passive mode (127,0,0,1,113,90)
> LIST 
OK: 125 Data connection already open. Transfer starting
OK: 226 LIST Transfer complete
text:  {"type":0,"directory":"f856240a-0fbf-4f4e-9017-aa7b54fe25c5","name":"freetube-0.19.1-setup-x64.exe.part1"}
attachment:  AttachmentBuilder {attachment: Readable, name: 'freetube-0.19.1-setup-x64.exe.part1', description: undefined}
text:  {"type":0,"directory":"f856240a-0fbf-4f4e-9017-aa7b54fe25c5","name":"freetube-0.19.1-setup-x64.exe.part2"}
attachment:  AttachmentBuilder {attachment: Readable, name: 'freetube-0.19.1-setup-x64.exe.part2', description: undefined}
2 part sent to discord
stoic gull

That looks like it only ever tries to send two parts. So the issue must be inside your stream I‘d say. What does it do when the source stream ends? That should afaik close the SizeStream too because of the pump, but does that stream‘s end event cause it to send the last chunk too?