-
Notifications
You must be signed in to change notification settings - Fork 184
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add discord bot example #1027
base: main
Are you sure you want to change the base?
Add discord bot example #1027
Conversation
🚀 The docs preview is ready! Check it out here: https://modal-labs-examples--frontend-preview-876e0ff.modal.run |
🚀 The docs preview is ready! Check it out here: https://modal-labs-examples--frontend-preview-f678863.modal.run |
🚀 The docs preview is ready! Check it out here: https://modal-labs-examples--frontend-preview-df4c7a6.modal.run |
🚀 The docs preview is ready! Check it out here: https://modal-labs-examples--frontend-preview-5fbf2b4.modal.run |
🚀 The docs preview is ready! Check it out here: https://modal-labs-examples--frontend-preview-2a88f11.modal.run |
🚀 The docs preview is ready! Check it out here: https://modal-labs-examples--frontend-preview-f4dc284.modal.run |
🚀 The docs preview is ready! Check it out here: https://modal-labs-examples--frontend-preview-c594693.modal.run |
🚀 The docs preview is ready! Check it out here: https://modal-labs-examples--frontend-preview-65995a4.modal.run |
🚀 The docs preview is ready! Check it out here: https://modal-labs-examples--frontend-preview-d021a61.modal.run |
🚀 The docs preview is ready! Check it out here: https://modal-labs-examples--frontend-preview-51ed462.modal.run |
🚀 The docs preview is ready! Check it out here: https://modal-labs-examples--frontend-preview-ea5459b.modal.run |
🚀 The docs preview is ready! Check it out here: https://modal-labs-examples--frontend-preview-db54a17.modal.run |
🚀 The docs preview is ready! Check it out here: https://modal-labs-examples--frontend-preview-3654188.modal.run |
🚀 The docs preview is ready! Check it out here: https://modal-labs-examples--frontend-preview-d8a4903.modal.run |
|
||
# # Serve a Discord Bot on Modal | ||
|
||
# (quick links: [try it out on Discord](https://discord.gg/nR96BxPu)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's a good idea to host an example, but we should take care to:
- Make it a Modal-branded Discord server.
- Restrict all permissions for members except running slash commands.
@@ -0,0 +1,230 @@ | |||
# --- | |||
# lambda-test: false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not test this?
Ideally, we QA this two ways:
- Set
deploy: true
so that the example is deployed continuously and include a link to the hosted version so that users can try it and complain to us when it's broken - Use
modal run
in Lambda testing to check that the example is working (either the full deployed version or some subset of the logic).
It's a bit tough to check that the whole example application is working because we are not Discord (the requests have to be signed using Discord's private key and the responses are sent to a URL defined by an interaction token from Discord).
So I would maybe advocate for splitting up the logic here -- the get_weather_forecast_for_city
function handles talking to the external API AND sending back to Discord. If it just talked to the external API, we could wrap it in another function that handles Discord integration.
Decomposing it also provides an opportunity to explain what's going on in the logic -- why do we have these interaction tokens and application IDs? What's with session.patch
(that's a rare HTTP verb)? This all comes from the Discord docs, to which we should link.
# 3. [Create a custom Modal secret](https://modal.com/docs/guide/secrets) for your Discord bot. | ||
# On Modal's secret creation page, select 'Discord'. Copy your Discord application’s | ||
# **Public Key** (in **General Information**) and paste the value of the public key | ||
# as the value of the `DISCORD_PUBLIC_KEY` environment variable. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is actually pretty weird -- the public key is not secret nor is it really ours. It's owned by Discord and they use it to authenticate with us. It is specific to our app, but it's actually public information.
Leaking it is harmless on its own, because Discord is the entity that takes actions using it. An adversary would need to compromise our secrets or Discord's in order to trigger Discord to use the key.
Really, we should put the Secrets used to register the slash command into Modal, along with the logic, and then this public key can come along for the ride.
See this code I wrote for Full Stack Deep Learning. The whole thing is a lot cleaner than the code in Boombot.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the advantage of having the ability to register a slash command as a modal function? Imo if we do that we'd have to get the user to run this separate function before they run anything else on the app
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Creating a slash command in Modal requires secret information, which you can put in the Secret. It's a better demonstration of what Secrets are for. It's a bit weird that we're using it for configuration alone.
- Including the setup in the code itself makes the example more self-contained and less error-prone (are you confident that snippet runs in all shells?). You can add a call to that Function in the local entrypoint, you just need to make it idempotent (e.g. with a
force
oroverwrite
flag, as in the linked code here).
) | ||
|
||
@web_app.post("/get_weather_forecast") | ||
async def get_weather_forecast_api(request: Request): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The names on the functions in this are a bit messy. Could we clean them up? Like this could just be get_weather_forecast
or just get_weather
, as could the function above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, we can't shadow it as-is because we later need a handle to call .spawn
on within this scope.
I think we might be able to remove that constraint if we change the composition here -- but it might just end up uglier. In that case, can only get slightly cleaner names.
|
||
@app.function(image=image) | ||
async def get_weather_forecast_for_city( | ||
city: str, interaction_token, application_id |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function is doing a bit too much -- figuring out the Discord URL to talk to, hitting a different external API, and then submitting the request. That makes it harder to write about and harder to effectively name.
Co-authored-by: Charles Frye <[email protected]>
Co-authored-by: Charles Frye <[email protected]>
Co-authored-by: Charles Frye <[email protected]>
🚀 The docs preview is ready! Check it out here: https://modal-labs-examples--frontend-preview-fcf035c.modal.run |
🚀 The docs preview is ready! Check it out here: https://modal-labs-examples--frontend-preview-1834262.modal.run |
🚀 The docs preview is ready! Check it out here: https://modal-labs-examples--frontend-preview-a90ca64.modal.run |
Part of initiative to split out boombot into 2 separate examples, one for discord and one for musicgen.
In this example I make a discord bot that just takes a city as input and returns the weather forecast for the next few days
Type of Change
Checklist
lambda-test: false
is added to example frontmatter (---
)latest
python_version
for the base image, if it is used~=x.y.z
or==x.y
version < 1
are pinned to patch version,==0.y.z
Outside contributors
You're great! Thanks for your contribution.