{"id":16175893,"url":"https://github.com/ker0olos/aws-lambda-discord-bot","last_synced_at":"2026-03-08T00:32:28.189Z","repository":{"id":125808556,"uuid":"407918045","full_name":"ker0olos/aws-lambda-discord-bot","owner":"ker0olos","description":"Developing a Discord Bot on AWS Lambda and Python","archived":false,"fork":false,"pushed_at":"2024-08-04T20:35:36.000Z","size":32,"stargazers_count":44,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-06-12T20:03:53.780Z","etag":null,"topics":["aws-lambda","discord","discord-bot","discord-interactions","python","serverless"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ker0olos.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-09-18T16:58:42.000Z","updated_at":"2025-04-01T15:20:11.000Z","dependencies_parsed_at":null,"dependency_job_id":"101ab016-ccdd-4f5b-ac5f-9eec94e5fa89","html_url":"https://github.com/ker0olos/aws-lambda-discord-bot","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ker0olos/aws-lambda-discord-bot","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ker0olos%2Faws-lambda-discord-bot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ker0olos%2Faws-lambda-discord-bot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ker0olos%2Faws-lambda-discord-bot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ker0olos%2Faws-lambda-discord-bot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ker0olos","download_url":"https://codeload.github.com/ker0olos/aws-lambda-discord-bot/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ker0olos%2Faws-lambda-discord-bot/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30238879,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-08T00:30:53.000Z","status":"ssl_error","status_checked_at":"2026-03-08T00:30:44.061Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws-lambda","discord","discord-bot","discord-interactions","python","serverless"],"created_at":"2024-10-10T04:46:40.883Z","updated_at":"2026-03-08T00:32:28.158Z","avatar_url":"https://github.com/ker0olos.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"Previously, this wasn't possible.\n\nBut in 2020, Discord introduced two new features: Slash Commands and Interactions Endpoints.\n\nHere's a very straightforward guide to getting you started.\n\n\u003cbr\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://discord.com/assets/a660b11b63a95e932719346ff67ea60f.png\" alt=\"Slash Commands\"\u003e\u003c/img\u003e\n\u003c/p\u003e\n\n\u003ch6 align=\"center\"\u003e\u003ci\u003e(This is what Slash Commands look like)\u003c/i\u003e\u003c/h6\u003e\n\n\u003cbr\u003e\n\n### 1. Setting up the Bot and the First Command\n\nIf you don't have one already, go to [Discord's Developer Portal](https://discord.com/developers/applications) and create a new app.\n\n\u003cbr\u003e\n\nUse this URL after repleacing `{APP_ID}` with your own and use it to invite the bot into your server.\n\n```https://discord.com/oauth2/authorize?client_id={APP_ID}\u0026scope=applications.commands```\n\n\u003cbr\u003e\n\nNow, you need to register a new slash command to test the bot.  \n\nDiscord can't automatticly figure out what commands you app has, so you need to tell it each command available.  \n\nThere is no UI for that, it's currently only possible via a HTTP endpoint.\n\n```python\nimport requests\n\nAPP_ID = \"APP_ID\"\nSERVER_ID = \"SERVER_ID\"\nBOT_TOKEN = \"BOT_TOKEN\"\n\n# global commands are cached and only update every hour\n# url = f'https://discord.com/api/v10/applications/{APP_ID}/commands'\n\n# while server commands update instantly\n# they're much better for testing\nurl = f'https://discord.com/api/v10/applications/{APP_ID}/guilds/{SERVER_ID}/commands'\n\njson = [\n  {\n    'name': 'bleb',\n    'description': 'Test command.',\n    'options': []\n  }\n]\n\nresponse = requests.put(url, headers={\n  'Authorization': f'Bot {BOT_TOKEN}'\n}, json=json)\n\nprint(response.json())\n```\n\n\u003e **Note** This is a script you keep to yourself and run locally every time you want to create a new command or update your existing ones.\n\n\u003cbr\u003e\n\n- `APP_ID` is visible through **General Information** in your app dev portal.  \n- `BOT_TOKEN` is in **Bot** \n- To get your `SERVER_ID`, go to your discord client and enable **Developer Mode** in the **Advanced** Settings,\nthen go to the server and right-click on the sever's name in the top-left. And now should see a new entry in the context menu called **Copy Server ID**.\n\nIf you are using server commands *(You should for testing commands and for private bots)*. before running the script, make sure that the bot was alreay added to your server.\n\nYou should now be able to go the the server type `/` in the chat and see the command you' created, if not then something is wrong, scroll up amd try again until you can.\n\nCommands can accept string and number inputs, But to learn more about setting up commands, check the offical docs or search for a more specific guide. \u003chttps://discord.com/developers/docs/interactions/application-commands#application-command-object\u003e \n\n### 2. The AWS Lambda Function\n\nGo to your console and `Create Function`.\n\nI'm using Python for this guide, but you can use whatever you like if you know how to do the same things the following script does in your language.\n\nNow `Add trigger` and select `API Gateway` *(The settings won't matter you can go with the defaults)*.\n\nLook for the `API endpoint`. It should look like this `https://a7ar46xyz.execute-api.eu-west-3.amazonaws.com/default/my-function`\n\nCopied it, go back to `General Information` in your discord dev portal. Find `Interactions Endpoint URL` and paste the endpoint there. Click **Save**... and you will get an error.\n\nThere are [steps](https://discord.com/developers/docs/interactions/receiving-and-responding#receiving-an-interaction) necessary for discord to accept the endpoint.\n\n  1. Your endpoint must be prepared to ACK a `PING` message\n  2. Your endpoint must be set up to properly handle signature headers\n\nYou should be familier with deploying Lambda functions. if not go read [Deploy Python Lambda functions with .zip file archives](https://docs.aws.amazon.com/lambda/latest/dg/python-package.html). Specifically **Deployment package with dependencies**\n\nYou need a security library for the handle signature headers part.\n\nFollowing the guild. Run `pip install --target ./package pynacl` \n\nAnd finally, here the acutual lambda function.\n\n```python\nimport json\n\nfrom nacl.signing import VerifyKey\nfrom nacl.exceptions import BadSignatureError\n\nPUBLIC_KEY = 'YOUR_APP_PUBLIC_KEY_HERE'\n\ndef lambda_handler(event, context):\n  try:\n    body = json.loads(event['body'])\n        \n    signature = event['headers']['x-signature-ed25519']\n    timestamp = event['headers']['x-signature-timestamp']\n\n    # validate the interaction\n\n    verify_key = VerifyKey(bytes.fromhex(PUBLIC_KEY))\n\n    message = timestamp + event['body']\n    \n    try:\n      verify_key.verify(message.encode(), signature=bytes.fromhex(signature))\n    except BadSignatureError:\n      return {\n        'statusCode': 401,\n        'body': json.dumps('invalid request signature')\n      }\n    \n    # handle the interaction\n\n    t = body['type']\n\n    if t == 1:\n      return {\n        'statusCode': 200,\n        'body': json.dumps({\n          'type': 1\n        })\n      }\n    elif t == 2:\n      return command_handler(body)\n    else:\n      return {\n        'statusCode': 400,\n        'body': json.dumps('unhandled request type')\n      }\n  except:\n    raise\n\ndef command_handler(body):\n  command = body['data']['name']\n\n  if command == 'bleb':\n    return {\n      'statusCode': 200,\n      'headers' : {'Content-Type': 'application/json'},\n      'body': json.dumps({\n        'type': 4,\n        'data': {\n          'content': 'Hello, World.',\n        }\n      })\n    }\n  else:\n    return {\n      'statusCode': 400,\n      'body': json.dumps('unhandled command')\n    }\n\n```\n\nThis handles discord security requirements for you.\nBut if you wan't to understand it more:\n  1. Discord's [Security And Authorization](https://discord.com/developers/docs/interactions/receiving-and-responding#security-and-authorization)\n  2. Gerald McAlister's [Building a Serverless Discord Bot](https://gemisis.medium.com/building-a-serverless-discord-bot-on-aws-5dc7d972c9c6)\n  \nReplace `YOUR_APP_PUBLIC_KEY_HERE` with your app public key also visible through **General Information** \n\nThen deploy the script to Lambda **(don't forget about packing the security library)**\n\n---\n\nGo back to the dev portal and try to save the endpoint again, This time it should save without any errors.\n  - If it saves correctly, go to your discord server and type `/bleb` in chat. It should work and respond with `Hello, World.`.\n  - If not then something is wrong, check the steps again until you get it working.\n\nTo add more command to the lambda function edit `command_handler(body)`.\n\n---\n\nYou **must** respond to any request within **3 seconds** (There’s no way to increase this time).\nIf your request will take longer than 3 seconds (i.e. an LLM query), you will need to acknowledge the user's interaction.\n\nOne method of acknowledging a request is to send back a message to user (like \"Loading..\") and edit the response later. Discord makes this possible by assigning an Interactions ID and an Interactions token to each interaction that expires after 15 minutes. We will be using this to our advantage.\n\nHere is a function to immediately send something back to the user\n```python\ndef send(message, id, token):\n    url = f\"https://discord.com/api/interactions/{id}/{token}/callback\"\n\n    callback_data = {\n        \"type\": 4,\n        \"data\": {\n            \"content\": message\n        }\n    }\n    response = requests.post(url, json=callback_data)\n```\n\nIn your `command_handler`, use the function as such.\n\n```python\nmessage = \"Loading..\" # Loading message that you'd want to send back to the user.\nsend(message, body['id'], body['token'])\n```\n\nTo update the message after sending out an acknowledgement, use the `update` function below\n\n```python\ndef update(message, token, app_id):\n    url = f\"https://discord.com/api/webhooks/{app_id}/{token}/messages/@original\"\n\n    # JSON data to send with the request\n    data = {\n        \"content\": message\n    }\n\n    # Send the PATCH request\n    response = requests.patch(url, json=data)\n```\n\nIn your `command_handler`, use the function as such\n\n```python\nupdated_message = \"...\"\nDISCORD_BOT_ID = \"....\" # Please set your discord bot ID as an environmental variable or manually\n\nupdate(updated_message, body['token'], DISCORD_BOT_ID)\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fker0olos%2Faws-lambda-discord-bot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fker0olos%2Faws-lambda-discord-bot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fker0olos%2Faws-lambda-discord-bot/lists"}