本文へ移動
cccskills
無料GitHub で公開

teams-connect

Set up Microsoft Teams as a notification channel for your Egregore — registers an Azure bot, uploads the app, and binds a channel. Use for /teams-connect, 'connect teams', or 'set up teams notifications'.

日本語の概要は準備中です。原文の説明を表示しています。

egregore-labs/egregoreスター 293(GitHub 293 + cccskills 0)

実行スコア 未検証

インストール方法を見る

含まれるファイル(1)

  • SKILL.md10.2 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Set up Microsoft Teams as a notification channel for your Egregore.

Arguments: $ARGUMENTS (none expected)

When to invoke

Trigger phrases:

  • "set up teams", "connect teams", "teams-connect", "microsoft teams"
  • "add teams notifications", "teams channel", "notify us on teams"

Disambiguation:

  • "set up telegram" → /telegram-connect
  • "send a message to teams" → NOT this — use the separate notification consent protocol in .claude/context/notification-consent.md

What this does

Registers a bot in the org's own Microsoft tenant, installs it in their Teams, and binds one channel to Egregore notifications. After this, everything that plans a group notification may also resolve Teams as a receiving channel; all resolved channels are shown before separate dispatch approval.

You (the agent) run all the Azure work via az after one browser login. The human does exactly three things: one login, two portal clicks, one paste.

OSS tier — visible, gated, honest

This skill ships to every Egregore, but Teams notifications run on the Connected tier. Before anything else, detect the tier:

bash bin/config-get.sh mode

Use the printed value as {mode}; quote it in single quotes when you use it in a command, and write any single quote inside the value as '\''. If it prints local, the instance is on the local (OSS) tier; if it prints connected, continue with setup. The command uses exactly the canonical _detect_mode truth table (bin/lib/config.sh): explicit local mode or an empty API URL means local. (A hand-set mode: "connected" without an api_url is still local — never treat it as an unlock.)

On the local tier, deliver exactly this message, then the question — do not paraphrase the message:

You can expand your knowledge base with connections to Notion, Google Drive, Docs, Sheets, and many more. Upgrade to Connected Tier to accelerate.

Ask with a structured question when available and permitted in this session; otherwise ask in plain text:

  • Upgrade to Connected Tier — tell them the one sanctioned path: run egregore connect in a terminal (the launcher walks the whole upgrade: registers your org with the platform, provisions the key, replays your graph). Teams notifications unlock once Connect is active.
  • Not now — respect it and stop. Do not improvise config edits, api_url values, or partial flows.

Only continue past this section on a connected instance.

Step 0: Prerequisites (check before touching anything)

Ask, or verify where possible. All three must be true:

  1. A Microsoft 365 tenant with Teams (work tenant, not personal Teams).
  2. The person here is admin of that tenant (Entra + Teams admin center).
  3. An Azure subscription in that tenant — the bot resource is free (F0) but must live in a subscription.

az CLI must be installed: which az — if missing, brew install azure-cli (macOS) or point at https://aka.ms/azure-cli for their OS.

Step 1: Login (human, ~1 min)

Ask them to run in the prompt:

! az login

Then verify tenant + user:

az account show --query "{tenant:tenantId, user:user.name, state:state}" -o json

