👶

Nostr上に作ったモナカードのボット紹介

2023/12/02に公開

はじめに

この記事はMonacard(モナカード)1 Advent Calendar 2023 2日目の記事です

モナカードのアドベントカレンダーは初めて書きます。ocknamoです。過去にはモナカードのJS(TS)実装のmonacardjsなどを作っていました。
この記事ではNostr上で稼働している私が作ったモナカードの2つのボットを紹介します。

私はNostrをTwitte(X)からの乗り換えとしてはじめたのですが、移住してみるとモナカードの情報が全然手に入らない! となってしまい困ったのでこれらのボットを作りました。

技術スタック

Nostrってなに?

Nostrとは主にTwitterのようなSNSとして使用できる分散型のオープンプロトコルです。
詳しくはこちらの記事を読んでください

また、今ちょうどNostrのアドベントカレンダーも開催されているのでそちらも参考になるかもしれません。

とりあえずはじめてみるというのもよいかと思います。

n8n

私が作ったボットはn8nというノーコードプラットフォームで稼働させています。
n8nでボットを作る方法はNostrのアドベントカレンダーの記事で解説する予定ですので今回の記事では詳細な話は割愛させていただきます。

n8nは無料で実行できるプラットフォームがないので自宅のサーバー内で起動しているumbrel上でアプリをインストールする形で実行しています。

n8n自体はNode.jsかDockerが使えればローカルのPCの環境でも実行できるので、これらの技術に明るい方であれば簡単に試すことができます。

ノーコードなのにほぼプログラマでないと試せないという罠

n8nにはZapierなどにはなどにはない素晴らしい美点があります。それはn8nのワークフローで使う部品(ノード呼ばれる)を誰でも自由に作れるという点です。
作成したノードはnpmパッケージとして公開して誰でも使ってもらうことができます。これはコミュニティノードと呼ばれています。

そこで私がNostrのボットを作るためにノードを作りました。

n8n-nodes-nostrobots

それがこちら。

詳しい話は書きませんがこのノードを部品として使うことでNostrのネットワーク(リレー)に対しての書き込みと読みとりを行うことができます。
Twitter(X)でいうところの「投稿」と「投稿の読み取り」ができるということです。

この2つの機能さえあれば大体のボットは作れそうですよね。(ただしリアルタイムに投稿をトリガーにする機能はまだないため対話型ボットは作成できません)

New Monacard ボット

https://primal.net/p/npub1mw9mq63qxynpae2pn85n9ty8f5tattpxzmlv0z4yl9uvat4wtfkqexqtal
実際のアカウント(primalというクライアントの画面です)

まず1つ目に作ったボットはモナカードの新規発行ボットです。モナカードが新しく発行されるとお知らせしてくれます。

キャラ紹介

アイコンはモナキャラットNo.291のハナショウブちゃんです。鼻と角が可愛くて気に入ってます。

モナキャラットは権利関係がはっきりしているので使いやすくていいですね。

でもモナキャラットを持っているヒトには、これが私のモナキャラットだぞといってお友達に自慢したり、モナキャラットの姿をSNSのアイコンとして使ったり、そういった心地のよい権利が与えられます。商用利用もできますが、大規模生産ラインに乗せるときはアーティストのあるひさんにひと声かけてみてください
https://monacharat.komikikaku.com/about

仕組み

https://card.mona.jp/ さまのAPIを使用させていただいております。

これが実際に稼働させているワークフローです。いろいろこまかいことをやっていて長くなっていますが基本的な仕組みは簡単で二行で説明できます。

  • 一定時間ごとにモナカード一覧のAPIを叩く
  • 新しいカードが発行されていたらNostrに投稿する。

ちなみにn8nはワークフローをjsonで出力でき、このボットのワークフローもこちらにサンプルとしておいてあります。(※最新のデータでない場合があります)
https://github.com/ocknamo/n8n-nodes-nostrobots/blob/main/sample/new_monacard_feed_bot .json

