https://github.com/saronic-technologies/uplogd-bot
Slack bot to run uplogd commands on behalf of user
https://github.com/saronic-technologies/uplogd-bot
Last synced: 4 months ago
JSON representation
Slack bot to run uplogd commands on behalf of user
- Host: GitHub
- URL: https://github.com/saronic-technologies/uplogd-bot
- Owner: saronic-technologies
- Created: 2025-11-04T23:46:50.000Z (7 months ago)
- Default Branch: main
- Last Pushed: 2026-02-10T22:34:18.000Z (4 months ago)
- Last Synced: 2026-02-11T00:27:51.639Z (4 months ago)
- Language: JavaScript
- Size: 260 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Uplogd Slack Bot
Slack app scaffold that runs entirely in Socket Mode, opens a modal from a global shortcut, and forwards the submission to an external HTTP endpoint.
## Prerequisites
- Node.js 18+
- Slack workspace where you can create/manage apps
- External API endpoint that accepts JSON POST requests
## Setup
1. Install dependencies:
```bash
npm install
```
2. Copy `.env.example` to `.env` and populate the values:
```bash
cp .env.example .env
```
| Variable | Description |
| --- | --- |
| `SLACK_SIGNING_SECRET` | **Required.** Found on your app's **Basic Information** page. |
| `SLACK_BOT_TOKEN` | **Required.** Bot token with `commands` and `chat:write` scopes. |
| `SLACK_APP_TOKEN` | **Required.** App-level token with the `connections:write` scope for Socket Mode. |
| `API_ENDPOINT` | **Required.** URL that receives the form data. |
| `API_AUTH_TOKEN` | Optional bearer token added to the outbound request. |
| `SHORTCUT_CALLBACK_ID` | Optional. Defaults to `manage_uplogd`. Must match your global shortcut callback ID. |
| `ASSETS_ENDPOINT` | **Required.** URL returning a list of assets used to populate the modal dropdown. |
| `ASSETS_AUTH_TOKEN` | Optional bearer token used when fetching assets. |
| `UPLOGD_UPDATES_CHANNEL` | Optional channel ID (e.g. `C01234567`). When set, the bot posts submission updates there instead of DMing the user. |
| `UPLOGD_DM_RECIPIENT` | Optional user ID (e.g. `U0123ABCD`). When set, the bot sends DM summaries to this user instead of the requester. |
3. Create the Slack app (or open your existing one):
- Enable **Socket Mode** and generate an app-level token with the `connections:write` scope.
- Enable **Interactivity & Shortcuts** (no public URL needed when using Socket Mode).
- Add a **Global Shortcut** whose callback ID matches `SHORTCUT_CALLBACK_ID` (default `manage_uplogd`).
- Add the following bot scopes: `commands`, `chat:write`, and any additional scopes you need. Include `chat:write.public` if you plan to post into public channels the bot hasn't joined yet.
- Install the app to your workspace and copy the credentials into your `.env` file.
## Running locally
```bash
npm run dev
```
This starts the Bolt app in Socket Mode—no public URL or tunneling tool is required.
## Deploying
The project includes a PM2 script that keeps the bot running on a server:
1. Install dependencies and configure `.env` on the host as described above.
2. Start the background process with:
```bash
npm run deploy
```
This launches PM2 with a process named `uplogd-bot` that watches the `src` directory for changes.
3. Check the process anytime with `pm2 status uplogd-bot`.
4. Stream logs when needed with `pm2 logs uplogd-bot`.
5. Stop or remove the process via `pm2 stop uplogd-bot` or `pm2 delete uplogd-bot`.
## How it works
- The global shortcut fires `src/app.js`, which fetches assets from `ASSETS_ENDPOINT`, then opens the modal defined in `src/modal.js`.
- When the user submits the modal, `src/services/submitForm.js` serializes the selected asset, which targets (`imx8`/`crystal`) were checked, and the chosen action (`start`, `stop`, `restart`), then sends them to `API_ENDPOINT` via `axios`.
- The bot DMs the requester immediately, then edits that DM with the SSH response once the external API call returns. When `UPLOGD_UPDATES_CHANNEL` is set, it also posts a one-line announcement with a status button to that channel; status checks there reply via ephemeral messages so the public post stays clean.
- A bearer token header is added when `API_AUTH_TOKEN` is provided.
You can extend the modal blocks or adjust the payload transformation inside `submitFormPayload` to match your API contract.
### Asset endpoint contract
`ASSETS_ENDPOINT` should respond with either:
- An array of strings; each string becomes both the option label and value.
- An array of objects containing at least an identifier (`asset`, `id`, `uuid`, `slug`, `code`, or `key`) and a display name (`name`, `title`, `label`, or `display_name`). Optional `description` fields are truncated and shown as helper text in the select menu.
If the endpoint responds with an object, the adapter falls back to `data.items`.
The dropdown currently filters assets to those whose name starts with `sg`, `by`, or `cr`. Primary/secondary flags from the payload determine which options appear under the "Which Machine?" checkbox group (`imx8` for primary, `crystal` for secondary), and unavailable machines are noted inline. The selected action (`start`, `stop`, `restart`) and any checked targets are included in the submission payload, and each selected machine results in a POST to `API_ENDPOINT/uplog/{boat}/{action}` (with `boat` taken from the asset ID) carrying the machine and metadata.