Misskeyで自分のノートをrenoteするbot

タイトルそのまま、備忘録。

# やること
- Misskey.ioでの自分の過去のノートを、同じアカウントでRenoteする

# 環境
- Python 3.12.1（新しもの好き）
    - 使うライブラリの関係上、バージョンは3.7以上必須
- Ubuntu（バージョンは忘れた……けどそもそもOS環境依存で発生する問題はないはず）

# 準備するもの
- MisskeyのAPIアクセストークン
    - [設定] > [API] > [アクセストークンの発行] から入手できます
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68786/1eda274b-fa5c-02e7-3e43-1a86581fe9ea.png)

    - 権限は「アカウントの情報を見る」と「ノートを作成・削除する」だけあれば十分です

# Pythonを書く
エッセンスとなる部分だけ紹介します。

## 使うライブラリ
Misskey.pyというめちゃくちゃ便利なライブラリがあります。

https://misskeypy.readthedocs.io/ja/latest/getting-started.html

PyPIからインストールできます。便利（2回目）
~~PyPIのこと、IをLの小文字と読んで「ペイパル」って呼ぶ人間は俺だけでいい~~

```shell
pip install -U Misskey.py
```

## クイックスタート
本家の文面ほぼ丸パクリですが、まずインスタンスを作ります。
~~インスタンスって何？（by日曜大工コーダー）~~

```py:main.py
from misskey import Misskey

TOKEN = '[MISSKEY APIのアクセストークン]'
mk = Misskey('misskey.io', i = TOKEN)
```

メソッドはここ↓にあります。

https://misskeypy.readthedocs.io/ja/latest/api/misskey.html

あとは煮るなり焼くなりしましょう。
例えば、アカウントの基本情報を得るには `.i()` メソッドを使います。

```py:main.py
from misskey import Misskey
# 結構色々な情報が出てくるので、見やすくするためにpprint()を使えるようにしておくといいかも
from pprint import pprint

TOKEN = '[MISSKEY APIのアクセストークン]'
mk = Misskey('misskey.io', i = TOKEN)

pprint(mk.i())
```

dict形式で山のように情報が出てきますが、ここで必要になるのは `'id'` だけです。
これが、自分のアカウントを走査するために必要なユーザIDになります。

```py:main.py
# pprint(mk.i())
user_id = mk.i()['id']
```

## 自分のノートを取得する
自分のノートは [`.users_notes()` メソッド](https://misskeypy.readthedocs.io/ja/latest/api/misskey.html#misskey.Misskey.users_notes)で取得できます。

オプションはたくさんありますが、使いそうなのは……
- user_id（上で取得したユーザID。必須）
- include_replies（取得対象にリプライを含めるか。デフォルトは `True` ）
- limit（取得するノート数。最大値は100。デフォルトは `10` ）
- since_date（`datetime.datetime`形式で指定して、その日付以降のノートを対象とする）
- include_my_renotes（自身のrenoteを取得対象に含めるか。デフォルトは `True` ）

とかでしょうか。基本的には最新のノートから取得していきます。
例えばこんな感じに指定します：

```py:main.py
user_id = mk.i()['id']
notes_response = mk.users_notes(
            user_id = user_id,
            limit = 100
            )
```
これで直近100件のノートが取得できます。

### renoteやリプライを含む場合
`notes_response` はノートに関する様々な情報を含むlistになります。ここで、ノートが何かをrenoteしていたり、何かへのリプライを行っている場合（ `.users_notes()` 実行時に `include_` 系のオプションをデフォルトのままにしてある場合）、`notes_response[i]['renote']` や `notes_response[i]['reply']` といったキーが含まれます。
どうも、これらの要素も「取得するノート数」に含まれるようなので（要検証）、実際に `.users_notes()` で `limit=100` を指定していても、見かけ上取得できるノート数は100件に達しないかもしれません。

~~というかオプションを `False` にしたところでrenoteやリプライは取得されているのでうまく動いていないっぽい？~~

## 取得したノートをrenoteする
`notes_response` にある `id`（renoteしたノートの場合は `['renote']['id']` ）を使ってrenoteができます。使うメソッドは [`.notes_create()`](https://misskeypy.readthedocs.io/ja/latest/api/misskey.html#misskey.Misskey.notes_create) です。

```py:main.py
user_id = mk.i()['id']
notes_response = mk.users_notes(
            user_id = user_id,
            limit = 100
            )
            
for item in notes_response:
    mk.notes_create(
            renote_id = item['id']
            )
```

これで、検索したノートを全てrenoteすることになります。

::: note alert
が、**こんなマジモンのrenote爆撃は停止措置にかかる可能性大なのでやめましょう**。
:::

自分は、検索したノートから指定したタグを含むものだけを収集し、別のプログラムでcronを回し、一定期間に1回だけ収集したノートからランダムで1つ、renoteするようにしています。

例えばタグは `['tags']` （または `['renote']['tags']`）、本文は `['text']`（または `['renote']['text']` ）というキーに入っているので、この中に指定した文字列があった場合に、別のファイルなどに書き出すような処理を書いておくと、別のプログラムや関数から読み込むことができます。

```py:main.py
for item in notes_response:
    if 'tags' in item:
        if '[検索したいタグ]' in item['tags']:
            # item['id']を、変数なり外部ファイルなりに書き出す処理を書く
```



# おしまい
能登半島地震でインプゾンビが湧いた~~Twitter~~ Xなんて離れてみんなでMisskey、しよう！