Verify Teams is actually licensed (the #1 silent dead-end — an Azure-only tenant has no Teams and the Teams admin center errors with a cryptic "can't find the tenant region for …" / PLS message):

az rest --method get --url "https://graph.microsoft.com/v1.0/subscribedSkus" \
  --query "value[].skuPartNumber" -o json
  • [] or no Teams-bearing SKU → they need a license first. Guide: M365 admin center → Marketplace → Microsoft 365 Business Basic (Trial). EEA trap: every SKU marked "(no Teams)" literally excludes Teams (EU unbundling) — pick the plain variant, or add "Microsoft Teams EEA" separately. After purchase, assign the license (set usageLocation on the user first — assignLicense fails without it, and racing the two calls fails too: PATCH usageLocation, then assign in a separate call).
  • Graph 403 AADSTS530035 (security defaults) → az logout && az login fresh.

Step 2: Azure infrastructure (agent, ~2 min)

Use the app ID printed here as {app_id}, the tenant ID from Step 1 as {tenant_id}, and the chosen Azure region (for example westeurope) as {region}; single-quote substituted values as shown and write any embedded single quote as '\''.

  1. App registration (single-tenant — deliberate; Microsoft is deprecating new multi-tenant bots):
az ad app create --display-name "Egregore Notifications" --sign-in-audience AzureADMyOrg \
  --query "{appId:appId}" -o json
  1. Client secret (2 years):
az ad app credential reset --id '{app_id}' --display-name "teams-notify" --years 2 -o json
  1. Service principal — az ad app create does NOT make one; skipping this yields token 401 AADSTS7000229 later:
az ad sp create --id '{app_id}'
  1. Resource group + free Azure Bot + Teams channel, one command at a time:
az group create -n egregore-bots -l '{region}'
az bot create --resource-group egregore-bots --name egregore-notifications \
  --app-type SingleTenant --appid '{app_id}' --tenant-id '{tenant_id}' --sku F0
az bot msteams create --name egregore-notifications --resource-group egregore-bots

Save to the instance .env (gitignored — never commit):

TEAMS_APP_ID=…
TEAMS_APP_SECRET=…
TEAMS_TENANT_ID=…

Smoke the token before proceeding (catches AADSTS7000229 immediately):

curl -sS -X POST "https://login.microsoftonline.com/<TENANT_ID>/oauth2/v2.0/token" \
  -d grant_type=client_credentials -d "client_id=<APP_ID>" \
  -d "client_secret=<SECRET>" -d "scope=https://api.botframework.com/.default"

Step 3: App package + catalog upload (human, 2 clicks)

Build and reveal the zip:

bash teams-app/build-package.sh '{app_id}'

After the build succeeds:

open teams-app/build/

(If this instance doesn't carry teams-app/, fetch it from the framework repo.)

Guide them: https://admin.teams.microsoft.com/policies/manage-apps → Actions → Upload new app → pick egregore-teams-app.zip.

Traps:

  • Fresh tenants show "setting up your new app management experience… up to 30 minutes" with the upload button greyed out. It's provisioning — wait, refresh.
  • Re-uploading the same app id via "Upload new app" is rejected — updates go through the app's detail page → Upload file to update.

Step 4: Add the bot to the team (human, 1 click)

In Teams — the work account (trap: the desktop app may silently be the consumer client — "Build your community" UI, no org catalog; use teams.microsoft.com if in doubt): Apps → Built for your org → Egregore → ▾ → Add to a team → pick the channel → Set up a bot.

Without this, sends fail 403 BotNotInConversationRoster.

Step 5: Channel binding (human pastes, agent decodes)

Ask for the channel link (channel → ⋯ → Get link to channel), then decode:

python3 -c "import sys,urllib.parse,re; m=re.search(r'(19%3a[^/?]+|19:[^/?]+)', sys.argv[1]); print(urllib.parse.unquote(m.group(1)))" "<PASTED_LINK>"

Result must look like 19:…@thread.tacv2.

Step 6: Persist

mkdir -p tmp

Only read the response with jq after the helper succeeds. If it fails, show its error and stop; the helper leaves no response file after a failure.

Write the file tmp/teams-connect-bind.json with {"conversation_id":"<CONV_ID>","app_id":"<APP_ID>","app_secret":"<SECRET>","tenant_id":"<TENANT_ID>"}, substituting the channel and Azure registration values. Non-default region: the bot's service URL may differ from the EMEA default — include "service_url" too (Azure portal → the bot → Channels → Teams shows it). The helper reads EGREGORE_API_KEY internally.

bash bin/api-call.sh POST /api/org/teams --auth egregore --json-file tmp/teams-connect-bind.json --out tmp/teams-connect-bind-response.json
jq '.' tmp/teams-connect-bind-response.json

Expect {"status":"connected", …}. The per-org creds matter: a single-tenant bot only works in its home tenant, so each org brings its own registration.

Step 7: Verify with separate exact notification consent

Follow .claude/context/notification-consent.md. Connecting Teams is not consent to send a test message. Prepare after configuration is final:

mkdir -p tmp
bash bin/notify.sh plan group "Teams channel connected — this message reached you through Egregore." > tmp/teams-connect-plan.json
jq -r '.plan_id, .digest' tmp/teams-connect-plan.json

Use the printed values as {plan_id} and {digest}, respectively, for the notification consent flow. Read the exact preview fields:

jq -r '.org, .recipient, .channels, .deliveries, .message' tmp/teams-connect-plan.json

Show every resolved receiving channel—potentially both Telegram and Teams—and the exact message in a dedicated Send / Edit / Cancel checkpoint. Only dispatch after Send is selected for that preview. Card avatar may show a generic icon for a few hours (Teams caches app icons) — cosmetic, self-heals.

Troubleshooting quick table

SymptomCause → fix
"can't find the tenant region" (PLS) in Teams admin centerNo M365/Teams license on the tenant → Step 1 licensing
Token 401 AADSTS7000229Missing service principal → az ad sp create --id '{app_id}'
Send 403 BotNotInConversationRosterBot not added to the team → Step 4
Send 404Wrong conversation id or wrong service_url region
"already an app with the same app ID" on uploadUse the app detail page → Upload file to update
No Apps rail / no org catalog in TeamsConsumer Teams client → work account at teams.microsoft.com
Upload button greyed outTenant still provisioning app management (≤30 min)

After

Emit telemetry (fire-and-forget):

bash bin/telemetry.sh emit "teams-connect" '{"command":"teams-connect"}' 2>/dev/null &

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

コメント

ログインなしで書き込めます。使ってみた感想、質問、動かなかった環境などを気軽にどうぞ。

まだコメントはありません。最初のコメントを書いてみませんか。

送信するとすぐに公開されます。メールアドレスや電話番号などの個人情報は書かないでください。URL は 2 つまでです。

0 / 1000 文字

このフォームは reCAPTCHA で保護されており、Google のプライバシーポリシーと利用規約が適用されます。

同じリポジトリのスキル

activity

無料

Explicit Activity card only. Use when the user names /activity or directly asks to show, open, or render the Activity dashboard/card. Never use it to answer or synthesize what the team is focused on, busy with, prioritizing, or doing; analytical organizational questions use Search/Runtime QMD.

日本語の概要は準備中です。原文の説明を表示しています。

egregore-labs/egregore2932026年10月17日 更新

announce

無料

Draft, preview, and explicitly send an Egregore group announcement. Use for /announce, telling the team something, or notifying everyone—not a direct message or structured handoff.

日本語の概要は準備中です。原文の説明を表示しています。

egregore-labs/egregore2932026年10月17日 更新

archive

無料

Capture an effective prompting or steering technique as a reusable canonical pattern. Use when a prompt chain worked especially well; use /reflect for insight about the work and /note for a private thought.

日本語の概要は準備中です。原文の説明を表示しています。

egregore-labs/egregore2932026年10月17日 更新

branch

無料

Create a working branch from what you are about to work on. Use for /branch, or any request to start a new branch before making changes.

日本語の概要は準備中です。原文の説明を表示しています。

egregore-labs/egregore2932026年10月17日 更新

checkup

無料

Run diagnostics on an Egregore environment and render a health report, repairing safe local Runtime problems when possible. Use for /checkup, a health check, or when something is broken and the root cause is unclear.

日本語の概要は準備中です。原文の説明を表示しています。

egregore-labs/egregore2932026年10月17日 更新

commit

無料

Stage changes and create a commit with a properly formatted message. Use for /commit, or saving work locally — not sharing it (/push) or opening a pull request (/pr).

日本語の概要は準備中です。原文の説明を表示しています。

egregore-labs/egregore2932026年10月17日 更新

egregore-labs のスキルをすべて見る

このスキルの問題を報告する