この記事はNostr (2) Advent Calendar 2023 13日目の記事です。

概要

ノーコードツールのn8nでNostrのボットを作ることができるノード(ノーコードツールの部品のようなもの)を作ったので使い方を解説します。

image

n8n-nodes-nostrobots

https://github.com/ocknamo/n8n-nodes-nostrobots

n8nとは

ノーコードツールです。ノーコードツールといえば有名どころにZapierやIFTTTなどがありますがそういう感じのワークフロー自動化ツールです。

公式の説明を引用します。

n8n - ワークフロー自動化ツール n8n は、拡張可能なワークフロー自動化ツールです。 フェアコード配布モデルにより、n8n は常にソース コードが表示され、セルフホストで利用でき、独自のカスタム関数、ロジック、アプリを追加できます。 n8n のノードベースのアプローチにより、汎用性が高く、あらゆるものをあらゆるものに接続できます。 (機械翻訳)

https://github.com/n8n-io/n8n

n8nで組み合わせて使用できるワークフローの部品を"ノード"と呼びます。

コミュニティノードとは

だれでも自由に作成できてみんなに共有できるノードです。Node.jsで作成することができます。

作成方法はこちら。

雛形やチュートリアルがあるのでそこまで難しくありません。今回は作成方法などは紹介しません。

n8nの準備

n8nはコードが公開されておりセルフホストも可能です。

利用する簡単な方法としてはお金を払うか、セルフホストする方法があります。

お金を払う

月20ユーロでプラットフォームを使用できまるようです。

https://n8n.io/pricing/

セルフホスト

DockerもしくはNode.jsを扱えるエンジニアであれば簡単にセルフホストできます。

https://docs.n8n.io/hosting/

またUmbrelを運用している人であればアプリがストアにあるのでワンクリックでインストールできます。

https://apps.umbrel.com/app/n8n

unbrelAppStore

コミュニティノードのインストール方法

コミュニティノードの利用はリスクもあるため必ず公式のドキュメントを読んでから自己責任でインストールしてください。

https://docs.n8n.io/integrations/community-nodes/

ここではn8n-nostrobotsのインストール方法だけ解説します。

サイドメニューのSettingsからCommunity nodesをページに移動し、インストールします

installDialog

npm Package Nameにn8n-nodes-nostrobotsと入力してインストールを実行します

しばらく待つとCommunity nodes一覧に追加されるのでこれでインストール完了です。

installed

RSS Feed ボットの作成

簡単なチュートリアルとしてRSS Feed ボットを作成してみましょう。

準備

先程説明した方法でn8n-nodes-rss-feed-triggerというコミュニティノードをインストールしてください。

https://github.com/joffcom/n8n-nodes-rss-feed-trigger

(一応実装を見たかったので私はコードもかるく確認していますが自己責任でお願いします)

ワークフロー作成

Workflows画面のAdd Workflowからワークフローを追加できます。

emptyWorkflow

トリガーノードの作成

はじめにトリガーとなるノードを設定します。(n8n-nostrobotsにはまだトリガーノードは実装されていません) "+"をクリックして追加メニューを開きます。

トリガーノードとしてn8n-nodes-rss-feed-triggerを使用したいので"rss"と入力するとRSS Feed Triggerが選択肢に現れるので選択してください。

とりあえずPollタイムをデフォルト値のままにしておきます。

FeedURLはLorem RSSがテストとして使用できます。

Feed URLに以下のURLを設定してください。

rssTriggerSetting

設定できたらFetch test Eventボタンでテスト実行を行います。

画像のようにテスト用のRSS Feedのデータが取得できます。

クレデンシャルの作成

サイドメニューからCredentialsを選択します。'Add Credential' ボタンで作成モーダルを開きます。 フォームに"nostr"と入力すると"Nostrobots API"がサジェストされるので選択してください。ちなみに表示されない場合はコミュニティノードのインストールが完了していない可能性があります。

credentialSettingDialog

クレデンシャルの作成画面が開くのでSecretKeyを入力してください。HEXでもbech32(nsecで始まる形式)どちらでも大丈夫です。

ワークフローの作成途中は使い捨て可能なテストアカウントを作成して使用することをおすすめします。

Nostrへの投稿の実行

RssFeedTriggerノードの右側に出ている"+"をクリックして後に続くノードを追加します。

nostrで検索するとNostr ReadNostr Writeの2つのノードが表示されるのでNostr Writeを選んでください。

AddNostrNode

選択肢が表示されたら(どれでもいいですが)Basic Noteactionsを選ぶとノードが追加されます。

ノードの設定画面が開くので以下のように値を設定します。'Credential to connect with'には先程自分が作成したクレデンシャルを設定します。

設定値は以下です。

Custom Relayはテスト用に一つだけに設定しました。デフォルトに戻したい場合、項目のメニューからReset Valueを実行してください。

設定が完了したらExecute nodeボタンをクリックしてノードを実行します。

実行が完了するとOUTPUTに実行結果が表示されます。

NodeSetting

content:Hello nostrを含むイベントが作成されており、sendResultが0:[accepted]: wss://nostr.momになっていれば成功です。

