Documentation Index
Fetch the complete documentation index at: https://mintlify.com/disgoorg/disgo/llms.txt
Use this file to discover all available pages before exploring further.
The httpserver package provides an HTTP server for receiving Discord interactions through outgoing webhooks, with built-in request verification and interaction handling.
Installation
import "github.com/disgoorg/disgo/httpserver"
Server
New
Creates a new HTTP server for handling Discord interactions.
func New(
publicKey string,
eventHandlerFunc EventHandlerFunc,
opts ...ConfigOpt
) (Server, error)
Your application’s public key from the Discord Developer Portal (hex-encoded)
Function to handle incoming interactions
Optional configuration options
Server interface
type Server interface {
// Start starts the HTTP server
Start()
// Close closes the HTTP server
Close(ctx context.Context)
}
Event handling
EventHandlerFunc
Function signature for handling interaction events.
type EventHandlerFunc func(responseFunc RespondFunc, event EventInteractionCreate)
Function to call to respond to the interaction
event
EventInteractionCreate
required
The interaction event data
RespondFunc
Function signature for responding to interactions.
type RespondFunc func(response discord.InteractionResponse) error
response
discord.InteractionResponse
required
The interaction response to send
EventInteractionCreate
Represents an incoming interaction event.
type EventInteractionCreate struct {
discord.Interaction
}
The underlying Discord interaction (can be any interaction type)
Request verification
VerifyRequest
Verifies that a request is from Discord using Ed25519 signature verification.
func VerifyRequest(verifier Verifier, r *http.Request, key PublicKey) bool
The verifier implementation to use
The HTTP request to verify
Your application’s public key (decoded from hex)
Returns true if the request signature is valid, false otherwise.
Verifier interface
type Verifier interface {
// Verify verifies the signature of the message using the public key
Verify(publicKey PublicKey, message []byte, sig []byte) bool
// SignatureSize is the size, in bytes, of signatures
SignatureSize() int
}
DefaultVerifier
The default Ed25519 signature verifier.
type DefaultVerifier struct{}
func (DefaultVerifier) Verify(publicKey PublicKey, message []byte, sig []byte) bool
func (DefaultVerifier) SignatureSize() int
PublicKey
Type alias for Ed25519 public keys.
Handler function
HandleInteraction
Creates an http.HandlerFunc for handling Discord interactions.
func HandleInteraction(
verifier Verifier,
publicKey PublicKey,
logger *slog.Logger,
handleFunc EventHandlerFunc
) http.HandlerFunc
Your application’s public key
Logger for request/response logging
Function to handle verified interactions
This function automatically:
- Verifies the request signature
- Parses the interaction payload
- Handles interaction timeouts (3 seconds)
- Sends the response back to Discord
Configuration
WithLogger
Sets a custom logger.
func WithLogger(logger *slog.Logger) ConfigOpt
WithHTTPServer
Sets a custom http.Server instance.
func WithHTTPServer(httpServer *http.Server) ConfigOpt
WithServeMux
Sets a custom http.ServeMux.
func WithServeMux(serveMux *http.ServeMux) ConfigOpt
WithURL
Sets the URL path for the interaction endpoint.
func WithURL(url string) ConfigOpt
The endpoint path (default: “/interactions/callback”)
WithAddress
Sets the server address.
func WithAddress(address string) ConfigOpt
The address to listen on (default: “:80”)
WithTLS
Enables TLS with certificate and key files.
func WithTLS(certFile string, keyFile string) ConfigOpt
Path to the TLS certificate file
WithVerifier
Sets a custom signature verifier.
func WithVerifier(verifier Verifier) ConfigOpt
Example usage
Basic server
package main
import (
"context"
"log"
"log/slog"
"os"
"os/signal"
"syscall"
"github.com/disgoorg/disgo/discord"
"github.com/disgoorg/disgo/httpserver"
)
func main() {
publicKey := os.Getenv("PUBLIC_KEY")
server, err := httpserver.New(publicKey, handleInteraction,
httpserver.WithAddress(":8080"),
httpserver.WithURL("/interactions"),
httpserver.WithLogger(slog.Default()),
)
if err != nil {
log.Fatal("failed to create server: ", err)
}
server.Start()
log.Println("Server started on :8080")
s := make(chan os.Signal, 1)
signal.Notify(s, syscall.SIGINT, syscall.SIGTERM)
<-s
server.Close(context.TODO())
}
func handleInteraction(respond httpserver.RespondFunc, event httpserver.EventInteractionCreate) {
switch data := event.Data.(type) {
case discord.SlashCommandInteractionData:
err := respond(discord.InteractionResponse{
Type: discord.InteractionResponseTypeCreateMessage,
Data: discord.MessageCreate{
Content: "Hello from DisGo HTTP server!",
},
})
if err != nil {
log.Println("failed to respond:", err)
}
}
}
With TLS
server, err := httpserver.New(publicKey, handleInteraction,
httpserver.WithAddress(":443"),
httpserver.WithTLS("cert.pem", "key.pem"),
)
if err != nil {
log.Fatal(err)
}
server.Start()
Handling different interaction types
func handleInteraction(respond httpserver.RespondFunc, event httpserver.EventInteractionCreate) {
switch data := event.Data.(type) {
case discord.SlashCommandInteractionData:
handleSlashCommand(respond, event, data)
case discord.ComponentInteractionData:
handleComponent(respond, event, data)
case discord.ModalSubmitInteractionData:
handleModalSubmit(respond, event, data)
}
}
func handleSlashCommand(
respond httpserver.RespondFunc,
event httpserver.EventInteractionCreate,
data discord.SlashCommandInteractionData,
) {
err := respond(discord.InteractionResponse{
Type: discord.InteractionResponseTypeCreateMessage,
Data: discord.MessageCreate{
Content: "Command received: " + data.CommandName(),
},
})
if err != nil {
log.Println("failed to respond:", err)
}
}
func handleComponent(
respond httpserver.RespondFunc,
event httpserver.EventInteractionCreate,
data discord.ComponentInteractionData,
) {
err := respond(discord.InteractionResponse{
Type: discord.InteractionResponseTypeUpdateMessage,
Data: discord.MessageUpdate{
Content: discord.NewNullablePtr("Button clicked!"),
},
})
if err != nil {
log.Println("failed to respond:", err)
}
}
func handleModalSubmit(
respond httpserver.RespondFunc,
event httpserver.EventInteractionCreate,
data discord.ModalSubmitInteractionData,
) {
err := respond(discord.InteractionResponse{
Type: discord.InteractionResponseTypeCreateMessage,
Data: discord.MessageCreate{
Content: "Modal submitted!",
Flags: discord.MessageFlagEphemeral,
},
})
if err != nil {
log.Println("failed to respond:", err)
}
}
Deferred responses
func handleInteraction(respond httpserver.RespondFunc, event httpserver.EventInteractionCreate) {
// Acknowledge the interaction immediately
err := respond(discord.InteractionResponse{
Type: discord.InteractionResponseTypeDeferredCreateMessage,
})
if err != nil {
log.Println("failed to defer:", err)
return
}
// Process the command in the background
go func() {
// Do some long-running work...
time.Sleep(5 * time.Second)
// Follow up with the actual response using the REST API
// You'll need to use the rest client to edit the original response
}()
}
Security notes
- Always verify requests using the provided verification mechanism
- Keep your public key secure and never commit it to version control
- Use environment variables or secure configuration management for sensitive data
- The server automatically rejects requests with invalid signatures
- Interactions must be responded to within 3 seconds or they will timeout