This repository contains serverless AWS Lambda functions that automate various tasks for Asmbly Makerspace. All infrastructure is managed as code using the AWS Serverless Application Model (SAM).
- What's in this Repository?
- Core Architecture: API Gateway & Custom Domain
- Core Services
- How It's Managed (The Important Part!)
- Supporting Documentation
- Repository Structure Overview
This repository contains several independent services that automate various tasks for Asmbly. Each service is implemented as a serverless AWS Lambda function and managed via the AWS Serverless Application Model (SAM).
This project uses a single AWS API Gateway (FacilitiesApi in template.yaml) to manage and route all incoming HTTP requests to the correct Lambda functions.
While API Gateway provides a temporary .execute-api URL for development, the production environment uses a stable, permanent custom domain:
https://facilities.asmbly.org
This entire setup is managed as code in the root template.yaml file and is only created when deploying to the prod environment.
- ACM Certificate (
FacilitiesCertificate): An AWS Certificate Manager (ACM) resource provides the free SSL/TLS certificate. - API Gateway Custom Domain (
FacilitiesApiCustomDomain): This resource links the certificate to API Gateway. - Route 53 Alias (
FacilitiesDnsRecord): AnArecord in theasmbly.orghosted zone points the "pretty" URL to the API Gateway. - API Mapping (
FacilitiesApiMapping): This resource connects the custom domain to theprodstage of yourFacilitiesApi.
This IaC (Infrastructure as Code) approach makes the production environment robust, self-healing, and easy to replicate.
- Stable Endpoint: All third-party webhooks (from Slack, ClickUp, Smartwaiver, etc.) are pointed to this single, permanent URL (e.g.,
https://facilities.asmbly.org/slack/events). - Simplified Deployments: This setup makes the deployment pipeline much more reliable. We no longer need the GitHub Action to dynamically update webhook URLs on every deployment. The custom URL never changes.
The project is organized into several functional areas, with a core infrastructure service for routing Slack events.
These services provide core functionality used by other parts of the system.
- Slack Event Router (
SlackEventSubscriptionsRouterFunction)- What it does: Acts as the single entry point for all Slack
reaction_addedevents. It inspects the event and forwards it to the correct handler function based on the channel where the reaction occurred. - How it's triggered: An HTTP
POSTfrom a Slack Event Subscription. - Webhook URL:
https://facilities.asmbly.org/slack/events - Config Location: Slack Bot - Maintenance Bot -> Event Subscriptions
- What it does: Acts as the single entry point for all Slack
- Kiln Drop-Off Viewer (
KilnOpsDropoffRecentEntriesViewer)- What it does: Creates a public web page that displays recent Kiln Drop Off entries. This lets members see their confirmation of submitting a kiln form easily.
- How it's triggered: An HTTP
GETrequest. - Webhook URL:
https://facilities.asmbly.org/KilnOpsDropoffRecentEntriesViewer - Config Location: This URL is used as the "Redirect URL" in the ClickUp Form settings for "Ceramics - Drop Off Requests".
These services automate administrative tasks, such as member data synchronization.
- New Waiver Completed Handler (
NewWaiverCompletedFunction)- What it does: Receives a webhook from Smartwaiver when a new waiver is signed. It parses the member's email and signature date, then updates the
WaverDatecustom field in the corresponding NeonCRM account. - How it's triggered: An HTTP
POSTfrom a Smartwaiver webhook. - Webhook URL:
https://facilities.asmbly.org/waiver/new - Config Location: "new waiver signed" at
https://app.cleverwaiver.com/v2profile/webhook
- What it does: Receives a webhook from Smartwaiver when a new waiver is signed. It parses the member's email and signature date, then updates the
These services automate tasks related to facilities management, problem reporting, and purchasing.
- PM Reminder Bot (
PMReminderBot)- What it does: Automatically fetches upcoming and overdue maintenance tasks from ClickUp and posts them as weekly reminders in the relevant Slack channels.
- How it's triggered: A scheduled cron job (via Amazon EventBridge), defined in
facilities.yaml.
- Slack Reorder Item (
FacilitiesSlackPurchaseReorderFunction)- What it does: Handles the
/reorderslash command, which opens an interactive modal in Slack. Users can filter a list of master items, select one, and submit a new purchase request to ClickUp. The same function also handles all in-modal interactions (filtering, submission). - How it's triggered: An HTTP
POSTfrom a Slack slash command and subsequentblock_actionsorview_submissionevents. - Webhook URL:
https://facilities.asmbly.org/SlackSlashReorder - Config Location: Slack Bot - Maintenance Bot -> Slash Commands (
/reorder) and Interactivity & Shortcuts.
- What it does: Handles the
- Problem Report Reaction Handler (
FacilitiesSlackProblemReportReactionWebhook)- What it does: Allows facilities team members to update the status of a problem report task in ClickUp by adding an emoji reaction (e.g.,
:eyes:,:white_check_mark:) to a Slack message that contains the task link. - How it's triggered: Asynchronously invoked by the Slack Event Router when a reaction is added in a monitored channel.
- What it does: Allows facilities team members to update the status of a problem report task in ClickUp by adding an emoji reaction (e.g.,
- Purchase Request Reaction Handler (
FacilitiesSlackPurchaseReactionWebhook)- What it does: Allows facilities team members to update the status of a purchase request task in ClickUp by adding an emoji reaction (e.g.,
:truck:,:house:) to a Slack message that contains the task link. - How it's triggered: Asynchronously invoked by the Slack Event Router when a reaction is added in a monitored channel.
- What it does: Allows facilities team members to update the status of a purchase request task in ClickUp by adding an emoji reaction (e.g.,
- New Purchase Request Handler (
NewPurchaseRequestReceivedFunction)- What it does: Listens for new purchase request tasks created in ClickUp. It then posts a detailed notification to a Slack channel and updates the original ClickUp task with a permalink to the Slack message.
- How it's triggered: An HTTP
POSTfrom a ClickUp webhook. - Webhook URL:
https://facilities.asmbly.org/purchase-request/new - Config Location: ClickUp Webhooks (Facilities - Purchase Requests) -> Automations -> "New Purchase Request" Webhook.
- New Problem Report Handler (
NewProblemReportRequestReceivedFunction)- What it does: Receives a webhook from a Google Form when a new problem report is submitted. It creates a task in ClickUp, posts a notification to Slack, and optionally creates a Discourse forum topic. It then updates the ClickUp task with links to the Slack and Discourse posts.
- How it's triggered: An HTTP
POSTfrom a Google Apps Script attached to the Problem Report Google Form. - Webhook URL:
https://facilities.asmbly.org/problem-report/new - Config Location: The webhook URL is configured in the Google Apps Script attached to the "Problem Report" Google Form.
This project uses the AWS Serverless Application Model (SAM). This means:
template.yamlis the boss. This single file is the source of truth. It defines every piece of the cloud infrastructure: the Lambda functions, the API Gateway, the scheduled triggers, IAM roles, environment variables, the custom domain, the SSL certificate, and the DNS records.- Do not make changes in the AWS Console. Any manual changes made directly in the AWS console (like changing an environment variable or a Route 53 record) will be overwritten and destroyed the next time the production pipeline runs.
- All changes must go through the
.yamltemplate files. To change a function's timeout, add a new API path, or modify a trigger, you must edit the appropriate.yamlfile and redeploy.
- CONTRIBUTING.md - How to contribute to the hub and add new functions.
- Deploying.md - How to deploy to the hub.
template.yaml: Defines all AWS resources. Start here to understand the architecture./templates: Contains the nested SAM templates for each service (facilities, ceramics, etc.)./functions: Contains a separate folder for each Lambda function's Python code./layers: Holds shared code or dependencies. Currently used for therequestsPython library.