Misskeyプラグインを作ってみよう

Misskeyの一番簡単なプラグインであるノートの文字列を置換するプラグインを作成することで、プラグインを作成する方法について紹介しようと思います。

## 前提
- この記事はある程度プログラミングの知識がある読者を想定して書いています
- この記事はAiScript 0.12.4の情報を基に書かれています
- Misskeyはサーバー（インスタンス）によってバージョンや使える機能が違う可能性があるのでこの記事の内容が参考にならない場合もあります
- AiScriptは公式ドキュメントが少なく、インターネット上で参照可能な文献も少ないのでみなさんもぜひ知見を共有してみましょう

### Misskeyとは？
MisskeyはActivityPubに対応した分散型プラットフォームです。

https://misskey-hub.net/

https://github.com/misskey-dev/misskey

### AiScriptとは？
主にMisskey内で使えるスクリプト言語でMisskeyのプラグインやMisskey Playはこの言語を利用して記述することが可能です

### 🔗AiScriptを書く上で参考になるリンク
まずはこの辺を読んでみるとかなりAiScriptについては分かりやすいです。

ここを読んでもわからないときは検索をしたりAiScriptのソースコードを見てみたり、Misskey内で`#AiScript` `#MisskeyPlugin`で検索してみたりするといいです。

#### 基本
https://github.com/syuilo/aiscript
- [aiscript/get-started.md](https://github.com/syuilo/aiscript/blob/master/docs/get-started.md)
  - AiScriptの書き方はまずはここを読んでみましょう 
- [aiscript/syntax.md](https://github.com/syuilo/aiscript/blob/master/docs/syntax.md)
  - 基本的な記法はこれを読むとなんとなくわかります
- [aiscript/std.md](https://github.com/syuilo/aiscript/blob/master/docs/std.md)
  - AiScriptで扱える関数一覧が書いてあります

AiScript PlaygroundではAiScriptのコードを試しに動かしてみることもできます！

https://syuilo.github.io/aiscript/

#### プラグイン関連
- [プラグインの作成](https://misskey-hub.net/docs/advanced/create-plugin.html)
- [プラグインAPIリファレンス](https://misskey-hub.net/docs/api/endpoints.html)
- Misskeyの[APIリファレンス](https://misskey-hub.net/docs/api/endpoints.html)

#### その他
- AiScriptの基本

https://qiita.com/YuzuRyo61/items/58d8c2f6a2c2bbfb7eda
- いろいろ書かれてる偉大な先人のQiita

https://qiita.com/saki-lere/items/851c4500d56659d15c9c
- ライブラリ
  - AiScript周りで足りないものをいろいろ補完してくれるらしいです

https://github.com/madorama/aiscript-library
- Misskey AiScript部
    - MisskeyでAiScriptを書いている人や興味がある人が集まっているチャンネルです。
    - ここで質問すれば返信がもらえるかも…？

https://misskey.io/channels/9bhwlim9bz

### プラグインができること
https://misskey-hub.net/docs/api/endpoints.html
こちらに書いてありますが、主なものを簡単に紹介していきます

- Plugin:register_post_form_action(title fn)
  - 投稿フォームにアクションを追加するもの
      - 導入後のイメージ
      - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2882536/94c4626f-2c5f-2e86-8042-68510a1f7b8c.png)
- Plugin:register_note_action(title fn)
    - ユーザーメニューに項目を追加するもの
    - 導入後のイメージ
        - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2882536/51b7be7b-8bed-4e53-417e-fb4def99090c.png)
- Plugin:register_note_view_interruptor(fn)
    - UIに表示されるノート情報を書き換えるもの
    - 投稿されたノートのオブジェクトの内容を書き換えてノートの中身やユーザー名などの書き換えが可能
- Plugin:register_note_post_interruptor(fn)
    - ノート投稿時にノート情報を書き換えるもの
    - 自動でノートの内容を書き換えるようなものが作れる

### メタデータを作成する
メタデータについて
https://misskey-hub.net/docs/advanced/create-plugin.html#%E3%83%A1%E3%82%BF%E3%83%86%E3%82%99%E3%83%BC%E3%82%BF

AiScriptのメタデータ埋め込み機能を利用してプラグインのメタデータを定義します。

#### 書式
```typescript
/// @ 0.12.4
### {
  name: "プラグイン名"
  version: "0.1.0"
  author: "書いた人"
  description: "説明"
  permissions: ["write:notes"] //Misskey APIにリクエストする際の権限
  config: {
    someKey: {
      type: 'string' // ここに設定の型（AiScriptの型とは違うので注意）string number boolean のいずれか
      label: '設定の名前・ラベル'
      description: '設定の説明'
      default: 'デフォルト値'
    }
  }
}
```

上記のメタデータをスクリプトの先頭に記述しておきます。

Misskey APIの権限一覧はこちら

https://misskey-hub.net/docs/api/permission.html

ここで設定したコンフィグは
```typescript
Plugin:config.someKey
```
のように呼び出すことで利用できます（今回は使用しません）

## コード本体を書く
表示するノートの文字列を置換するプラグインを作成していきます。

### メタデータ
まず、メタデータですが今回はAPIに対する権限・設定は必要ないのでこのような感じのメタデータになります。
```typescript
/// @ 0.12.4
### {
  name: "ノートの偉業をカスタム絵文字に変換する"
  version: "0.0.1"
  author: "@taichan@misskey.io"
  description: "ノート中に現れる偉業の文字列をカスタム絵文字に変換します。"
  permissions: [] //Misskey APIにリクエストする際の権限
  config: {}
}
```
バージョン番号のつけ方に迷ったときは、個人的にはセマンティックバージョニングに従うのがおすすめです。

https://qiita.com/usamik26/items/c8911219b610101e69a9

### コードを書く
今回は、表示するノートの内容を書き換えたいので`Plugin:register_note_view_interruptor(fn)`を利用していきます。
[記事内の解説はこちら](#プラグインができること)

`Plugin:register_note_view_interruptor(fn)`は次のような関数です。

> コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。
> コールバック関数の返り値でノートが書き換えられます。

引用元: [プラグインAPIリファレンス](https://misskey-hub.net/docs/advanced/plugin-api-reference.html#plugin-register-note-view-interruptor-fn)

```typescript
Plugin:register_note_view_interruptor(@(note){
  note.text = note.text.replace("偉業", ":igyo:")
  note
})
```
このコードでは、noteが持つテキストの中の「偉業」という文字を「:igyo:」に置き換えて、ノートオブジェクトを返却する関数を`Plugin:register_note_view_interruptor`に渡すことでノートの表示時に「偉業」の文字列を置き換えます。

ノートオブジェクトの詳細はこちら

https://misskey-hub.net/docs/api/entity/note.html

### 完成図
```typescript
/// @ 0.12.4
### {
  name: "ノートの偉業をカスタム絵文字に変換する"
  version: "0.0.1"
  author: "@taichan@misskey.io"
  description: "ノート中に現れる偉業の文字列をカスタム絵文字に変換します。"
  permissions: [] //Misskey APIにリクエストする際の権限
  config: {}
}

Plugin:register_note_view_interruptor(@(note){
  note.text = note.text.replace("偉業", ":igyo:")
  note
})
```

### 実行するとこんな感じ
上記のプラグインを`[設定]>[プラグイン]>[プラグインのインストール]`を開き、ペーストして`[✓ インストール]`をクリックすることでインストール可能です。

投稿画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2882536/86eb2e47-dca4-1651-06a8-7c9f8fef63ad.png)

ノートの表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2882536/6bc20d5c-10f9-5f85-0779-6962d8cec1d8.png)



## さいごに
以上で簡単なプラグインが作成できました！
他のサンプルはMisskey内で`#MisskeyPlugin`で検索するとたくさんプラグインが出てくるのでぜひ読んでみても参考になると思います！

Misskey Playに関してはこちらの記事が分かりやすいです！

https://qiita.com/saki-lere/items/e7f0eb6b7dc0af659a67

Misskeyでは
- [@taichan@misskey.io](https://misskey.io/@taichan)
- [@taichan@misskey.io](https://misskey.io/@taichan)

などで活動しているのでお気軽にお声がけください！

### Misskey周りで作ったものの宣伝
ここにもプラグインやPlayのコードを置いてあるので参考になるかもしれません。

https://misskey.io/@taichan/pages/1679914402810