【Figma】デザインファイルの Owner が夜逃げした時に役立つTips

# はじめに

こんにちは、梅雨です。

タイトルの「**デザインファイルの Owner が夜逃げした時に役立つTips**」は半分冗談ですが、今回は Figma のデザインファイルのオーナー権限を擬似的に移行する方法を紹介したいと思います。

実は最近、Google Workspace で貸与されていた Google アカウントを返却したことによって、デザインファイルのオーナー権限を持つアカウントが消滅してしまうという事故が起きました。

このような場合や、ファイルのオーナーと連絡が取れなくなってしまった場合、また何かしらの理由でオーナーをキックアウトしなければいけない事情がある場合などにはこの記事の内容を参考にしてみてください。

# 前提条件

- Owner のアカウントが何かしらの理由で操作できない
- Owner 以外にもアクセス権限を持つアカウントが存在する
- 手作業で移行しきれないほどのコメントが存在する

Figma の各コンポーネントはコピー & ペーストをすることができますが、この際コメントまではコピーすることができません。

そのため、この記事のメインの内容は**大量のコメントを移行する方法**ということになります。

# 移行方法

それでは早速、移行方法を紹介していきます。

## デザインファイルの複製

まずはデザインファイルを複製します。

![Screenshot 2024-12-16 at 2.38.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2671591/4ba131e9-febb-7745-2ab7-e9de0eb5fe54.png)

ファイルの複製ではなく画面の要素をコピーして別のデザインファイルに貼り付けてしまうと、次に行うコメントの移行ができなくなってしまうため注意してください。

## アクセストークンの発行

ホーム > アカウント名 > Settings >　Security > Personal access tokens > Generate new token からアクセストークンを発行します。

この操作は、移行したい元のデザインファイルにアクセス権限のあるアカウント上で行ってください。

![Screenshot 2024-12-16 at 2.48.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2671591/f97ca1ff-3aba-035c-2948-e0d49a183948.png)

Token name には任意のトークン名を入力します。

Scopes は

- `File content` -> `Read-only`
- `Comments` -> `Write`

とするようにしてください。

![Screenshot 2024-12-16 at 2.49.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2671591/c8b0d0f8-8fd7-64eb-47ad-fa985a2d84b6.png)

トークンが発行できたら、コピーして紛失しないようにメモしておきましょう。

## ファイルキーの取得

続いて、ファイルキーの取得を行います。

まずは Share > Copy link で共有用のリンクを取得しましょう。URL は以下のような構造になっており、この例では `ABCDEFGHIJKL1234567890` がファイルのキーとなります。

`https://www.figma.com/design/ABCDEFGHIJKL1234567890/...`

元のファイルと移行先のファイルの両方でこのファイルキーを取得してメモしておいてください。

## コメントの取得と作成

最後に、元のファイルのコメントを取得し、複製先の新しいファイルにコメントを作成するスクリプトを書いていきます。言語はなんでも構いませんが、Figma API のレスポンスは json 形式で返却されるため、今回は JavaScript を使って作成していきます。

取得のエンドポイントは `GET https://api.figma.com/v1/files/:file_key/comments`
作成のエンドポイントは `POST https://api.figma.com/v1/files/:file_key/comments`

となっています。

https://www.figma.com/developers/api#comments-endpoints

まずはコメントの取得をします。

```js
const handler = async () => {
  const accessToken = // アクセストークン;
  const beforeFileKey = // 移行元のファイルキー;

  const res = await fetch(
    `https://api.figma.com/v1/files/${beforeFileKey}/comments`,
    {
      method: "GET",
      headers: {
        "X-Figma-Token": accessToken,
      },
    }
  );
  
  const { comments } = await res.json();
};

handler();
```

次に、このコメントを複製後のファイルに移行するにあたって適切な形に変形してあげる必要があります。

```diff_typescript
const handler = async () => {
  const accessToken = // アクセストークン;
  const beforeFileKey = // 移行元のファイルキー;

  const res = await fetch(
    `https://api.figma.com/v1/files/${beforeFileKey}/comments`,
    {
      method: "GET",
      headers: {
        "X-Figma-Token": accessToken,
      },
    }
  );

  const { comments } = await res.json();
+
+   for (const comment of comments) {
+     if (comment.resolved) {
+       continue;
+     }
+ 
+     const newMessage = {};
+ 
+     newMessage.message = `${comment.user.handle}: ${comment.message}`;
+ 
+     if (comment.parent_id) {
+       newMessage.comment_id = comment.parent_id;
+     }
+ 
+     if (comment.client_meta?.node_id && comment.client_meta?.node_offset) {
+       newMessage.client_meta = {
+         node_id: comment.client_meta.node_id,
+         node_offset: comment.client_meta.node_offset,
+       };
+     }
+   }
};

handler();
```

そして最後に、新しいデザインファイルにコメントを作成します。

```diff_typescript
const handler = async () => {
  const accessToken = // アクセストークン;
  const beforeFileKey = // 移行元のファイルキー;
+   const afterFileKey = // 移行後のファイルキー;

  const res = await fetch(
    `https://api.figma.com/v1/files/${beforeFileKey}/comments`,
    {
      method: "GET",
      headers: {
        "X-Figma-Token": accessToken,
      },
    }
  );

  const { comments } = await res.json();

  for (const comment of comments) {
    if (comment.resolved) {
      continue;
    }

    const newMessage = {};

    newMessage.message = `${comment.user.handle}: ${comment.message}`;

    if (comment.parent_id) {
      newMessage.comment_id = comment.parent_id;
    }

    if (comment.client_meta?.node_id && comment.client_meta?.node_offset) {
      newMessage.client_meta = {
        node_id: comment.client_meta.node_id,
        node_offset: comment.client_meta.node_offset,
      };
    }
+
+     const res = await fetch(
+       `https://api.figma.com/v1/files/${afterFileKey}/comments`,
+       {
+         method: "POST",
+         headers: {
+           "X-Figma-Token": accessToken,
+           "Content-Type": "application/json",
+         },
+         body: JSON.stringify(newMessage),
+       }
+     );
+
+     console.log(await res.json());
  }
};

handler();
```

これでスクリプトが完成しました。ファイルを実行してみましょう。

```bash
$ node script.js
```

エラーが起きなければ成功です。以上でデザインファイルの移行が完了しました。

# おわりに

Owner アカウントにアクセスができなくなってしまうことはあまりないと思いますが、もしそのようなことが起きてしまった場合はこの記事を参考にしてみてください。

最後まで読んでくださりありがとうございました。