インポートすると実装できるのでよかったら試してみてください。(秘密鍵は自分で登録が必要)

工夫したところ

実行環境が自宅のサーバーというか実態はただのミニPCなのでスペックが貧弱です。そのため負荷はかけられなうえに、いつ落ちるかわかりません。そこで以下の2点を工夫しました。

  1. 実行間隔を1時間に1回にする
  2. たまに実行できなくても漏れが発生しないように作る

1は実行トリガーの設定を行うだけです。
2はモナカードAPIからの取得を3時間前から現在までの範囲として冗長にしておいて、そのあとボットの過去投稿を"Nostr Read"ノードを使用して取得し、すでに投稿済みのカードの重複を取り除くということを行うことで実現しています。

こうすることで例えば2~3時間ほどノードが落ちていてもその間の新規作成カードをあとから投稿することができます。

Dispenser Start ボット

https://primal.net/p/npub1gq6ee54n39ky9lx79x6cf85uu5ftqvxu8g3kq6uzfec0fndj5jfqnk9s7p

2つめに作ったボットはDispenserの販売開始をお知らせしてくれるボットです。お目当てのカードをいち早く見つけて売り切れる前に買いたいので作りました。

キャラ紹介

アイコンはモナキャラットNo.420のムシちゃんです。未来的な格好と奇跡的に名前にマッチした冷たい表情がたまりませんね。

仕組み

さっきよりかなり長いワークフローになってます。

新規販売開始データの取得には https://mpchain.info/ さまのAPIを使用させていただいてます。
また画像の表示などには https://card.mona.jp/ さまのAPIを使用させていただいております。

見ての通り長いので箇条書きで仕組みを説明すると以下のようになります。

  • mpchainさんのAPIでモナコインのブロック高さを取得
    • https://mpchain.info/api/networkを使用
  • データを取るブロック範囲を決める
  • mpchainさんのAPIでブロック内のDispenserの新規発売開始データを取る
    • https://mpchain.info/api/dispensers/{{ targetBlock }}を使用
  • すでに投稿したデータを除外
  • モナカードAPIとデータをマージ
  • 投稿数制限などを行う
  • Nostrに投稿

以上です。

こちらはいろいろと試しながら実装したのですが本当に正しく新規販売開始データを取得できているのかというのは確信が持てていません。間違っていたら指摘していただけるとたすかります。

こちらは結構継続的にアップデートをかけていたのでエクスポートデータは公開していないですが落ち着いてきたので、そのうち気が向いたら公開します。

工夫したところ

Nostrでは投稿(Event)にtagというデータを設定できます。実は今回そこに色々とmpchainさんから取得したメタデータをつっこんでいます。

とくに["datajson","{{ encodeURI(JSON.stringify($json.data)) }}"]のところです。JSONをそのままつっこんでますね。

このEventデータはあとからNostrネットワーク(リレー)から取得できるためメタデータをあとで自分のアプリケーションに使ったりすることができます。

たとえば今後、売買通知ボットなどを作ろうと思ったときにこのデータを使用することを考えています。
(ただしリレーのデータは永続化が保証されないので網羅性を期待できない販売通知ボットになると思いますが)

またこのデータはNostrネットワーク上にオープンに存在するので誰でも使用可能です。

さいごに

全然関係ないですが最近新しいモナキャラットをお迎えしました!思いがけず見つけると嬉しいですね。

https://monacharat.komikikaku.com/A1092794321323236217

今回ノーコードツール自体の説明は全然しませんでしたが、ノーコードツールは私のような忘れっぽい人間でもメンテナンスがしやすいのがいいところだと思います。たくさんボットを作っても管理画面がないと忘れてしまって知らない間に死んでいるということになりがちです。

また話が変わりますが、Twitterではボット作るのは大変になったみたいなのでボット作りたい人はぜひNostrに来ていただければとも思います。

アドベントカレンダー次回はrkgk_acさんの記事です!

Tip me

Discussion