What You’ll Learn
- Setting up Discord interactions in Google Cloud Functions
- Manual signature verification with
verifyKey - Handling raw request bodies in cloud functions
- Working with serverless constraints
- Deploying to Google Cloud Platform
Prerequisites
Before you begin, make sure you have:
- A Google Cloud Platform account
- Google Cloud SDK installed
- A Discord application with a public key
- Node.js 16 or higher
Complete Example
index.js
Key Concepts
Manual Signature Verification
Unlike Express middleware, Cloud Functions require manual verification:Why manual verification?
Why manual verification?
Cloud Functions don’t use Express-style middleware in the traditional sense. Instead of using
verifyKeyMiddleware, we:- Extract the signature headers manually using
req.get() - Access the raw request body via
req.rawBody - Call
verifyKey()directly to verify the request - Return a 401 status if verification fails
Request Handling
The function handles both PING and command interactions:Project Structure
Create the following files:package.json
.env.yaml
Deployment
Using gcloud CLI
Deploy your function to Google Cloud:The
--allow-unauthenticated flag is necessary because Discord needs to send HTTP requests to your function. Security is handled through signature verification.Deployment Options
Get Your Function URL
After deployment, get your function’s URL:Configure Discord
In your Discord application settings:- Go to your application in the Discord Developer Portal
- Navigate to “General Information”
- Set the Interactions Endpoint URL to your Cloud Function URL
- Discord will send a test PING request to verify the endpoint
Make sure your function is deployed and responding to requests before configuring Discord. The verification will fail if your function isn’t accessible.
Advanced Example
Here’s an enhanced version with better error handling and logging:index.js
Monitoring and Logs
View your function logs:Cost Considerations
Google Cloud Functions pricing is based on:- Number of invocations
- Compute time
- Memory allocated
- Network egress
The free tier includes:
- 2 million invocations per month
- 400,000 GB-seconds of compute time
- 200,000 GHz-seconds of compute time
- 5 GB of network egress
Serverless Best Practices
Response Time
Response Time
Discord requires responses within 3 seconds. For long-running operations:
Cold Starts
Cold Starts
Cloud Functions can have cold start latency. To minimize this:
- Keep your function code small
- Minimize dependencies
- Use minimum memory allocation (256MB is usually sufficient)
- Consider using Cloud Run for persistent containers if cold starts are an issue
Environment Variables
Environment Variables
Always use environment variables for sensitive data:
- Set them during deployment with
--env-vars-file - Or set them individually with
--set-env-vars KEY=value - Update them without redeploying using
gcloud functions deploy --update-env-vars
Updating Your Function
To update your function after making changes:Troubleshooting
401 Bad request signature
401 Bad request signature
- Verify your
CLIENT_PUBLIC_KEYis correct - Check that you’re using
req.rawBody(notreq.body) for verification - Ensure headers are being read correctly with
req.get()
Function timeout
Function timeout
- Increase timeout with
--timeoutflag (max 540s for HTTP functions) - Use deferred responses for long operations
- Consider moving to Cloud Run for longer timeouts
Discord endpoint verification fails
Discord endpoint verification fails
- Make sure your function is deployed and accessible
- Test your function URL in a browser or with curl
- Check function logs for errors
- Verify your function responds to PING interactions
Next Steps
- Learn about Express.js setup for local development
- Explore modal interactions for user input
- Check out Next.js API routes for another serverless option
- Deploy to AWS Lambda or Azure Functions using similar patterns