# src/commands/onboarding.py
import logging
from bot.state import StateManager, get_team_id
from services.mongo_service import get_user_interests, save_user_interests
_INTEREST_OPTIONS = [
{"text": {"type": "plain_text", "text": "Sports"}, "value": "sports"},
{"text": {"type": "plain_text", "text": "Food"}, "value": "food"},
{"text": {"type": "plain_text", "text": "Hobbies"}, "value": "hobbies"},
{"text": {"type": "plain_text", "text": "Personal Life"}, "value": "personal_life"},
{"text": {"type": "plain_text", "text": "TV and Movies"}, "value": "tv_movies"},
{"text": {"type": "plain_text", "text": "Work Life"}, "value": "work_life"},
{"text": {"type": "plain_text", "text": "Would You Rather"}, "value": "would_you_rather"},
]
def _extract_user_id(body) -> str | None:
if body.get("user", {}).get("id"):
return body["user"]["id"]
return body.get("user_id")
def _build_interests_modal(team_id: str, user_id: str, current_tags: list[str]) -> dict:
valid_values = {option["value"] for option in _INTEREST_OPTIONS}
selected_values = [tag for tag in current_tags if tag in valid_values]
initial_options = [option for option in _INTEREST_OPTIONS if option["value"] in selected_values]
checkboxes_element = {
"type": "checkboxes",
"action_id": "selected_interests",
"options": _INTEREST_OPTIONS,
}
if initial_options:
checkboxes_element["initial_options"] = initial_options
return {
"type": "modal",
"callback_id": "user_interests_modal",
"private_metadata": f"{team_id}|{user_id}",
"title": {"type": "plain_text", "text": "Your Interests"},
"submit": {"type": "plain_text", "text": "Save"},
"close": {"type": "plain_text", "text": "Cancel"},
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "Select the topics you like so we can get a general sense of your interests.",
},
},
{
"type": "input",
"block_id": "interests_block",
"optional": True,
"label": {
"type": "plain_text",
"text": "Pick the topics that interest you",
},
"element": checkboxes_element,
},
],
}
[docs]
def register_onboarding(bolt_app, state_manager: StateManager):
"""
Sends new workspace members a DM with a topic interest checklist when they join.
Tags are stored per-user to help the bot make soft social introductions.
"""
@bolt_app.event("team_join")
def handle_team_join(event, client, body):
user = event.get("user", {})
user_id = user.get("id") if isinstance(user, dict) else user
if not user_id:
return
try:
client.chat_postMessage(
channel=user_id,
text="Welcome to Vibe Check! :wave: Choose which topics interest you.",
blocks=[
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": (
":wave: *Welcome to Vibe Check!*\n\n"
"The bot sends regular prompts to get the team sharing and connecting. "
"Let us know which *topics* interest you!\n"
"Hit the button below to pick your interests.\n\n"
"For more information on the bot, use `/help`."
),
},
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {"type": "plain_text", "text": ":label: Choose Interests"},
"action_id": "onboarding_choose_tags",
"style": "primary",
}
],
},
],
)
logging.info(f"[ONBOARDING] Sent welcome DM to user {user_id}")
except Exception as e:
logging.error(f"[ONBOARDING] Failed to DM user {user_id}: {e}")
@bolt_app.command("/picktags")
def handle_picktags_command(ack, body, client):
ack()
_open_interests_modal(body, client)
@bolt_app.action("onboarding_choose_tags")
def handle_onboarding_choose_tags(ack, body, client):
ack()
_open_interests_modal(body, client)
def _open_interests_modal(body, client):
team_id = get_team_id(body)
user_id = _extract_user_id(body)
trigger_id = body.get("trigger_id")
if not user_id or not trigger_id:
logging.warning("[ONBOARDING] Could not open interests modal, missing user_id or trigger_id")
return
current_tags = get_user_interests(team_id, user_id)
client.views_open(
trigger_id=trigger_id,
view=_build_interests_modal(team_id, user_id, current_tags),
)
@bolt_app.view("user_interests_modal")
def handle_user_interests_modal(ack, body, client):
ack()
metadata = body["view"].get("private_metadata", "|")
parts = metadata.split("|", 1)
team_id = parts[0] if parts[0] else get_team_id(body)
user_id = parts[1] if len(parts) > 1 and parts[1] else body["user"]["id"]
selected = (
body["view"]["state"]["values"]
.get("interests_block", {})
.get("selected_interests", {})
.get("selected_options", [])
)
tags = [opt["value"] for opt in selected]
save_user_interests(team_id, user_id, tags)
tag_list = ", ".join(f"`{t}`" for t in sorted(tags)) if tags else "nothing yet"
logging.info(f"[ONBOARDING] Saved interests for user {user_id}: {tags}")
client.chat_postMessage(
channel=user_id,
text=f":white_check_mark: Got it! Your interests are saved as: {tag_list}. You can update them anytime with `/picktags`.",
)