This repository provides an AWS Lambda to:
- Send a Slack message when a GitHub Projects (V2) item changes statuses
- Watch issue comments for a
/status
command to schedule a status change on a specific date
Roughly, the following steps are performed when a webhook event is received:
-
If the event was a
projects_v2_item
event:- If the event matches the watched project/field, query the GitHub API for information about the item
- Construct and send a Slack message to a specified channel with information from above steps
-
If the event was an
issue_comment
event:- Check for the first word being
/status
, skipping the event otherwise - Check for the next word being
cancel
, removing any already-scheduled moves from DynamoDB - Parse the remaining words as
{status} on {date}
or{status} in {number} {interval}
, storing the corresponding status move in DynamoDB
- Check for the first word being
This is built upon the following packages, see those repositories for more in-depth information:
Important: this is still in extremely early development, and the below setup steps are mostly to document my own deployment of this Lambda rather than be a guarantee of how to set this up from scratch.
- Copy the directory
Example secrets
toSecrets
- Create a GitHub App in your account (alternatively use an existing app you have already created)
- The only values you need to fill in are the app name and URL (which can be your GitHub profile URL), and you can uncheck
Active
underWebhook
(you'll come back and fill this in once you have a URL) - Under
Repository permissions
, thenIssues
, grantRead and write
permissions - Under
Organization permissions
, thenProjects
, grantRead and write
permissions
- The only values you need to fill in are the app name and URL (which can be your GitHub profile URL), and you can uncheck
- After successful creation, copy the
App ID
value and replace the example value for the keyappId
inSecrets/github-credentials.json
- At the bottom of the same page, under
Private keys
, generate a private key for your app - Open the generated and downloaded
.pem
file in a text editor, copy the entire contents, and replace the example value for the keyprivateKey
inSecrets/github-credentials.json
- Important: make sure you replace all new lines in the
.pem
with\n
as in the example value
- Important: make sure you replace all new lines in the
- Create a new example project (alternatively reuse an existing project you have already created)
- Important: make note of the project number (
{number
} inhttps://github.com/orgs/{organization}/projects/{number}
from the project's URL)
- Important: make note of the project number (
- Create a new repository to contain issues for the project (alternatively reuse an existing repository you have already created)
- Copy the name of your new repository (in
{Username}/{Repository}
format) and replace the example value for the keygithubRepository
inSecrets/lambda-configuration.json
- Install your new app on the account containing the new project, granting access to the issue-containing repository
- Install and set up the GitHub CLI tool
- On macOS with Homebrew installed, you can just run:
brew install gh
gh auth login
- On macOS with Homebrew installed, you can just run:
- Query the GraphQL API for the required project and field IDs to watch (making sure to replace example values):
gh api graphql --field organizationLogin='{Your organization username}' --field projectNumber='{Your project number}' --raw-field query=' query($organizationLogin: String!, $projectNumber: Int!) { organization(login: $organizationLogin) { projectV2(number: $projectNumber) { id field(name: "Status") { ... on ProjectV2SingleSelectField { id } } } } } '
- Copy the value at
data.organization.projectV2.id
and replace the example value for the keygithubProjectId
inSecrets/lambda-configuration.json
- Copy the
data.organization.projectV2.field.id
, then replace the example value for the keygithubProjectFieldId
inSecrets/lambda-configuration.json
- Create an HMAC secret for your webhook, copy it, and replace the example value for the key
webhookSecret
inSecrets/github-credentials.json
- An example tool has been provided in this package to generate a sufficiently secure secret, simply run:
swift run GenerateHmacSecret
and copy the resulting output string
- An example tool has been provided in this package to generate a sufficiently secure secret, simply run:
- Create a Slack App for your workspace (alternatively use an existing app you have already created and installed)
- Add the
chat.write
bot scope under OAuth & Permissions - Install the app to your workspace
- Copy the app's Bot Token from the OAuth & Permissions page and replace the example value for the key
botToken
inSecrets/slack-credentials.json
- Invite the bot user into the channel you wish to post messages to (
/invite @bot_user_name
). - Click the channel name in the upper bar, then copy the channel ID from the resulting screen and replace the example value for the key
slackChannelId
inSecrets/lambda-configuration.json
- Create 3 AWS Secrets Manager secrets for each of the JSON files in
Secrets
, setting the secret value to the entire contents of the file- Naming does not matter here, but the following is recommended:
github-credentials.json
:githubCredentials
slack-credentials.json
:slackCredentials
lambda-configuration.json
:webhookReceiverConfiguration
- Copy the ARNs of all 3 for use in a later step
- Naming does not matter here, but the following is recommended:
- Create an AWS DynamoDB table with partition key
itemId
of typeString
- Naming does not matter, but
scheduledProjectItemMoves
is recommended
- Naming does not matter, but
- Create a Global Secondary index on your DynamoDB table with partition key
projectId
of typeString
and sort keyscheduledDate
of typeString
- Naming does not matter, but
itemsByDate
is recommended
- Naming does not matter, but
- Install
Docker
- On macOS with Homebrew installed, you can just run:
brew install --cask docker
- Launch and set up
Docker.app
(default settings are fine)
- On macOS with Homebrew installed, you can just run:
- Create the directory for the output Lambda:
mkdir .lamdba
- Build the Lambda in a container, and copy the resulting Zip to your host:
DOCKER_BUILDKIT=1 docker build --output .lambda
- Create an AWS Lambda and upload the Zip file at
.lambda/debug/GithubProjectsWebhookReceiver.zip
as the deployment package- You will need to grant the Lambda permissions to the Secrets and DynamoDB table created above
- Set environment variables for the Lambda to function correctly:
REGION
: AWS region name in which you've deployed the Lambda and secrets (for example,us-west-1
)GITHUB_CREDENTIALS_SECRET_ARN
: ARN for the GitHub credentials secret created aboveSLACK_CREDENTIALS_SECRET_ARN
: ARN for the Slack credentials secret created aboveCONFIGURATION_SECRET_ARN
: ARN for the configuration secret created aboveSCHEDULED_MOVES_TABLE_NAME
: name of the DynamoDB table created above
- Create a Function URL for your Lambda
- Back in your GitHub App settings, in the
General
tab and theWebhook
section, check theActive
box and fill in your new Lambda URL- Use the HMAC secret created above and stored in
Secrets/github-credentials.json
as the Webhook secret - Make sure to click
Save changes
when done
- Use the HMAC secret created above and stored in
- In the
Permissions & events
tab, under theSubscribe to events
section, selectProjects v2 item
andIssue comments
and then clickSave changes
You should now be able to:
- Create/move items in your project and have a Slack notification sent to your specified channel
- Reply to an issue with a comment like
/status To-do in 2 weeks
and have a corresponding move inserted into your DynamoDB table