← 返回
未分类 Key 中文

M365 Planner

Manage Microsoft 365 Planner plans, buckets, and tasks via Microsoft Graph API. Use when creating, listing, updating, or deleting Planner resources. Supports...
通过 Microsoft Graph API 管理 Microsoft 365 Planner 计划、桶和任务。用于创建、列出、更新或删除 Planner 资源。支持...
felox63 felox63 来源
未分类 clawhub v1.2.3 1 版本 100000 Key: 需要
★ 1
Stars
📥 577
下载
💾 0
安装
1
版本
#latest

概述

M365 Planner Skill

Manage Microsoft 365 Planner through Microsoft Graph API.

What's New in v1.2.3

  • 🌍 English Documentation – Complete translation for international ClawHub availability
  • 🔧 Portability – Env path now uses os.homedir() instead of hardcoded paths
  • 🧹 Security Cleanup – Full audit for sensitive data (no IDs, names, domains)
  • 📦 ClawHub-ready – Tarball created, node_modules excluded

What's New in v1.2.2

  • 🔧 Portability – Env path now uses os.homedir() instead of hardcoded /home/claw/.openclaw/.env
  • 🧹 Security Cleanup – Full audit for sensitive data (no IDs, names, domains)
  • 📦 ClawHub-ready – Tarball created, node_modules excluded

What's New in v1.2.1

  • Generic Scripts – No hardcoded Group-IDs or Plan names anymore
  • Command-Line Parameters – All scripts accept IDs as arguments
  • List Plans Improved – Shows all groups when no ID provided
  • Flexible Cleanup – Works with any plans/buckets
  • ClawHub-ready – No project-specific data included

What's New in v1.1.0

  • Node.js Scripts – Standalone scripts without mgc CLI
  • If-Match Header Support – Correct ETag handling for updates/deletes
  • Group-Based API – Direct access via M365 Group-ID
  • Recurring Tasks – Note about native Planner recurrence feature
  • Cleanup Scripts – Automated task cleanup

Prerequisites

  1. Azure AD App Registration (see Setup below)
  2. Node.js v18+ with @microsoft/microsoft-graph-client and axios
  3. M365 Group (not Security Group or Distribution List!)

Quick Start

# Test connection
node scripts/test-connection.js

# List all plans
node scripts/list_plans.js

# List plans for specific group
node scripts/list_plans.js <group-id>

# Create plan
node scripts/create_plan.js "Project Name" <group-id>

# Create task
node scripts/create_task.js <plan-id> <bucket-id> "Task Title"

# Delete completed tasks
node scripts/cleanup_verlaengerungen.js <group-id> "<plan-name>" "<bucket-name>"

Setup: Azure AD App Registration

Step 1: Create App Registration

Azure Portal:

  1. https://portal.azure.com → Azure Active Directory → App registrations
  2. "New registration"
  3. Name: M365-Planner-Integration
  4. Supported account types: Accounts in this organizational directory only
  5. Redirect URI: None (Client Credentials Flow)

Or via Azure CLI:

az login
az ad app create --display-name "M365-Planner-Integration" --sign-in-audience "AzureADMyOrg"

Note the Application (client) ID from the output.

Step 2: Add API Permissions

Important: Use Application Permissions (not Delegated)!

Azure Portal:

  1. App → API permissions → Add a permission
  2. Microsoft Graph → Application permissions
  3. Add:
    • Group.Read.All (not Group.ReadWrite.All – sufficient for Planner)
    • Tasks.ReadWrite.All
  4. Grant Admin Consent: Click "Grant admin consent for [Tenant]"!

Or via Azure CLI:

APP_ID="your-app-id"

# Group.Read.All
az ad app permission add \
  --id $APP_ID \
  --api 00000003-0000-0000-c000-000000000000 \
  --api-permissions 5b567253-7703-48e2-861c-caed61531407=Role

# Tasks.ReadWrite.All
az ad app permission add \
  --id $APP_ID \
  --api 00000003-0000-0000-c000-000000000000 \
  --api-permissions bdfbf15f-ee85-495a-99a9-ef9b2abb1dcb=Role

# Admin Consent
az ad app permission admin-consent --id $APP_ID

Step 3: Create Client Secret

Azure Portal:

  1. App → Certificates & secrets → Client secrets → New client secret
  2. Description: OpenClaw Integration
  3. Expires: 24 months (Maximum)
  4. Copy values immediately! – Only shown once

Or via Azure CLI:

az ad app credential reset \
  --id $APP_ID \
  --append \
  --display-name "OpenClaw Integration"

