LoginSignup
3
3

Misskeyのウィジェット(AiScript App)やプラグインなどで使う定数はページに保存すると便利

Last updated at Posted at 2023-10-13

まえがき

今回の記事は"Pageのデータを取得@AiScriptで困ったときに見るメモ - Qiita"で説明されているページのデータを取得できるという記述に対して「それができると何が嬉しいのか」を説明する記事です。

全てのケースで「定数はページに保存すると便利」と主張するものではありません。

主張

前提

AiScriptにはMk:api()という関数があります1。この関数はMisskey APIにリクエストする関数です。そして、Mk:api("pages/show" {pageId: pageId})あるいはMk:api("pages/show", {name: pageTitle, username: userName})のように書くことでページのデータを取得できます。
例えば、pageIdとコンテント名からデータを取るようなページの中のデータを取り出す関数はこのようになるでしょう。

ただし、以下のコードはページのコンテントの配置に強く依存します。
コンテンツの配置にあった関数を定義する方が良いでしょう。

@getPageContentData(pageId, contentName){
  let contents = Mk:api("pages/show" {pageId: pageId}).content.filter(@(content){content.title==contentName})
  if ((contents.len < 1) || (contents[0].type!="section")) {return null}
  let childrens = contents[0].children
  if ((childrens.len < 1) || (childrens[0].type!="text")) {return null}
  return childrens[0].text
}

このようにすることで、pageIdcontentNameからデータの取得が可能なことがわかりました。
また、これはユーザーに関わらず利用可能だと考えられます2

どのように使うか

前提として、ページの内容は一般的には読み込みしかできません。以上を踏まえて、定数データなどに対して利用しましょう。
ページにはstr型のデータしか置くことはできません。そのため、数字やオブジェクトも文字列で表現しなければなりません。そこで、JSONというデータ形式の出番です。JSONという形式はerrorfnなどの一部を除くあらゆる形式のデータをstr型で表現できる形式です。この形式を利用して、ページにデータを保存することができそうです。

どのようなケースに有効か

ここまでで、ページのこのような手法は以下のようなケースで有効です

  • 変更が想定される定数データ
  • 形式が統一されている定数データ

有効ではないケース

一方で、これが有効ではないケースもあります。

  • 明らかに変更が行われないであろう定数(円周率など)
  • 変数

何が嬉しいのか

これができて嬉しいケースは、主にウェジェットとプラグインを利用している場合です。
もし、定数の変更のたびにコードを書き換えると、その都度ユーザーにソースコードの更新をお願いする必要があります。つまり、ユーザーに手間をかけたり、ユーザー間での得られるサービスに差が発生する要因にもなります。
しかし、このページでデータを管理するモデルでは、そのような問題を起こさずにデータの更新を行えます。そのため、ユーザー側の負担減少や、ユーザー間での得られるサービス格差などを無くすことができます。

実際に使うシナリオ

以下では実例を提示します。

おみくじPlay

公式プリセットからの変更点
  • {result}{Str:lf}{THIS_URL}となっていたところを{result}に変更(ウェジェットとして扱うため)
Omikuji
/// @ 0.16.0
// ユーザーごとに日替わりのおみくじのプリセット

// 選択肢
let choices = [
	"ギガ吉"
	"大吉"
	"吉"
	"中吉"
	"小吉"
	"末吉"
	"凶"
	"大凶"
]

// シードが「ユーザーID+今日の日付」である乱数生成器を用意
let random = Math:gen_rng(`{USER_ID}{Date:year()}{Date:month()}{Date:day()}`)

// ランダムに選択肢を選ぶ
let chosen = choices[random(0 (choices.len - 1))]

// 結果のテキスト
let result = `今日のあなたの運勢は **{chosen}** です。`

// UIを表示
Ui:render([
	Ui:C:container({
		align: 'center'
		children: [
			Ui:C:mfm({ text: result })
			Ui:C:postFormButton({
				text: "投稿する"
				rounded: true
				primary: true
				form: {
					text: `{result}`
				}
			})
		]
	})
])

さて、ここで"歴史に遺る超吉"を追加するケースを考えましょう。
ここで、choicesを直接編集してしまうと、このウェジェットを利用している人全員にウェジェットのスクリプトの書き換えを要求しなければなりません。
それでは面倒なので、choicesに関するコードをあらかじめ以下のようにしておきましょう。

- let choices = [
- 	"ギガ吉"
- 	"大吉"
- 	"吉"
- 	"中吉"
- 	"小吉"
- 	"末吉"
- 	"凶"
- 	"大凶"
- ]
+ let choices = Json:parse(getPageContentData(pageId, contentName))

そしてページ側のテキストをこのように指定します。

- ["ギガ吉","大吉","吉","中吉","小吉","末吉","凶","大凶"]
+ ["歴史に遺る超吉","ギガ吉","大吉","吉","中吉","小吉","末吉","凶","大凶"]

こうすることで、ウェジェット側のコードを書き換えずに新しいパターンを容易に追加できます。

続きのようなもの

出典

  1. 正確にはAiScriptの関数ではないですが、Misskeyコンソールなどから呼び出せるため、このような表現をしました。

  2. ただしブロックなどの場合で未検証

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3