他のクライアントからも確認できます。(Custom Relayに設定したリレーをクライアントに設定する必要があります)

testnote1

RSSとの接続

INPUTにRSS Feed Triggerの結果がSchema形式で表示されていると思います。A contenという項目をドラッグしてNostr Writeの'Content'のフォームドロップしてください。

これだけで実行済みのノードの結果のデータをコンテントに埋め込んで渡すことができます。

この状態でテスト実行して確かめてみましょう。

testnote2

RSS Feedの内容を投稿できました。

有効化

あと有効化して実行するだけです。

右上の赤いSaveボタンをクリックして保存したら、その左のInactiveと書かれたトグルボタンを有効化してください。確認モーダルが表示されるので確認してGot itを選択します。

以上で完了です。

クライアントから投稿ができているか見てみましょう。

client

1分ごとに投稿ができており、一度に2投稿できているので成功です!

お疲れ様でした。これでRSS Feedボットの作成完了です。

機能の解説

以下は細かい機能解説になります。ドキュメント用に書いたものなので、興味がなければ読みとばしていただいで必要なときに参照してください。

Nostr Read

'Strategy'

リレーからイベントを取得する方法を指定します。以下の2つのオプションを選ぶことができます。 リレーに送るフィルタとしてなにを設定するかを選んでいるだけです。

UserPublickey

対象のユーザを示す公開鍵文字列を指定できます。HEXでもbech32(npub)方式でもどちらでも指定できます。

EventId

対象のイベントのeventIdです。eventIdにリレーの情報が含まれる場合、指定したリレーに加えてそのリレーにも取得リクエストを送ります。

HEXでもbech32(nevent)方式でもどちらでも指定できます。

期間の範囲指定

イベントの取得対象期間を指定します。StrategyがUserPublickeyの場合のみ指定できます。 以下のオプションを指定できます。

'Relative'

期間の指定方法です。Relativeがオンの場合は過去に遡っていつから取得するかを相対的に指定することができます。(もちろん現在まで取得します)

'From'

現在から遡っていつから取得範囲にするかを指定することができます。Relativeが有効な場合のみ指定できます。

'Unit'

単位を選択肢から選ぶことができます。Relativeが有効な場合のみ指定できます。

NOTE: 例えばFromを"1"に設定してUnitを"day"に設定した場合取得範囲は、”1日前からノードの実行時刻”までのイベントが対象になります。

'Since', 'Until'

Relativeを無効にした場合期間範囲指定は'Since', 'Until'を使用します。 その名の通り'Since'の日時から'Until'日時までの期間指定でイベントを取得することができます。

'Custom Relay'

問い合わせ先のリレーを指定します。リレーのURLを入力してください。複数を指定する場合はカンマ(,)でつなげて書いてください。 デフォルト値としてリレーを8件設定しているため、ここは修正しないでそのまま使用してもらって構いません。ただし、当たり前ですがデフォルトリレーが正常に動いていることは保証できません。

wss://relay.damus.io,wss://relay-jp.nostr.wirednet.jp,wss://nostr-relay.nokotaro.com,wss://nostr.fediverse.jp,wss://nostr.holybea.com,wss://nos.lol,wss://relay.snort.social,wss://nostr.mom

'Error With Empty Result'

有効にした場合取得イベントが存在しない場合はエラーになってワークフローを停止することができます。無効の場合はイベントがなくても、エラーにはならず空配列を次のノードに実行結果として送ります。

Sample

jackの直近1時間のイベントを取得してみた実行結果です。3件のイベントを配列で取得できました。

[
  {
    "id": "6c1428c9afdd315f07a9b6e22118ce45c31b2a8de12ef694121ae1cfd06ee2df",
    "kind": 1,
    "pubkey": "82341f882b6eabcd2ba7f1ef90aad961cf074af15b9ef44a09f9d2a8fbfbe6a2",
    "created_at": 1702389559,
    "content": "Only for you. Of course",
    "tags": [
      [
        "e",
        "4e222fdb7edb65172f85f262eff95a53132bcac6ccd2842b23c79f8bc0872e15"
      ],
      [
        "e",
        "9295e82f3b802728dc18ef888bad81b3110711679982dc94e719f5a20e7e2528"
      ],
      [
        "p",
        "e88a691e98d9987c964521dff60025f60700378a4879180dcbbb4a5027850411"
      ]
    ],
    "sig": "ad3b4873c8c4103555f5bdec4ad39cc0b029f000d88e67964a72e41359981440b776aea6e3758257346ae8c5efde6efe8cda2490abdfc3d0b02f675f06c9bada"
  },
  {
    "content": "สวัสดีชาว bitcoiners ชาวไทย",
    "created_at": 1702388695,
    "id": "309dea1a6e298fe3b591e8c4f87736528ee867a94ffa820b3225aa9169c6a009",
    "kind": 1,
    "pubkey": "82341f882b6eabcd2ba7f1ef90aad961cf074af15b9ef44a09f9d2a8fbfbe6a2",
    "sig": "e113577b3281eb6637abf5ee60aef6b7a0dd700bf6254196e862fee96d4806eefa80c37292919f4e38dedbdc2f1d2a16d58c4d3c1a7d1dab40514868f48d3277",
    "tags": [
      [
        "e",
        "4e222fdb7edb65172f85f262eff95a53132bcac6ccd2842b23c79f8bc0872e15",
        "",
        "reply"
      ],
      [
        "p",
        "82341f882b6eabcd2ba7f1ef90aad961cf074af15b9ef44a09f9d2a8fbfbe6a2"
      ]
    ]
  },
  {
    "id": "4e222fdb7edb65172f85f262eff95a53132bcac6ccd2842b23c79f8bc0872e15",
    "kind": 1,
    "pubkey": "82341f882b6eabcd2ba7f1ef90aad961cf074af15b9ef44a09f9d2a8fbfbe6a2",
    "created_at": 1702388333,
    "content": "nostr:naddr1qq9rzdesxgensvpnxuusygxv5lh4g8dcx6y5z0vht38k5d0ya3eezk39jmrhqsfdj2rwwv33wcpsgqqqwens60xga9",
    "tags": [],
    "sig": "7f5d80867650d5fa2a7da55d20fd604423a785e028595d0c9fb56b80a2be0d555997e06e4f3a2d9930c183122fafa51bd8035e8eb9fe83d3cc47b13e040b29d8"
  }
]