Step 4: Configure Environment

Store credentials in ~/.openclaw/.env:

# Microsoft 365 Planner Credentials
M365_CLIENT_ID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
M365_CLIENT_SECRET="your-secret-value"
M365_TENANT_ID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

Secure permissions:

chmod 600 ~/.openclaw/.env

Step 5: Test Connection

node scripts/test-connection.js

Expected output:

✅ Access Token successfully received!
📋 Test: M365 Groups...
   3 groups found:
   - My Team ✅ M365/Planner-capable
✅ Connection successful!

Important Notes

M365 Groups vs. Security Groups

Planner ONLY works with M365 Groups!

  • M365 Group – Has Exchange mailbox, Teams, Planner (recognizable by mail attribute)
  • Security Group – Only for permissions, no Planner
  • Distribution List – Only for email distribution, no Planner

Check groups:

node scripts/test-connection.js

Shows all groups with status "✅ M365/Planner-capable".

Create M365 Group (if none exists):

  • Microsoft 365 Admin Center → Groups → Add a group
  • Or Teams: Create new team (automatically creates M365 Group)

If-Match Header (ETag)

All update and delete operations require the If-Match header!

Planner uses Optimistic Concurrency Control. Requests fail without ETag.

Delete Example:

// Wrong ❌
await client.api(`/planner/tasks/${taskId}`).delete();

// Correct ✅
const task = await client.api(`/planner/tasks/${taskId}`).get();
await client.api(`/planner/tasks/${taskId}`)
    .headers({ 'If-Match': task['@odata.etag'] })
    .delete();

Update Example:

const task = await client.api(`/planner/tasks/${taskId}`).get();
await client.api(`/planner/tasks/${taskId}`)
    .headers({ 'If-Match': task['@odata.etag'] })
    .update({ percentComplete: 50 });

Group-Based API Endpoints

Do NOT use:

GET /planner/plans  ❌ (requires complex filter)

Use:

GET /groups/{group-id}/planner/plans  ✅

Example:

const plans = await client.api(`/groups/${groupId}/planner/plans`).get();

Recurring Tasks

Microsoft Planner supports native recurring tasks!

In Planner Web UI or Mobile App:

  1. Open task
  2. Click "Repeat"
  3. Choose frequency: Daily, Weekly, Monthly, Yearly, Custom

Example:

  • "Domain renewal example.com" → Repeat yearly
  • "Check backup" → Repeat weekly

⚠️ API Limitation: The Graph API does not support creating recurring tasks directly.

Recurring tasks must be set up via Planner UI.

Common Operations

Plans

OperationScript
-------------------
List all plansnode scripts/list_plans.js
Create plannode scripts/create_plan.js
Delete plannode scripts/delete_plan.js

Buckets

OperationScript
-------------------
List bucketsIntegrated in list_plans.js
Create bucketnode scripts/create_bucket.js
Delete bucketnode scripts/delete_bucket.js

Tasks

