Skip to content

Multipart Uploads

Overview

The REST multipart helpers turn File values into replayable multipart/form-data requests. They support JSON payloads plus files[n], ordinary form fields, named file fields for endpoints such as sticker creation, and no-auth interaction webhook callbacks.

Architecture

File contains Name, ContentType, and an io.Reader. FileFromBytes creates an in-memory reader. FileFromPath reads the whole file, uses the base filename, and infers ContentType from the extension. Multipart request methods read each reader into memory before sending so 429 retries can rebuild the body. Large files therefore have a memory cost.

RequestMultipart writes a payload_json field followed by files[0], files[1], and so on. RequestMultipartNoAuth omits Authorization. RequestMultipartForm writes ordinary fields and uses files[0] for the single-file default; RequestMultipartFormNamedFile lets the caller select a field name such as file. AttachmentMetadata returns descriptors with sequential IDs starting at zero and each filename. ValidateFilesSize checks each file against 8 MiB, 25 MiB, 50 MiB, or 100 MiB for tiers 0, 1, 2, or 3.

Quick Start

go
package main

import (
	"fmt"

	"github.com/discord-go/discord.go/rest"
)

func main() {
	content := []byte("generated report")
	file := rest.FileFromBytes("report.txt", content)
	attachments := rest.AttachmentMetadata([]rest.File{file})
	if err := rest.ValidateFilesSize([][]byte{content}, 0); err != nil {
		panic(err)
	}
	builder := rest.NewAttachmentBuilderFromBytes("report.txt", content)
	built := builder.SetName("renamed.txt").Build()
	fmt.Println(attachments[0].ID, attachments[0].Filename, built.Name)
}

Creating Uploads

Use NewAttachmentBuilder(path) when a local file should be loaded and NewAttachmentBuilderFromBytes(name, content) for generated data. SetName changes a non-empty name; calling it on a nil builder is safe and Build on a nil builder returns an empty File. FileFromBytes keeps a reader over the provided bytes; the attachment builder clones generated bytes before storing them.

Using Multipart Requests

Pass a messages.MessageSend, rest.ExecuteWebhookParams, or endpoint parameter as the payload. Include messages.AttachmentSend or metadata in the JSON payload as required by the endpoint, and include the corresponding File values in the same order. Interaction callbacks use RequestMultipartNoAuth or the typed CreateInteractionResponseWithFiles method.

Common Patterns

For edits, send every attachment that should remain. Discord removes omitted attachments from the message. Validate each byte slice before building files; unknown premium tiers use the base 8 MiB limit. Use named file fields only when the endpoint documentation requires them.

Best Practices

Bound upload size before reading untrusted files into memory. Use a fresh reader or FileFromPath for custom callers that may reuse a File. Keep filenames safe and avoid leaking local paths. Use context cancellation for large uploads and retries.

Common Mistakes

AttachmentMetadata does not upload bytes. Its IDs are multipart indexes, not Discord message snowflakes. A File reader can be consumed by a request; do not assume it can be read again outside REST. RequestMultipartForm is not the same as RequestMultipart, and sticker creation may require the named file field.

API Walkthrough

The exported API is File, FileFromPath, FileFromBytes, AttachmentMetadata, ValidateFilesSize, the four max-size constants, AttachmentBuilder, NewAttachmentBuilder, NewAttachmentBuilderFromBytes, SetName, Build, RequestMultipart, RequestMultipartNoAuth, RequestMultipartForm, and RequestMultipartFormNamedFile.

Examples

The Quick Start program is complete and runnable without HTTP. Request wiring and authentication are covered in requests.md.

Released under the Apache License 2.0.