技能 编程开发 Miro API集成:画板操作指南

Miro API集成:画板操作指南

v20260423
miro-hello-world
这是一个基于TypeScript的全面实战教程,演示了如何通过Miro REST API v2进行程序化操作。用户可以学习如何完整管理画板的生命周期,包括创建画板、添加不同类型的元素(便签、形状)、使用连接器连接元素,以及读取所有板上内容。适用于学习Miro集成或自动化工作流的场景。
获取技能
81 次下载
概览

Miro Hello World

Overview

Minimal working example: create a board, add a sticky note, add a shape, connect them, and read the results back — all using the Miro REST API v2.

Prerequisites

  • Completed miro-install-auth setup
  • Valid access token with boards:read and boards:write scopes
  • @mirohq/miro-api installed

Instructions

Step 1: Create a Board

import { MiroApi } from '@mirohq/miro-api';

const api = new MiroApi(process.env.MIRO_ACCESS_TOKEN!);

async function createBoard() {
  // POST https://api.miro.com/v2/boards
  const response = await api.createBoard({
    name: 'Hello World Board',
    description: 'Created via REST API v2',
    policy: {
      sharingPolicy: {
        access: 'private',          // 'private' | 'view' | 'comment' | 'edit'
        inviteToAccountAndBoardLinkAccess: 'no_access',
      },
      permissionsPolicy: {
        collaborationToolsStartAccess: 'all_editors',
        copyAccess: 'anyone',
        sharingAccess: 'owners_and_coowners',
      },
    },
  });

  const boardId = response.body.id;
  console.log(`Board created: ${boardId}`);
  console.log(`View at: https://miro.com/app/board/${boardId}/`);
  return boardId;
}

Step 2: Add a Sticky Note

async function addStickyNote(boardId: string) {
  // POST https://api.miro.com/v2/boards/{board_id}/sticky_notes
  const response = await fetch(
    `https://api.miro.com/v2/boards/${boardId}/sticky_notes`,
    {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${process.env.MIRO_ACCESS_TOKEN}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        data: {
          content: 'Hello from the API!',
          shape: 'square',          // 'square' | 'rectangle'
        },
        style: {
          fillColor: 'light_yellow', // light_yellow | light_green | light_blue | light_pink | etc.
          textAlign: 'center',       // 'left' | 'center' | 'right'
          textAlignVertical: 'middle',
        },
        position: { x: 0, y: 0 },
        geometry: { width: 200 },
      }),
    }
  );

  const note = await response.json();
  console.log(`Sticky note created: ${note.id} (type: ${note.type})`);
  return note.id;
}

Step 3: Add a Shape

async function addShape(boardId: string) {
  // POST https://api.miro.com/v2/boards/{board_id}/shapes
  const response = await fetch(
    `https://api.miro.com/v2/boards/${boardId}/shapes`,
    {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${process.env.MIRO_ACCESS_TOKEN}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        data: {
          content: 'Next Step',
          shape: 'round_rectangle',  // rectangle | circle | triangle | rhombus | round_rectangle | etc.
        },
        style: {
          fillColor: '#4262ff',
          fontFamily: 'arial',
          fontSize: 14,
          textAlign: 'center',
          borderColor: '#1a1a2e',
          borderWidth: 2,
          borderStyle: 'normal',     // 'normal' | 'dashed' | 'dotted'
        },
        position: { x: 400, y: 0 },
        geometry: { width: 200, height: 100 },
      }),
    }
  );

  const shape = await response.json();
  console.log(`Shape created: ${shape.id} (type: ${shape.type})`);
  return shape.id;
}

Step 4: Connect Items with a Connector

async function connectItems(boardId: string, startId: string, endId: string) {
  // POST https://api.miro.com/v2/boards/{board_id}/connectors
  const response = await fetch(
    `https://api.miro.com/v2/boards/${boardId}/connectors`,
    {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${process.env.MIRO_ACCESS_TOKEN}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        startItem: { id: startId },
        endItem: { id: endId },
        captions: [{ content: 'leads to' }],
        style: {
          strokeColor: '#1a1a2e',
          strokeWidth: 2,
          startStrokeCap: 'none',
          endStrokeCap: 'stealth',   // none | stealth | arrow | filled_triangle | etc.
        },
      }),
    }
  );

  const connector = await response.json();
  console.log(`Connector created: ${connector.id}`);
  return connector.id;
}

Step 5: List All Items on the Board

async function listBoardItems(boardId: string) {
  // GET https://api.miro.com/v2/boards/{board_id}/items
  // Returns cursor-paginated results
  const response = await fetch(
    `https://api.miro.com/v2/boards/${boardId}/items?limit=50`,
    {
      headers: {
        'Authorization': `Bearer ${process.env.MIRO_ACCESS_TOKEN}`,
      },
    }
  );

  const result = await response.json();
  console.log(`Board has ${result.data.length} items:`);
  for (const item of result.data) {
    console.log(`  - ${item.type}: ${item.id} (${item.data?.content ?? 'no content'})`);
  }

  // Handle pagination
  if (result.cursor) {
    console.log(`More items available. Next cursor: ${result.cursor}`);
  }
}

Step 6: Run the Complete Flow

async function main() {
  const boardId = await createBoard();
  const noteId = await addStickyNote(boardId);
  const shapeId = await addShape(boardId);
  await connectItems(boardId, noteId, shapeId);
  await listBoardItems(boardId);
  console.log('\nDone! Open the board in Miro to see your items.');
}

main().catch(console.error);

Miro REST API v2 Item Types

Type Create Endpoint Key Properties
sticky_note /v2/boards/{id}/sticky_notes content, shape, fillColor
shape /v2/boards/{id}/shapes content, shape, fillColor, borderStyle
card /v2/boards/{id}/cards title, description, dueDate, assigneeId
text /v2/boards/{id}/texts content, fontSize
frame /v2/boards/{id}/frames title, showContent, childrenIds
image /v2/boards/{id}/images url or data (base64)
document /v2/boards/{id}/documents url
embed /v2/boards/{id}/embeds url
app_card /v2/boards/{id}/app_cards title, description, fields, status
connector /v2/boards/{id}/connectors startItem, endItem, captions

All create endpoints require boards:write scope. All GET endpoints require boards:read.

Error Handling

Error HTTP Status Cause Solution
boardNotFound 404 Invalid board_id Verify board exists and token has access
insufficientPermissions 403 Missing boards:write Add scope in app settings
invalidInput 400 Bad request body Check required fields per item type
rateLimitExceeded 429 Too many requests Implement backoff (see miro-rate-limits)

Resources

Next Steps

Proceed to miro-local-dev-loop for development workflow setup, or miro-core-workflow-a for board management patterns.

信息
Category 编程开发
Name miro-hello-world
版本 v20260423
大小 7.6KB
更新时间 2026-04-28
语言