Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,41 @@ html_test/

# Playwright MCP screenshots
.playwright-mcp/

# CDL Onboarding Bot
scripts/onboarding/.env
scripts/onboarding/output/
scripts/onboarding/*.json
*.credentials.json
service-account*.json

# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
.pytest_cache/
.coverage
htmlcov/

# Virtual environments
venv/
ENV/
env/
.venv/
Binary file modified lab_manual.pdf
Binary file not shown.
2 changes: 1 addition & 1 deletion lab_manual.tex
Original file line number Diff line number Diff line change
Expand Up @@ -828,7 +828,7 @@ \subsection{Authorship guidelines}
an interface for asking questions, storing notes, and sharing
ideas. If you have a~\ourschool~NetID you should be able to join the workspace by clicking the link.
If you do \textit{not} have a NetID, you'll need to \href{https://services.dartmouth.edu/TDClient/1806/Portal/Requests/ServiceDet?ID=30581}{request one here}.
\marginnote{\texttt{TASK:} When you join our Slack workspace, initiate our onboarding process using the ``Join the lab!'' workflow. You can access this workflow in the \texttt{\#general} channel
\marginnote{\texttt{TASK:} When you join our Slack workspace, initiate our onboarding process using the \href{https://slack.com/shortcuts/Ft07ESC6CP3J/b1531b6fe100db8522fbd05c6a49ef63}{``Join the lab!'' workflow}. You can also access this workflow in the \texttt{\#general} channel
through the Workflows menu (usually near the top left of the window). Once you initiate the workflow, you'll be guided through the onboarding process.}

\item \href{https://www.github.com}{\textbf{GitHub.}}
Expand Down
59 changes: 59 additions & 0 deletions scripts/onboarding/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# CDL Onboarding Bot Configuration
# Copy this file to .env and fill in the values
# NEVER commit the actual .env file to the repository

# =============================================================================
# REQUIRED: Slack Configuration
# =============================================================================

# Slack Bot OAuth Token (starts with xoxb-)
# Get from: https://api.slack.com/apps > Your App > OAuth & Permissions
SLACK_BOT_TOKEN=xoxb-your-bot-token

# Slack App-Level Token for Socket Mode (starts with xapp-)
# Get from: https://api.slack.com/apps > Your App > Basic Information > App-Level Tokens
SLACK_APP_TOKEN=xapp-your-app-token

# Slack User ID of the admin (lab director)
# Find by clicking on profile > More > Copy member ID
SLACK_ADMIN_USER_ID=U12345678

# =============================================================================
# REQUIRED: GitHub Configuration
# =============================================================================

# GitHub Personal Access Token with admin:org scope
# Create at: https://github.com/settings/tokens
# Required scopes: admin:org, repo (for team management)
GITHUB_TOKEN=ghp_your_token_here

# GitHub Organization name (default: ContextLab)
GITHUB_ORG_NAME=ContextLab

# Default team to add new members to
GITHUB_DEFAULT_TEAM=Lab default

# =============================================================================
# OPTIONAL: Google Calendar Configuration
# =============================================================================

# Path to Google service account credentials JSON file
# Create at: https://console.cloud.google.com/iam-admin/serviceaccounts
# The service account needs to be granted access to each calendar
GOOGLE_CREDENTIALS_FILE=/path/to/service-account.json

# Calendar IDs (found in calendar settings > Integrate calendar)
GOOGLE_CALENDAR_CONTEXTUAL_DYNAMICS_LAB=primary@group.calendar.google.com
GOOGLE_CALENDAR_OUT_OF_LAB=outoflab@group.calendar.google.com
GOOGLE_CALENDAR_CDL_RESOURCES=resources@group.calendar.google.com

# =============================================================================
# OPTIONAL: Anthropic Configuration (for bio editing)
# =============================================================================

# Anthropic API key for Claude
# Get from: https://console.anthropic.com/account/keys
ANTHROPIC_API_KEY=sk-ant-your-key-here

# Model to use (default: claude-sonnet-4-20250514)
ANTHROPIC_MODEL=claude-sonnet-4-20250514
226 changes: 226 additions & 0 deletions scripts/onboarding/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
# CDL Onboarding Bot

A Slack bot for automating the onboarding and offboarding process for CDL lab members.

## Features

### Onboarding (Two Methods)

**Method 1: Workflow Builder Integration (Recommended)**

Integrates with existing "Join the lab!" and "Leave the lab" Slack Workflow Builder workflows. New members initiate their own onboarding by clicking a workflow link.

- New member runs the "Join the lab!" workflow
- Bot receives form data and validates GitHub username
- Admin gets an interactive approval message
- On approval: GitHub invite sent, calendars shared, photo processed

**Method 2: Admin-Initiated (`/cdl-onboard @user`)**

Admin can also start onboarding manually:
- Sends welcome message to new member
- Collects: GitHub username, bio, photo, website URL
- Validates GitHub username via API
- Edits bio to CDL style (third person, 3-4 sentences) using Claude
- Adds hand-drawn green border to profile photo
- Sends GitHub organization invitation
- Shares Google Calendar access
- All actions require admin approval

### Offboarding (`/cdl-offboard` or Workflow)
- Can be initiated by member or admin
- Works with "Leave the lab" Workflow Builder workflow
- Admin selects what access to revoke (GitHub, calendars)
- Does NOT automatically remove anyone
- Generates checklist for manual steps

## Setup

### 1. Create Slack App

1. Go to [api.slack.com/apps](https://api.slack.com/apps)
2. Create new app from manifest (use `manifest.json` in this directory)
- Or create from scratch and configure manually:
3. Enable Socket Mode in "Socket Mode" settings
4. Create an app-level token with `connections:write` scope
5. Add Bot Token Scopes in "OAuth & Permissions":
- `chat:write`
- `commands`
- `users:read`
- `users:read.email`
- `im:write`
- `im:history`
- `files:read`
- `files:write`
- `workflow.steps:execute`
6. Add Event Subscriptions:
- `file_shared`
- `function_executed`
7. Create slash commands in "Slash Commands":
- `/cdl-onboard` - Start onboarding a new member
- `/cdl-offboard` - Start offboarding process
- `/cdl-ping` - Health check
- `/cdl-help` - Show help
8. Enable "Interactivity & Shortcuts"
9. Enable "Org Level Apps" (for Workflow Builder custom steps)
10. Install app to workspace

### 2. Create GitHub Token

1. Go to [github.com/settings/tokens](https://github.com/settings/tokens)
2. Create new token (classic) with scopes:
- `admin:org` (for team and invitation management)
- `repo` (for team repository access)

### 3. Set Up Google Calendar (Optional)

1. Create a Google Cloud project
2. Enable the Google Calendar API
3. Create a service account
4. Download the credentials JSON file
5. Share each calendar with the service account email

### 4. Get Anthropic API Key (Optional)

1. Go to [console.anthropic.com](https://console.anthropic.com)
2. Create an API key for bio editing

### 5. Configure Environment

```bash
# Copy the example config
cp .env.example .env

# Edit with your credentials
nano .env
```

Required variables:
- `SLACK_BOT_TOKEN` - Bot OAuth token (xoxb-...)
- `SLACK_APP_TOKEN` - App-level token (xapp-...)
- `SLACK_ADMIN_USER_ID` - Your Slack user ID
- `GITHUB_TOKEN` - GitHub PAT with admin:org scope

Optional variables:
- `GOOGLE_CREDENTIALS_FILE` - Path to service account JSON
- `GOOGLE_CALENDAR_*` - Calendar IDs
- `ANTHROPIC_API_KEY` - For bio editing

### 6. Install Dependencies

```bash
pip install -r requirements.txt
```

### 7. Run the Bot

```bash
python -m scripts.onboarding.bot
```

## Usage

### Starting Onboarding

As admin:
```
/cdl-onboard @newmember
```

This will:
1. Open a form for the new member to fill out
2. Send approval request to admin
3. Admin reviews and approves/rejects
4. On approval: GitHub invite sent, calendars shared, photo processed

### Starting Offboarding

As member leaving:
```
/cdl-offboard
```

As admin for specific member:
```
/cdl-offboard @member
```

Admin selects what to revoke and receives checklist.

## Testing

Run tests (model and image tests don't require API keys):
```bash
# Models only
pytest tests/test_onboarding/test_models.py -v

# Image processing only
pytest tests/test_onboarding/test_image_service.py -v

# GitHub service (requires GITHUB_TOKEN)
pytest tests/test_onboarding/test_github_service.py -v

# Bio service (requires ANTHROPIC_API_KEY)
pytest tests/test_onboarding/test_bio_service.py -v

# All tests
pytest tests/test_onboarding/ -v
```

## Workflow Builder Integration

The bot provides custom steps that can be added to Slack Workflow Builder workflows.

### Adding Custom Steps to Workflows

1. Ensure the Slack app has `workflow.steps:execute` scope and `function_executed` event
2. In Workflow Builder, create or edit a workflow
3. Add a step and search for "CDL Onboarding" to find the custom steps:
- **Process CDL Onboarding**: Receives form data, validates GitHub, sends approval to admin
- **Process CDL Offboarding**: Notifies admin and generates checklist

### Connecting to Existing "Join the Lab!" Workflow

1. Edit your existing "Join the lab!" workflow in Workflow Builder
2. After the form collection step, add the "Process CDL Onboarding" step
3. Map the form fields to the step inputs:
- `submitter_id` -> Person who started the workflow
- `github_username` -> GitHub username field from form
- `bio` -> Bio field from form
- `website_url` -> Website field from form
- `photo_url` -> Photo URL if collected

### Connecting to "Leave the Lab" Workflow

1. Create a new "Leave the lab" workflow or add to existing
2. Add the "Process CDL Offboarding" step
3. Map:
- `submitter_id` -> Person leaving the lab

## Architecture

```
scripts/onboarding/
├── bot.py # Main entry point
├── config.py # Configuration management
├── manifest.json # Slack app manifest (with functions)
├── handlers/
│ ├── onboard.py # /cdl-onboard command handling
│ ├── approval.py # Admin approval workflow
│ ├── offboard.py # /cdl-offboard command handling
│ └── workflow_step.py # Workflow Builder custom steps
├── models/
│ └── onboarding_request.py # Data models
└── services/
├── github_service.py # GitHub API integration
├── calendar_service.py # Google Calendar API
├── image_service.py # Photo border processing
└── bio_service.py # Claude API bio editing
```

## Security Notes

- Credentials stored in `.env` (gitignored)
- All onboarding actions require admin approval
- Offboarding does NOT auto-remove (generates checklist)
- Private info detection in bios (phone, email, SSN)
8 changes: 8 additions & 0 deletions scripts/onboarding/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"""
CDL Onboarding Bot
Contextual Dynamics Laboratory, Dartmouth College

Automates the lab member onboarding process via Slack.
"""

__version__ = "0.1.0"
Loading