📖

自分なりのmisskey-fork開発

2025/02/02に公開

はじめに

どうも、misskey-tempという自己満足misskeyフォークをいじってる者です。
どんな機能があるのかっていうのはhackmdを見てもらえれば大体わかると思います。
他のフォークでも見たことあるような機能や、普通は実装しないであろう機能を「とりあえず入れちゃえ!」って感覚で突っ込んでる、多種多様なフォークです。
特にこだわりは無いのですが、強いて言えばmisskey-dev/misskey:masterに追従する形でフォークを運用してるって感じですね。

開発に使ってる環境

PC

  • OS: Arch Linux + KDE Plasma(wayland)
  • CPU: Ryzen 7 4700U + Radeon Vega(integrated)
  • RAM: 16GB
  • Storage: 512GB

開発ツール

  • IDE: VSCode / AstroNvim
  • Terminal: Tabby + zsh + starship
  • Node.js: v22.13.0
  • npm: 11.0.0
  • Docker: PostgreSQL + Redis (misskey標準構成)
  • Browser: Google Chrome + Firefox Developer Edition

アシスト

  • DeepSeek-R1-Distill-Llama-70B (ローカルGPUサーバー上)
  • Github Copilot (Pro)
  • Gemini Advanced

基本的にVSCodeばっかり使ってますね。
こだわりがない方はVSCode+Devcontainerを使うと、拡張機能を含んだセットアップが楽にできるのでおすすめです。
アシストとしてLLMを使っていますが、主にコードレビューワーとして使ってます。
ちょっと大きめの機能を実装する際は、まずGeminiに構成を考えてもらって、それからDeepSeekに全体の構図を作ってもらって、それから作業を始めるようにしています。
これが結構楽をしつつ、楽しく作業できるので良い感じです。
CopilotはIDEの補完程度にしか使ってないですね。

Misskeyフォーク開発の進め方

フォークの方針・機能のアイデアは?

misskey-tempはmisskey-dev/misskey:masterに追従して開発していますが、バグ修正や脆弱性対応などは、cherry-pickして先に取り込むようにしています。

機能周りのアイデアは思いついたら即issueに書き込むようにしていて、とりあえず書いて後で吟味する感じですね。
「これなんで欲しいんだっけ?」ってならないように、コメントを残しておいたりもしてます。

実際に実装して使い込んでる機能と言えば、ListenBrainzから再生中の音楽をウィジェット経由でノートするものですね。
今回はこれを例に、コードを出しながらどんなフローで実装していったのか紹介しようと思います。

ウィジェットを実装してみよう

大まかな流れとしては

  1. 他のウィジェットのコードを見る
  2. 実際にコードを書いてみる
    って感じですね。

1. コードを見る

ウィジェット関連のものはpackages/frontend/src/widgetsに全部あります。
サンプルとしてWidgetButton.vueを見てみましょう。
雰囲気としてわかるのは、Widget~みたいなことが色々なところで見られるってことですね。
例えば、importしてる部分の

import { useWidgetPropsManager, WidgetComponentEmits, WidgetComponentExpose, WidgetComponentProps } from './widget.js';

とか、完全にウィジェットの重要な部分!って感じが伝わってきますね。
ちょっと下の方を見ていくと

const name = 'button';

const widgetPropsDef = {
	label: {
		type: 'string' as const,
		default: 'BUTTON',
	},
	colored: {
		type: 'boolean' as const,
		default: true,
	},
	script: {
		type: 'string' as const,
		multiline: true,
		default: 'Mk:dialog("hello" "world")',
	},
};

ってありますね。
constって書いてあるので、定義してるってことがわかります。
ところで、このウィジェットってどうやってフロントにロードしてるんだろう?って思いますよね。
そういうときはWidgetButton.vueって検索しちゃえばいいんですよね。
お!一件だけヒットしました。
VSCode
index.tsを開いてみると、たくさん同じことが書いてありますね。

export default function(app: App) {
  app.component('WidgetButton',  defineAsyncComponent(() => import('./WidgetButton.vue')));
}

export const widgets = [
  'button',
];

って感じで読み込んでるっぽいですね〜
ほへ〜

ま〜大体importしてこういうの書いておけばいい、みたいな雰囲気がコードを読むことで理解できたので、実際に作っちゃおうってことで書いていきます。

2. コードを書いていくよ

とりあえずwidgetsフォルダの中にWidgetListenBrainz.vueってのを作っちゃいました。
ついでにbuttonのコードをそのままコピペして、とりあえずウィジェットとして使えるようにします。
そしたらindex.tsで他の部分と同じように、見様見真似で書き足しちゃいます。

app.component('WidgetListenBrainz', defineAsyncComponent(() => import('./WidgetListenBrainz.vue')));

'listenBrainz',

って感じで、一部省略してますが一番最後の方に書いておけばいいと思います。
で、本当は一個ずつ解説していきたいのですが、長ったらしい文章を読むのも書くのも苦手なので、実際のコードはこれを見てください!
https://git.0il.pw/n/misskey-temp/src/branch/master/packages/frontend/src/widgets/WidgetListenBrainz.vue

大雑把に言えば、ListenBrainzのエンドポイントで貰えるJSONをパースして、メタデータとして保持しつつ、ユーザーの好きなようにカスタマイズしてる感じです。
あとはMkButtonでノートボタンを置いてあげて、misskeyApiでノート作成を呼び出してます。

おわり

ってまあこんな感じで、コードを雰囲気で音楽を聴きながら書いてます。
フロントに慣れてきたらバックエンドを触りつつ、実際にフロントから呼び出して使うものを実装してみると良いと思います。
フォロー/フォロリク履歴を実装したのも、大体慣れて来たぐらいだった気がします?(あんまり覚えてない)

Misskeyフォークだけではないですが、プログラミングは学ぶというよりは、自分で興味があれば触りつつ理解を深めていけば楽しくできるのかなって感じますね〜
別に人それぞれやり方があるので、自分に合うようにやってみると良いと思います!
困ったら鯖缶として動いて、繋がりでフォークをいじってる人に聞いてみるといいかもしれませんね!
性格が合うのかわかりませんが、私なんかで良ければ暇してそうなときに聞いてくれたら、多少は教えたりとかできると思います。(わかる範囲だったら...)

コードはどうやって学んだ?(本編とは関係ない)

学ぶと言うか、楽しそうだなって感じで始めたのが、BO2のgscをいじるところからだった気がします。
とりあえず自分でメニュー作ってみたいって気持ちだったので、海外の記事を見ながらコピペしてました。
大体、途中から同じようなコードが繰り返してるな〜ってのを感じ取って、自分で書き足す感じでやってましたね。
そしたら簡単に自作mod menuもどきが作れちゃったので、マイクラのmodとかも同じ感覚でできるかも?って感じでJavaを触ってみたり、PHPでサイトを作ってみたり、なんか色々やってました。
気づいたら今の感じですね。
学ぶと言うよりは、実際に触りつつ理解を深めていくタイプでした。
ドキュメントとかは必要になったら調べて読むぐらいで、Misskeyのコードも同じ感じで触ってたら段々理解できるようになりましたね。
ちなみにatcoderは最高1500程度でした。

Discussion