Skip to Content

운영자 broadcast (Teams DM)

AI 요청 프롬프트

https://docs.axelabs.ai/ops/runbook/operator-broadcast 따라 임직원 [수신자 email list] 에게 다음 공지 broadcast 해줘: [공지 본문 paste] 진행: 1. 본 페이지의 Prereq 확인 (Blueprint LIVE + CRON_SECRET 접근 가능) 2. Step 1..4 순서대로 — 매 step 결과 받고 다음 3. 함정 발생 시 페이지 "함정 정리" 표 따라 우회 4. Step 4 결과 (3 messageId) 받으면 종료 + Ship Log 한 줄 (선택)

본인 AI session = Claude Code / Cursor / ChatGPT 데스크탑 / Claude.app / 기타.

페이지 본문 = 사람이 직접 read 도 가능, AI 도 참고. AI 가 본 페이지 fetch 후 위 진행 순서대로 사용자와 step-by-step interactive 풀어나감.

Prereq

  • 운영자 자격 (AXE org Owner — 본 broadcast 가 정당 operational 공지인지 본인 판단)
  • axe-macmini 에서 실행 (Blueprint LIVE 가 http://blueprint.local:3100 으로 접근 가능)
  • /Users/axe/blueprint/.envCRON_SECRET 환경변수 존재 (Blueprint deploy 시 자동 set)
  • 수신자 email list (@axellc.com 도메인 — 운영자 자체 broadcast 가 cross-tenant 안 함)
  • 본문 = plain text 또는 escaped html (default text — 권장)

Step 1: 사전 확인 (Blueprint LIVE + CRON_SECRET + bot identity)

# (a) Blueprint health curl -sf -o /dev/null -w 'blueprint http=%{http_code}\n' http://blueprint.local:3100/api/health # (b) CRON_SECRET 길이 (값 출력 X) SECRET=$(grep '^CRON_SECRET=' /Users/axe/blueprint/.env | cut -d= -f2- | tr -d '"' | tr -d "'") echo "secret_len=${#SECRET}" # (c) bot identity = ai@ 인지 self-DM 거부 응답으로 검증 (실제 메시지 발송 X) curl -sf -X POST http://blueprint.local:3100/api/admin/broadcast-dm \ -H "Authorization: Bearer $SECRET" \ -H 'Content-Type: application/json' \ -d '{"emails":["[email protected]"],"text":"self-test","contentType":"text"}' \ | jq '.results[0]' # 기대: {email:"[email protected]", status:"skipped", reason:"target AAD id matches bot — refusing self-DM"} # → reason 안에 "matches bot" 보이면 bot = ai@ 정상

3개 다 통과해야 진행. 실패 시 함정 표 참조.

Step 2: 본문 + payload JSON 작성

본문 = plain text (default contentType). 줄바꿈 \n, 특수문자 escape 불필요 (text mode 라 client 가 그대로 렌더). bullet 은 - 또는 등 plain.

# 본문을 한 변수에 — heredoc 이 가독성 ↑ BODY=$(cat <<'EOF' [제목 1줄] [본문 내용] - bullet 1 - bullet 2 링크: https://... EOF ) # payload JSON 작성 (jq 가 \n + 특수문자 자동 escape) EMAILS_JSON='["[email protected]","[email protected]","[email protected]"]' jq -n --argjson emails "$EMAILS_JSON" --arg text "$BODY" \ '{emails:$emails, contentType:"text", text:$text}' > /tmp/bcast.json # 확인 (수신자 + 본문 길이만 — 본문 풀 출력 안 함) jq '{emails, text_len: (.text | length)}' /tmp/bcast.json

Step 3: POST 호출

SECRET=$(grep '^CRON_SECRET=' /Users/axe/blueprint/.env | cut -d= -f2- | tr -d '"' | tr -d "'") curl -s -X POST http://blueprint.local:3100/api/admin/broadcast-dm \ -H "Authorization: Bearer $SECRET" \ -H 'Content-Type: application/json' \ -d @/tmp/bcast.json \ -w '\nHTTP_%{http_code}\n'

기대 응답:

{ "summary": {"total":3, "sent":3, "skipped":0, "error":0}, "results": [ {"email":"[email protected]", "status":"sent", "chatId":"19:[email protected]", "messageId":"1779..."}, {"email":"[email protected]", "status":"sent", "chatId":"19:...", "messageId":"1779..."}, {"email":"[email protected]", "status":"sent", "chatId":"19:...", "messageId":"1779..."} ] }

sent=3 + HTTP 200 = 정상. cleanup:

rm -f /tmp/bcast.json

Step 4: 결과 검증 + Ship Log (선택)

각 수신자가 Teams 앱 (phone + desktop) 에서 [email protected] 로부터 1:1 DM push 알림 받았는지 본인이 확인 (수신자 회신 또는 운영자 본인 Teams 의 sent items 확인).

운영 회고용 Ship Log 한 줄 (broadcast 가 의미 있는 일이면 — vault 공지 / 신규 customer launch 등):

| YYYY-MM-DD HH:MM | broadcast (axe org) | (operator action) | **broadcast title** — 3 임직원 (soohun/taehun/jinwoo) Teams DM 발송. broadcast-dm REST + bot ai@. 본문 핵심: [한 줄 요약]. messageId: 1779..., 1779..., 1779... |

추가하면 /Users/axe/axelabs-docs/content/ops/updates.mdx Ship Log 표 최상단에 한 줄. axe ship docs 로 배포.

함정 정리

#증상원인우회
1외부 7cb41f76 MCP 의 노출 tool list 에 send_mail / send_email / graph_send_email 없음의도된 분리 — Blueprint 의 32+ graph_* tool 중 send 계열은 blueprint-graph 내부 MCP 에만 등록, 외부 connector 는 read-only 격리본 페이지의 broadcast-dm REST 사용 (admin 채널 별도)
2az rest --uri /me/sendMail403 Forbidden ErrorAccessDeniedaz CLI 의 first-party app (04b07795) 이 Mail.Send scope 받을 권한 없음 (Microsoft 자사 앱 간 consent preauthorization 정책)az CLI 경유 mail send 영구 불가 — broadcast-dm 또는 Outlook 수동
3az account get-access-token --scope https://graph.microsoft.com/Mail.Send → AADSTS65002(#2 와 동일 root cause)(#2 와 동일)
4/api/admin/broadcast-dm{status:"skipped", reason:"target AAD id matches bot — refusing self-DM"}bot identity = [email protected] — 본인에게 DM 시도 거부수신자 list 에서 ai@ 제거. 또는 self-test 용도 (Step 1 의 (c)) 일부러 의도적
5{status:"skipped", reason:"no AAD object id for user"}수신자가 Blueprint 에 한 번도 로그인한 적 없음 — NextAuth callback 의 User.aadObjectId populate 안 됨수신자가 https://blueprint.axelabs.ai  1회 SSO 로그인 → 자동 fill → 재시도
6401 UnauthorizedCRON_SECRET 헤더 잘못 / .env 에 미설정 / Bearer prefix 빠짐Authorization: Bearer $SECRET 정확. .env 의 CRON_SECRET 값 직접 변수에
7Connection refused http://blueprint.local:3100Blueprint 미실행 (PC 부팅 직후 / launchd 미가동)ps aux | grep blueprint 확인, 필요 시 launchctl kickstart -k gui/$(id -u)/com.axe.blueprint
8본문 줄바꿈 깨짐 (Teams 한 줄로 표시)contentType: "html" 인데 plain text 넣음 — <br> 없으니 collapsecontentType: "text" 명시 (default 권장)
9본문 안 * 강조 등이 안 보임Teams 는 markdown 미해석 (text contentType)bullet 은 - plain, 강조는 대문자 or === 줄 구분
10customer 직원 (@truvia.co.kr 등) 에게 보내려고 시도 → skipbroadcast-dm 의 bot = AXE tenant 의 ai@, cross-tenant chat 생성 불가customer 측은 본인 운영자 (Truvia 의 broadcast 채널) 자체 보냄 — sovereignty 원칙

관련 use case (참고)

  • vault 운영 공지 — KDF rotation / setup 안내 (D-ops-40, 2026-05-26 첫 실 사용)
  • 신규 customer launch 안내 — 새 service 가 LIVE 됐을 때
  • 시스템 변경 통보 — Blueprint major upgrade, frame schema migration 등
  • D-day 직전 사전 안내 — onboard step 차단 가능성 등 사전 경고

NOT for: 일반 잡담 (channel 사용), 1:1 코칭 (Teams 직접 chat), customer 측 공지 (customer 자체 채널).

매 작업 시 사전 작업

빈도작업자동화
매 broadcastStep 1 사전 확인 (Blueprint LIVE + bot identity 검증)❌ (사람 판단)
CRON_SECRET 회전 시Blueprint .env + axe-macmini launchd 재시작B-blueprint-secret-rotation 참조

참조

  • D-ops-40 — vault axe.3 release (본 broadcast 의 첫 use case, 2026-05-26)
  • /architecture/vault-policies — vault 3 layer 정책 모델 (broadcast 본문 안 참조 patterns)
  • /services/blueprint — Blueprint 서비스 개요
  • src/app/api/admin/broadcast-dm/route.ts — REST 구현
  • src/lib/teams/graph-client.ts — bot Graph client (getSharedClient() 가 ai@ 정합)
  • B-blueprint-broadcast-mail — 실 SMTP email 발송 route 추가 (M5, 사용 빈도 보고 진행)
  • /ops/known-gaps — Microsoft 첫 당사자 app consent policy (az CLI Mail.Send 영구 차단)
Last updated on