【実務・中級編】PenpotのWebhooksとAPI連携入門:デザイン変更を自動検知して通知・管理する方法 – UI/UX・デザインツール活用バイブル

Penpot Webhooks & API実践ガイド:デザインの「暗黙知」をコードと連携させ、開発速度を限界突破させる方法

こんにちは。テックリードの私たちが日々直面する最大のボトルネックは何でしょうか?
それは「デザインの変更がエンジニアに伝わるまでのタイムラグ」であり、「Figma(あるいはPenpot)のキャンバス上で何が起きたのかを、コードベースに手動で同期し続けるという不毛な作業」です。

オープンソースのプロトタイピングツール「Penpot」の真骨頂は、単に「オープンソースでFigmaっぽいことができる」という点ではありません。システムアーキテクチャの根幹にAPIファーストとWebhooksを据えていること、そしてDocker等でセルフホストして社内インフラと完全に統合できる拡張性にあります。

今回は、PenpotのWebhooksとAPIを駆使し、デザインの変更を自動検知してSlackやGitHubへシームレスに連携させる、現場で即座に使える実践知を伝授します。

—

1. 開発スピードを劇的に高めるPenpotの隠れたキーボードショートカット

自動化の前に、まず私たちの手元の速度を極限まで引き上げましょう。Penpotをただの「お絵描きツール」として使っているなら、それは宝の持ち腐れです。コンポーネント指向を意識した設計スピードを上げるためのショートカットを厳選しました。

  • `Shift + A`(AutoLayoutの適用):

エンジニアのFlexboxメンタルモデルと完全に一致する機能です。コンポーネントをグループ化し、一瞬でレスポンシブなコンテナ構造を作ります。

  • `Ctrl + Alt + K` (コンポーネントの作成):

デザインシステムにおける「原子(Atom)」を定義します。ここにつけた名前が、そのままAPI経由で取得する際のコンポーネント名になります。命名規則(例: `button/primary/md`)の徹底が、後のAPI連携の成否を分けます。

  • `Alt + ドラッグ`(インスタンスのスマート複製 & プロパティ継承):

デザイン変更の差分(Diff)を最小限に抑えるため、極力マスターコンポーネントから派生させます。

  • `Z` + ドラッグ(精緻なズームイン):

複雑なデザインシステムのマトリクスを確認する際、マウスホイールのスクロールロスをゼロにします。

—

2. チーム開発の秩序を守る!絶対入れるべき神機能・プラグイン&設定共有ルール

Penpotの強力なアドバンテージは、SVGネイティブであることと、ブラウザベースで完結する点です。チーム開発を破綻させないための「設定の共有化ルール」を定義します。

チーム開発の鉄則:デザインシステムの「Git管理」と同期

デザインの変更履歴を追うだけならGitは不要ですが、「どのバージョンのデザインが、どのAPIのバージョンに対応しているか」を紐付けるには、PenpotのTeam(チーム)設定とWebhooksの組み合わせが不可欠です。

1. カラーパレットとタイポグラフィのトークン化:
チーム共通のワークスペースには、必ずCSS Variables(Custom Properties)と完全一致する命名規則でDesign Tokensを登録します。
2. Webhooksエンドポイントの集中管理:
チーム管理者は、ワークスペース設定から「Webhook URLs」を登録し、イベントの送信先(後述の的中サーバーやAPI Gateway)を1箇所に集約します。

—

3. 実践:Penpot Webhooks & API連携アーキテクチャ

ここからが本題です。Penpotでデザインが更新された瞬間(`board.update` や `component.changed` など)にWebhooksを発火させ、Slackへ通知し、さらにGitHub Actionsを叩いてデザインデータのJSONを自動生成・コミットするパイプラインを構築します。

全体像

[ Penpot Editor ]
│ (デザイン変更)
▼
[ Penpot Server ]
│ (Webhooks: POST)
▼
[ Middleware (Node.js / AWS Lambda 等) ]
├──> [ Slack API ] (チャンネルへ通知)
└──> [ GitHub API ] (リポジトリへデザイン差分をPR作成)

—

4. 実用的な設定ファイル・スクリプトのベストプラクティス

ここでは、PenpotのAPIを叩き、Webhookを受け取って処理するための実用的な設定ファイルとコード群を提示します。

A. Webhookを受け取るミドルウェアのサーバーレス設定 (serverless.yml)

AWS LambdaとAPI Gatewayを使用し、PenpotからのWebhookをセキュアに受け取るための構成例です。

serverless.yml
service: penpot-webhook-integrator
frameworkVersion: ‘3’

provider:
name: aws
runtime: nodejs18.x
region: ap-northeast-1
environment:
SLACK_WEBHOOK_URL: ${env:SLACK_WEBHOOK_URL}
GITHUB_TOKEN: ${env:GITHUB_TOKEN}
PENPOT_SECRET_TOKEN: ${env:PENPOT_SECRET_TOKEN} # Webhook検証用シークレット

functions:
webhookHandler:
handler: handler.handle
events:

  • httpApi:

path: /webhook/penpot
method: post

B. Webhookイベントを解析し、Slack & GitHubへ流す処理 (handler.js)

Penpotから送られてきたペイロードを検証し、デザインの変更を検知してアクションを起こすNode.jsのコードです。

// handler.js
const crypto = require(‘crypto’);
const axios = require(‘axios’);