Nostr Write

Nostrのリレーにイベントの書き込みを行うノードです。 このノードを使用する前に書き込みを行いたいアカウントの秘密鍵をn8nにクレデンシャル情報として登録する必要があります。

'Credential to connect with'

作成したクレデンシャル情報を選択して投稿するアカウントを決めます。クレデンシャルを複数作成すると複数のアカウントが選択肢に追加されます。 ワークフローの作成途中は使い捨て可能なテストアカウントを作成して使用することをおすすめします。

'Resource'

どのような方法でイベントを作成するか選択することができます。以下の3つのオプションがあります。

'BasicNote'

一番単純なノートイベント(kind1)です。SNS用のクライアントで見ることができるイベントです。'Content'に本文を設定すれば使用できるため使い方も一番簡単で、おそらくNostrプロトコルをあまり理解していなくても利用可能です。

'Event(advanced)'

BasicNoteと異なりkindやtagsを設定することができます。利用するには少なくともNIP-01を理解する必要があると思われます。

BasicNoteから追加になるメニュー項目がかなりたくさんあります。以下に箇条書します。

ShowOtherOptionを有効にするとEventId以下のメニューを表示できます。これらを使う機会はかなり限られるためデフォルトで非表示にしています。

注意点としてShowOtherOptionが有効な場合Sig(署名)が必須となるため'Credential to connect with'で選択したアカウントでは署名を行いません。自力で署名する必要があります。

Kind

イベントのkindナンバーを設定できます。 詳しくはNIPを確認してください。

Tags

イベントに追加するタグを設定できます。jsonを入力する必要があります。jsonでパースできない場合やタグの配列形式ではない場合、実行時エラーとなることに注意してください。設定時にはバリデーションされません。

タグの指定方法はクライアントでまちまちだったりして結構難しいです。これも基本的にNIPを確認してください。

FYI. メンションを行う場合のタグのサンプル

[["e","dad5a4164747e4d88a45635c27a8b4ef632ebdb78dcd6ef3d12202edcabe1592","","root"],
["e","dad5a4164747e4d88a45635c27a8b4ef632ebdb78dcd6ef3d12202edcabe1592","","reply"],
["p","26bb2ebed6c552d670c804b0d655267b3c662b21e026d6e48ac93a6070530958"],
["p","26bb2ebed6c552d670c804b0d655267b3c662b21e026d6e48ac93a6070530958"]]
otherOption

これは細かく説明する必要もないかと思います。名前の通りの項目です。

'Raw Json Event(advanced)'

生のjsonをそのまま設定できるオプションです。使い方は限られますが、Nostr Readで取得したイベントをそのままパブリッシュしたい場合などが考えられます。

json

'Raw Json Event(advanced)'の場合のみ表示されます。jsonには完全な署名済みイベントのjsonを入力してください。したがって'Credential to connect with'で選択したアカウントで署名しません。

'Content'

イベントの本文です。Resourceの選択肢で'BasicNote'か'Event(advanced)'を選択した場合に利用できます。

'Operation'

実行するオペレーションを選択します。いまは作成したイベントをリレーにパブリッシュするSendしかありません。

Custom Relay

イベントを送信するリレーを指定します。スキーマやデフォルトリレーはNostr Readと同じです。

実行時の挙動について

まとめ

網羅的にn8n-nostrobotsの利用方法について書きました。チュートリアルもやってみていただけると嬉しいです。

個人的にNostr関係では一番ドッグフーディングしているプロジェクトなので、欲しい機能があればこれからもちょくちょくアップデートを続けようと思います。おかしなところがあったらissueで報告していただけると助かります。

https://github.com/ocknamo/n8n-nodes-nostrobots/issues

他の人みたいに英語化もして書こうと思いましたが時間がないので諦めました。正月の宿題にします。

さてあしたのアドベントカレンダーは

の2本立てです。楽しみですね。