こんにちは、みみです。
これは、Figma アドベントカレンダー 2021 22日目の記事です。
せっかくFigmaのアドベントカレンダーに参加したのでデザイナーぽい記事を書こうかなと思ったのですが、それっぽい記事をお世話になっているVektor, Inc.のアドベントカレンダーに書いたばっかり(VektorチームでFigmaを1年使ってみての所感と、Vektorブランドガイドラインのリリース | 株式会社ベクトル)なので、こちらは前々からやりたかったFigma APIをつかってゴニョゴニョしてみたのを書いてみようと思います。
デザイナーだけどFigma API何者か気になる、的な人にも分かるように書いてみた、つもりです。分からない処があったらそっと聞いてください。分かっている人で間違えを見つけたらそっと教えてください。Twitterはこちらです。
Figma API についての公式ドキュメントはこちら
https://www.figma.com/developers/api
といってもですね、既に素敵なライブラリとかプラグインはいくつも存在するので、ちゃっちゃと作りたい人はそちらを活用するのをオススメします。
今回は、私が全然把握してなかったFigma APIの仕様を確認するのが主な目的で、指定したファイルのコンポーネントをアセットファイルをpngとsvgで書き出してZIPするのを1コマンドで出来るものを作ってみました。
ベースのラッパーはこちらを活用。
figma-js
https://github.com/jongold/figma-js
そして、基本的にこちらのライブラリを参考にして、ほぼ写経しながら学ばせてもらいました。
ohkimur/figma-assets-export: Export assets from Figma and download them as local files.
https://github.com/ohkimur/figma-assets-export
実は、最初はこのライブラリだけで楽勝じゃん、よーしReactでWebアプリかプラグインにしちゃうかーなどと妄想していたのですが、そもそもFigma APIの仕様が分かってないためにうまく活用出来ず。Reactで書こうとしたり、TypeScript化しようとしたり大分と右往左往したのですが、その辺りはFigmaアドベントカレンダー的には要らないと思うので割愛しますw
というわけで、いったん極シンプルに、JSでZIPが出来るものを作ってみました。
Figma APIのしくみを試してみよう
まずは、Figma APIがどんなものか、直接アクセスしてみます。
Figma API / GET file
https://www.figma.com/developers/api#get-files-endpoint
ここのページで右側にある黒いエリアの処にあるfile_key
に試してみたいFigmaのファイルのファイルキーを入力します。
ファイルIDは各FigmaのファイルURLのhttps://www.figma.com/file/xxxxxxxx/
以下の文字列xxxxxxxxx
の部分です。
アクセストークンというものが必要なのですが、Figmaにログインしていれば、「+ Get personal access token」というリンクをクリックすると自動で取得されます。
その状態で、「Submit API Request」ボタンを押してしばし待てば、Loading… エリアに何やら以下のような文字列がつらつらと書かれます。
{
"document": {
"id": "0:0",
"name": "Document",
"type": "DOCUMENT",
"children": [
{
"id": "0:1",
"name": "Page 1",
"type": "CANVAS",
// 中略
}
]
},
"components": {
"1:2": {
"key": "xxxxx",
"name": "color=Default",
"description": "",
"componentSetId": "1:5",
"documentationLinks": []
},
"1:6": {
"key": "xxxxx",
"name": "color=Knockout",
"description": "",
"componentSetId": "1:5",
"documentationLinks": []
}
},
"componentSets": {
"1:5": {
"key": "xxxxx",
"name": "photosynthesic_icon",
"description": ""
}
},
"schemaVersion": 0,
"styles": {},
"name": "figma_api_test",
"lastModified": "2021-12-19T13:39:15Z",
"thumbnailUrl": "xxxxx",
"version": "1395982838",
"role": "owner",
"editorType": "figma",
"linkAccess": "view"
}
といった感じで、JSON形式で指定したファイルの情報が返ってきます。
cURL(コマンドラインツール)で試したい人のために、コマンドも生成してくれるので、ターミナルかiTerm、VS Codeのターミナルでも良いのでコピペしてreturnしたら、同じ結果が得られるでしょう。
Figma Advent Calendar 2021 の3日目の記事 Figmaのコメント一覧をさっと取得したいなあ…… – Qiita で、綿貫さんがコメント一覧を取得するcURLを試してらっしゃるので参考になるかもです。
さて後は、この文字列から、必要な情報だけ抜き出して良きに計らえば良いのでざっと書いてみました(ほんとうはここがたいへんでしたがry)。
拙作リポジトリの試し方
という訳で、お試し用のファイルを作ってみたので、もしお暇な方がいらっしゃったらどうぞ。Duplicateしてお試しください。
figma_api_test – Figma
https://www.figma.com/file/MfHUbW7xefpYqEE4s7b5pI/figma_api_test?node-id=0%3A1
こちらのファイルからコンポーネント化されているアイコン2種類をSVGとPNGファイルでダウンロードしてきて同じファイル名のzip化することができます。
別にお手持ちのコンポーネントがある好きなFigmaファイルでも良いのですが、コンポーネントがあんまりに多すぎる場合にタイムアウトする気がしなくもないのでご利用は計画的に。何かあっても当方は一切の責任を負いかねます。試すならシンプルなファイルにしてみたほうが良いと思います。
拙作リポジトリ
https://github.com/miminari/figma-zipper
動作には Node (npm) が必要です。17系で作ってみています。
リポジトリをクローンまたはZIPダウンロードして展開したら
npm i
してください。
コードの本体はhttps://github.com/miminari/figma-zipper/blob/main/index.mjsです。
.env(dotenv)を設定する必要があります
Figma APIを使うには、最低限トークンとファイルのID(またはファイルのURL)が必要です。
トークンについてはアクセストークンを取得 – Figma | nju33などを参考に取得してみてください。
リポジトリを試すには.env
ファイルをリポジトリの直下に作成し、以下のように記述したらOKです。
FIGMA_TOKEN = xxxxxxxx
FIGMA_FILE_ID = xxxxxxxxxx
あとは
npm run zip
でzipファイルが生成されるはずです。やったね 🎉
Figma APIのエンドポイントを見つけてカスタムしてみよう
これだけだと、それでどうした?という感じなので、figma-jsの使い方をメモしておきます。
先ずはクライアントを呼び出し
これは、figma-jsのREADMEに書いてある通りに。
const client = Figma.Client({ personalAccessToken: process.env.FIGMA_TOKEN || '' });
ファイルのコンポーネントを取得
const file = await client.file(ここにファイルキー);
const fileComponents = file.data.components;
ここからはもう少し踏み込んで、オプションとかの扱い方を見てみましょう。
pngを2xで書き出したい(画像データの取得)
最初スケールの設定いれてなかったのですが、何も設定しないとPNGが1倍で出てくるので、2xにしてみました。
先ずは、Figma APIのドキュメントを見て、エンドポイントがあるか確認します(大体何でも取れるから確認しなくても良いけれど、構造理解のためにもみてみましょう)。
画像関連のエンドポイントについてはGET imageに書かれています。
「Query parameters」の一覧にある「scale」がそれっぽいですね。0.01〜4の数値で、画像の拡大縮小率を指定できる、とあります。動作が不安だったら、右側の黒いお試しツールで試すことができます。
で、今回はfigma-jsというラッパーを使っているので、こちらの仕様でどう書いたらいいか確認します。
figma-js > Interface FileImageParams > scale
https://jongold.github.io/figma-js/interfaces/fileimageparams.html#scale
同じく`scale`で、数値を渡したら良いらしいということが分かります。なのでこんな感じ。
const response = await client.fileImages(ここにファイルキー, {
ids: [画像のID],
format: PNG,
scale: 2
})
…ここでタイムアップ!
というところまでカスタムしてみた処で、アドベントカレンダーの期日が来てしまったので、今回はここまで。
次回?以降にやりたいことのメモを書いておきます。
Variantsの名前とコンポーネントの名前をちゃんとファイル名に入れたい
Variantsを使っていると、filenameが`color=Default.svg`みたいになっちゃうんですよね。これをちゃんとコンポーネントの名前とVariantsにしたいのですが、figma-jsが対応していないぽいので、自力でgotかaxiosか何か使ってAPI叩くところを作るか、figma-jsにPR投げないといけない感じ。
figma-jsもPublishしているコンポーネントだと取れる気がするので、まずはPublishしているファイルを作って試してみようと思います。そもそもPublishしていないデータを取れて良いのかという気がしたけれどトークン使うからまあ気にしなくて良いはず。
その他
- 書き出したものを自動アップロードさせたい
- 画像最適化したい
- 保存形式を簡単に指定できるようにしたい
- プラグイン化してみる?
- TypeScript化
- TestとLint入れる
- リクエストがデカイとどうなるか検証(タイムアウト対策)
などなど…年末年始の遊びが充実しそうです。
Figmaからコンポーネント取ってきて画像ブロック化してくれるWordPressプラグインとかもできそうですが、需要が迷子ですね。コンポーネントを一気にCSSのインライン化してくれるとか、アイコンブロック化してくれるのとかいいかなあ…🤔