OperationScript
-------------------
List tasksIntegrated in list_plans.js
Create tasknode scripts/create_task.js </code></td></tr><tr><td>Update task</td><td><code>node scripts/update_task.js <task-id> --percent-complete 50</code></td></tr><tr><td>Delete task</td><td><code>node scripts/delete_task.js <task-id></code></td></tr><tr><td>Cleanup</td><td><code>node scripts/cleanup_verlaengerungen.js <group-id> "<plan-name>" "<bucket-name>"</code></td></tr></tbody></table><h2>Helper Scripts</h2><h3>test-connection.js</h3><p>Tests connection to Microsoft Graph:</p><ul><li>Request access token</li><li>Display tenant information</li><li>List available M365 Groups</li><li>Check Planner capability</li></ul><pre><code>node scripts/test-connection.js </code></pre><h3>list_plans.js</h3><p>Shows all plans in an M365 Group with:</p><ul><li>Buckets and their tasks</li><li>Task status (completed/in progress/open)</li><li>Percentage progress indicator</li></ul><pre><code># Without argument: Shows all available groups node scripts/list_plans.js # With Group ID: Shows plans for specific group node scripts/list_plans.js <group-id> </code></pre><h3>create_plan.js</h3><p>Creates a new plan with default buckets:</p><ul><li>To Do</li><li>In Progress </li><li>Done</li></ul><pre><code>node scripts/create_plan.js "Project Alpha" <group-id> </code></pre><h3>cleanup_verlaengerungen.js</h3><p>Cleans up completed tasks from a bucket:</p><ul><li>Deletes tasks with 100% progress</li><li>Keeps open tasks</li><li>Correct If-Match header handling</li></ul><pre><code>node scripts/cleanup_verlaengerungen.js <group-id> "<plan-name>" "<bucket-name>" </code></pre><p><strong>Example:</strong></p><pre><code>node scripts/cleanup_verlaengerungen.js abc-123 "My Project" "Completed" </code></pre><h2>Troubleshooting</h2><h3>Error: Insufficient privileges</h3><p><strong>Cause:</strong> Admin consent not granted</p><p><strong>Solution:</strong></p><pre><code>az ad app permission admin-consent --id <app-id> </code></pre><p>Or in Azure Portal: API permissions → Grant admin consent</p><h3>Error: Group not found</h3><p><strong>Cause:</strong> Planner only works with M365 Groups</p><p><strong>Solution:</strong></p><ol><li>Check if it's an M365 Group (has mail attribute)</li><li>Security Groups/Distribution Lists don't work</li><li>Create new M365 Group (Teams or Admin Center)</li></ol><h3>Error: The If-Match header must be specified</h3><p><strong>Cause:</strong> Update/Delete without ETag</p><p><strong>Solution:</strong></p><pre><code>// First get task for ETag const task = await client.api(`/planner/tasks/${id}`).get(); // Then update/delete with If-Match header await client.api(`/planner/tasks/${id}`) .headers({ 'If-Match': task['@odata.etag'] }) .delete(); </code></pre><h3>Error: This entity set must be queried with a filter</h3><p><strong>Cause:</strong> <code>/planner/plans</code> endpoint requires filter</p><p><strong>Solution:</strong> Use group-based endpoint:</p><pre><code>// Wrong ❌ const plans = await client.api('/planner/plans').get(); // Correct ✅ const plans = await client.api(`/groups/${groupId}/planner/plans`).get(); </code></pre><h3>Error: Cannot find module '@microsoft/microsoft-graph-client'</h3><p><strong>Cause:</strong> Node.js packages not installed</p><p><strong>Solution:</strong></p><pre><code>cd ~/.openclaw/workspace/skills/m365-planner npm install </code></pre><h2>Dependencies</h2><p>Install packages locally in skill directory:</p><pre><code>cd ~/.openclaw/workspace/skills/m365-planner npm install @microsoft/microsoft-graph-client axios </code></pre><h2>References</h2><ul><li><a href="references/planner-api.md" target="_blank" rel="noopener">Planner API Overview</a></li><li><a href="references/setup-guide.md" target="_blank" rel="noopener">Setup Guide</a></li><li><a href="references/common-patterns.md" target="_blank" rel="noopener">Common Patterns</a></li><li><a href="https://docs.microsoft.com/en-us/graph/api/overview" target="_blank" rel="noopener">Microsoft Graph API Docs</a></li><li><a href="https://docs.microsoft.com/en-us/graph/api/resources/planner-overview" target="_blank" rel="noopener">Planner REST API Reference</a></li></ul><h2>Changelog</h2><h3>v1.2.3 (2026-04-18)</h3><ul><li>🌍 <strong>English Documentation</strong> – Complete translation for international ClawHub availability</li><li>🔧 <strong>Portability</strong> – Env path uses <code>os.homedir()</code> for cross-system compatibility</li><li>🧹 <strong>Security Audit</strong> – No hardcoded IDs, names, or domains</li></ul><h3>v1.2.2 (2026-04-18)</h3><ul><li>🔧 <strong>Portability</strong> – Env path now uses <code>os.homedir()</code> instead of hardcoded <code>/home/claw/.openclaw/.env</code></li><li>🧹 <strong>Security Cleanup</strong> – Full audit for sensitive data (no IDs, names, domains)</li><li>📦 <strong>ClawHub-ready</strong> – Tarball created, node_modules excluded</li></ul><h3>v1.2.1 (2026-04-18)</h3><ul><li>✅ <strong>Generic Scripts</strong> – No hardcoded Group-IDs or Plan names anymore</li><li>✅ <strong>Command-Line Parameters</strong> – All scripts accept IDs as arguments</li><li>✅ <strong>List Plans Improved</strong> – Shows all groups when no ID provided</li><li>✅ <strong>Flexible Cleanup</strong> – Works with any plans/buckets</li><li>✅ <strong>ClawHub-ready</strong> – No project-specific data included</li></ul><h3>v1.1.0 (2026-04-17)</h3><ul><li>✅ Node.js Scripts instead of mgc CLI</li><li>✅ If-Match Header Support for updates/deletes</li><li>✅ Group-based API Endpoints</li><li>✅ Test-Connection Script with M365 Group Detection</li><li>✅ List Plans Script with Bucket/Task overview</li><li>✅ Cleanup Script for completed tasks</li><li>✅ Documentation for recurring tasks (native Planner feature)</li><li>✅ Troubleshooting Section expanded</li></ul><h3>v1.0.0 (2023-01-19)</h3><ul><li>Initial version with mgc CLI</li><li>Azure AD Setup Guide</li><li>Basic CRUD operations</li></ul></div> </div> </div> <div id="tab-versions" class="detail-content"> <div class="detail-section"> <h2>版本历史</h2> <p style="margin-bottom:12px;font-size:14px;color:#94a3b8;">共 1 个版本</p> <ul class="version-list"> <li> <div> <span class="version-tag">v1.2.3</span> <span style="font-size:11px;color:#5b6abf;margin-left:8px;background:#eef0ff;padding:1px 8px;border-radius:10px;">当前</span> </div> <div style="font-size:12px;color:#94a3b8;"> 2026-05-07 08:54 安全 安全 </div> </li> </ul> </div> </div> <div id="tab-security" class="detail-content"> <div class="detail-section"> <h2>安全检测</h2> <div class="sec-grid"> <div class="sec-card"> <h4>腾讯云安全 (Keen)</h4> <div class="sec-status sec-safe"> 安全,无风险 </div> <a href="https://tix.qq.com/search/skill?keyword=8713b79da72515a14bd09790546ca588" target="_blank">查看报告</a> </div> <div class="sec-card"> <h4>腾讯云安全 (Sanbu)</h4> <div class="sec-status sec-safe"> 安全,无风险 </div> <a href="https://static.cloudsec.tencent.com/html-report-v2/2026/05/26/439903_0e3b4b0bfd8621772c602cfa6709bc24.html?q-sign-algorithm=sha1&q-ak=AKID8JMG1bzBC1dz96qNhssfFftujT1NCoFi&q-sign-time=1782771150%3B1814307150&q-key-time=1782771150%3B1814307150&q-header-list=host&q-url-param-list=&q-signature=74995385b9913eefd96aa11e43a485ace8ad5911" target="_blank">查看报告</a> </div> </div> </div> </div> <!-- Recommended Skills --> <div style="margin-top:24px;"> <h2 style="font-size:18px;font-weight:600;margin-bottom:16px;">🔗 相关推荐</h2> <div class="rec-grid"> <div class="rec-card"> <span class="badge-cat" style="margin-bottom:8px;display:inline-block;">office-efficiency</span> <h3><a href="/s/word-docx">Word / DOCX</a></h3> <div class="rec-owner">ivangdavila</div> <div class="rec-desc">创建、检查和编辑 Microsoft Word 文档及 DOCX 文件,支持样式、编号、修订记录、表格、分节符及兼容性检查等功能。</div> <div class="rec-stats"> <span style="color:#f39c12;">★ 468</span> <span style="color:#5b6abf;">📥 156,035</span> </div> </div> <div class="rec-card"> <span class="badge-cat" style="margin-bottom:8px;display:inline-block;">office-efficiency</span> <h3><a href="/s/gog">Gog</a></h3> <div class="rec-owner">steipete</div> <div class="rec-desc">Google Workspace 命令行工具,支持 Gmail、日历、云端硬盘、通讯录、表格和文档。</div> <div class="rec-stats"> <span style="color:#f39c12;">★ 934</span> <span style="color:#5b6abf;">📥 187,474</span> </div> </div> <div class="rec-card"> <span class="badge-cat" style="margin-bottom:8px;display:inline-block;">office-efficiency</span> <h3><a href="/s/nano-pdf">Nano Pdf</a></h3> <div class="rec-owner">steipete</div> <div class="rec-desc">使用nano-pdf CLI通过自然语言指令编辑PDF</div> <div class="rec-stats"> <span style="color:#f39c12;">★ 281</span> <span style="color:#5b6abf;">📥 117,087</span> </div> </div> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded',function(){ document.querySelectorAll('.detail-tab').forEach(function(btn){ btn.addEventListener('click',function(e){ var tab = this.getAttribute('data-tab'); document.querySelectorAll('.detail-tab').forEach(function(b){b.classList.remove('active')}); document.querySelectorAll('.detail-content').forEach(function(c){c.classList.remove('active')}); this.classList.add('active'); var el = document.getElementById('tab-'+tab); if(el) el.classList.add('active'); }); }); }); </script> <div class="footer"> <p>Skill工具集 © 2026</p> </div></body> </html>