/

  • PenpotからのWebhookを受け取り、Slack通知およびGitHubとの連携を行うハンドラー

/
exports.handle = async (event) => {
const signature = event.headers[‘x-penpot-signature’] || ”;
const body = event.body;

// 1. セキュリティ検証(HMAC-SHA256署名チェック)
if (!verifySignature(body, signature, process.env.PENPOT_SECRET_TOKEN)) {
console.warn(‘Invalid signature detected.’);
return { statusCode: 401, body: JSON.stringify({ message: ‘Unauthorized’ }) };
}

const payload = JSON.parse(body);
const { eventType, projectId, projectName, author } = payload;

console.log(`[Penpot Event] Type: ${eventType}, Project: ${projectName} by ${author}`);

// 2. イベントに応じた処理の分岐
try {
if (eventType === ‘project.updated’ || eventType === ‘component.modified’) {
// Slackへ通知を送信
await sendSlackNotification(projectName, author, eventType);

// 必要に応じてGitHub Actionsをトリガー(デザイン変更に伴う自動モック生成など)
await triggerGitHubWorkflow(projectName);
}

return { statusCode: 200, body: JSON.stringify({ success: true }) };
} catch (error) {
console.error(‘Error processing webhook:’, error);
return { statusCode: 500, body: JSON.stringify({ error: error.message }) };
}
};

/

  • ペイロードの署名を検証するヘルパー関数

/
function verifySignature(body, signature, secret) {
if (!secret) return true; // シークレット未設定時はスキップ(開発環境用)
const hmac = crypto.createHmac(‘sha256’, secret);
const digest = hmac.update(body).digest(‘hex’);
return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(digest));
}

/

  • Slackへのリッチ通知送信

/
async function sendSlackNotification(projectName, author, eventType) {
const slackUrl = process.env.SLACK_WEBHOOK_URL;
if (!slackUrl) return;

const message = {
blocks: [
{
type: “section”,
text: {
type: “mrkdwn”,
text: `🎨 Penpot デザイン更新検知\nプロジェクト: ${projectName}\n担当者: ${author}\nイベント: \`${eventType}\“
}
},
{
type: “actions”,
elements: [
{
type: “button”,
text: { type: “plain_text”, text: “Penpotで確認する” },
url: “https://your-penpot-instance.com/dashboard” // 実際のPenpotインスタンスURL
}
]
}
]
};

await axios.post(slackUrl, message);
}

/

  • GitHub API経由でワークフローをトリガーする

/
async function triggerGitHubWorkflow(projectName) {
const githubToken = process.env.GITHUB_TOKEN;
if (!githubToken) return;

const repoOwner = ‘your-org’;
const repoName = ‘your-frontend-repo’;

// GitHub Actionsの repository_dispatch イベントを発火
await axios.post(
`https://api.github.com/repos/${repoOwner}/${repoName}/dispatches`,
{
event_type: ‘penpot_design_update’,
client_payload: { project: projectName, timestamp: new Date().toISOString() }
},
{
headers: {
Authorization: `Bearer ${githubToken}`,
Accept: ‘application/vnd.github+json’
}
}
);
}

C. GitHub Actions側の受け取り設定 (.github/workflows/design-sync.yml)

Penpot側でデザインが変更された際、GitHub側で自動的にトークンの同期や、変更レポートの生成を行うCI/CDの設定ファイルです。

.github/workflows/design-sync.yml
name: Sync Penpot Design Tokens

on:
repository_dispatch:
types: [penpot_design_update]

jobs:
sync:
runs-on: ubuntu-latest
steps:

  • name: Checkout Repository

uses: actions/checkout@v3

  • name: Set up Node.js

uses: actions/setup-node@v3
with:
node-version: ’18’

  • name: Install Dependencies

run: npm ci

  • name: Fetch Latest Design Tokens from Penpot API

env:
PENPOT_API_TOKEN: ${{ secrets.PENPOT_API_TOKEN }}
PENPOT_API_URL: ${{ secrets.PENPOT_API_URL }}
run: |
# Penpot APIを叩いて最新のトークンJSONをダウンロードするスクリプトを実行
node scripts/fetch-penpot-tokens.js

  • name: Create Pull Request if changes exist

uses: peter-evans/create-pull-request@v5
with:
commit-message: “chore(design): sync latest tokens from Penpot”
title: “🎨 自動デザイン同期: Penpotの更新を検知しました”
body: |
Penpotでのデザイン変更が検知されたため、自動的にデザイントークンを同期しました。
差分を確認し、コンポーネントの実装に反映させてください。
branch: chore/penpot-design-sync
signoff: true

—

5. テックリードからの総括:真の「Design-Code Integration」へ向けて

今回の構成を導入することで、デザインチームがPenpot上でコンポーネントを修正した瞬間、Slackに通知が飛び、バックグラウンドでGitHubが動き出し、コードベースとの差分を検知するパイプラインが完成します。

「デザイナーが変更をチャットで連絡し、エンジニアが手動でFigma/Penpotを覗きに行って数値を確認する」という前近代的なワークフローは、今日で終わりにしましょう。

PenpotのオープンなAPIとWebhooksをハックし、デザインとコードの境界線をなくすこと――それこそが、プロダクトのデリバリー速度をネクストレベルへと引き上げる唯一の解なのです。さあ、今すぐあなたのセルフホスト環境で試してみてください。

タイトルとURLをコピーしました