RaycastからObsidianのデイリーノートにメモ追記

要望
画面遷移なしでObsidianメモが取りたいよーー
要件整理
- Raycastから1アクションで起動できること
- コンテンツは以下の形式であること
###### $(date +%H:%M)
<multi-line-input-text>
- コンテンツは
Daily/YYYY/MM/YYYY-MM-DD.md
の# Journal
最下部に追記されること - 起動→入力→書き込み完了までのフローで画面遷移・アプリのフォーカス移動が生じないこと(バックグラウンド動作?)

結論
bottomのpostで記載の通り、以下の実装で実現できた。
Obsidian側の設定
- Quickaddで、Raycastから呼び出す専用のChoiceを定義
- URIのクエリパラメータとして受け取る変数は、テンプレート内で
{{VALUE:<my_var_name>}}
で展開される
- URIのクエリパラメータとして受け取る変数は、テンプレート内で
- Advanced-URIをenable
Raycast/シェルスクリプト側の設定
-
@raycast.argument{1,3}
で引数を3つ受取り、1~3行の文字列として結合 - Pythonワンライナーで文字列をURIエンコード
- Advanced-URIからRaycast向けに定義したChoiceを呼び出し、エンコードした文字列を渡す
- URIからQuickaddを呼ぶ際は、
value-<var_name>=<var_value>
の形式で変数定義
- URIからQuickaddを呼ぶ際は、

参考資料
アプローチ検討- Raycastからbash, Pythonを走らせて直接ローカルのVault配下に書き込む
- RaycastのObsidianプラグインから"Append to daily note"する
- "Advanced URI"必須。これを使うとローカルAPIサーバライクにObsidianのリソースを操作できるっぽい
2は複数行inputできなさそう。
公式README: https://github.com/marcjulianschwarz/obsidian-raycast?tab=readme-ov-file#append-to-daily-note-1
1ベースにAdvanced URIを使えばいけそう?

ChatGPT-4oに相談
# @raycast.schemaVersion 1
# @raycast.title Add to Journal
# @raycast.mode fullOutput
# @raycast.icon 🗒️
#!/bin/bash
# 設定: あなたのObsidian Vault名をここに記入(スペースは%20に置き換える)
VAULT_NAME="ObsidianVault" # 例: "My%20Vault"
# ファイルパスを生成
DATE=$(date +%Y-%m-%d)
YEAR=$(date +%Y)
MONTH=$(date +%m)
FILEPATH="Daily/$YEAR/$MONTH/$DATE.md"
HEADING="Journal"
# 複数行入力受付
echo "Enter your journal entry (End with Ctrl+D):"
USER_INPUT=$(cat)
# 現在時刻取得
TIME=$(date +%H:%M)
# フォーマット準備
FORMATTED_CONTENT="###### $TIME"$'\n'"$USER_INPUT"
# URLエンコード(複数行対応)
ENCODED_CONTENT=$(python3 -c "import urllib.parse, sys; print(urllib.parse.quote(sys.stdin.read()))" <<< "$FORMATTED_CONTENT")
# Advanced URI 呼び出し
URI="obsidian://advanced-uri?vault=$VAULT_NAME&filepath=$FILEPATH&heading=$HEADING&append=$ENCODED_CONTENT"
# 実行(バックグラウンドでObsidianに渡す)
open "$URI"
一旦作ってみる。

たぶんadvanced-uriのクエリパラメータで直接daily noteパス解決できるな。
構文も微妙に違う。
open --background
しないと要件4を破りそう。
FBしてみた。いけそう??
#!/bin/bash
echo "Enter your journal entry (End with Ctrl+D):"
USER_INPUT=$(cat)
TIME=$(date +%H:%M)
FORMATTED_CONTENT="###### $TIME"$'\n'"$USER_INPUT"
ENCODED_CONTENT=$(python3 -c "import urllib.parse, sys; print(urllib.parse.quote(sys.stdin.read()))" <<< "$FORMATTED_CONTENT")
URI="obsidian://advanced-uri?vault=Vault&daily=true&mode=append&heading=Journal&data=$ENCODED_CONTENT"
open --background "$URI"

入力受付がうまくいってない
Obsidian側への出力
# Journal
###### 17:17

グエーーー
Raycast Script Command は、GUIから実行するだけでは標準入力(cat)を受け付けない仕様 です。
ユーザー入力を受け取りたい場合、Raycastは次の二通りの方法を提供しています:
① @raycast.argument を使う(単一行限定)
→ これはあなたの求める 複数行 には向いていません。
② Script Command をターミナルモード(Terminal Emulator)で実行
→ Raycast は「フルターミナル入力」を直接サポートしていません。
つまり、Raycast Script Command から cat で対話的に複数行取得することは仕様上不可能です。
これは「Done in 0.13s」と即座に返ってきてしまう理由でもあります。
案2. 別途対話的ツールを呼び出す
例えば、osascript で入力ダイアログを出す方法があります。
USER_INPUT=$(osascript -e 'Tell application "System Events" to display dialog "Enter your journal entry:" default answer "" buttons {"OK"} default button 1' -e 'text returned of result')
デフォルトの仕様ではRaycast commandから標準入力は取れない?
osascript
やってみるか?
@raycast.argument
で3つまでなら引数を取得できるらしい。
3行以上はそうそう無かろうし、システムに自分を合わせに行くか?

osascript
を試す
USER_INPUT=$(osascript -e 'Tell application "System Events" to display dialog "Enter your journal entry:" default answer "" buttons {"OK"} default button 1' -e 'text returned of result')
一行しか入らんな。osascript
に深入りするのは避けたいんだが。
default answerパラメータを"\n"にすれば改行可能になったが、こんどはReturnキーが改行入力に奪われて書き込みがキーボードで完結できなかった。
USER_INPUT=$(osascript -e 'Tell application "System Events" to display dialog "Enter your journal entry:" default answer "\n" buttons {"OK"} default button 1' -e 'text returned of result')
@raycast.argument{1,3}を試す
複数行入力はかなった!!挿入位置の調整が必要
# @raycast.argument1 { "type": "text", "placeholder": "1行目" }
# @raycast.argument2 { "type": "text", "placeholder": "2行目", "optional": true }
# @raycast.argument3 { "type": "text", "placeholder": "3行目", "optional": true }
USER_INPUT="$1"
if [ -n "$2" ]; then
USER_INPUT="$USER_INPUT"$'\n'"$2"
fi
if [ -n "$3" ]; then
USER_INPUT="$USER_INPUT"$'\n'"$3"
fi
TIME=$(date +%H:%M)
FORMATTED_CONTENT="###### $TIME"$'\n'"$USER_INPUT"
ENCODED_CONTENT=$(python3 -c "import urllib.parse, sys; print(urllib.parse.quote(sys.stdin.read()))" <<< "$FORMATTED_CONTENT")
URI="obsidian://advanced-uri?vault=Vault&daily=true&mode=append&heading=Journal&data=$ENCODED_CONTENT"
open --background "$URI"

挿入位置の柔軟な調整はAdvanced URIだけでは難しい。
導入済みのQuickaddをcallするようにするか??

Quickaddの既存Choiceを呼び出す
コンテンツの内容はRaycastとbashで確定する。
パラメータのスキーマだけ調節すれば行けるんじゃないか???
#!/bin/bash
# Required parameters:
# @raycast.schemaVersion 1
# @raycast.title Append memos
# @raycast.mode compact
# Optional parameters:
# @raycast.icon 📝
# @raycast.argument1 { "type": "text", "placeholder": "1行目" }
# @raycast.argument2 { "type": "text", "placeholder": "2行目", "optional": true }
# @raycast.argument3 { "type": "text", "placeholder": "3行目", "optional": true }
USER_INPUT="$1"
if [ -n "$2" ]; then
USER_INPUT="$USER_INPUT"$'\n'"$2"
fi
if [ -n "$3" ]; then
USER_INPUT="$USER_INPUT"$'\n'"$3"
fi
# TIME=$(date +%H:%M)
# FORMATTED_CONTENT="**$TIME**"$'\n'"$USER_INPUT"
ENCODED_CONTENT=$(python3 -c "import urllib.parse, sys; print(urllib.parse.quote(sys.stdin.read()))" <<< "$USER_INPUT")
URI="obsidian://quickadd?choice=Raycast-fleeting&value-raycast_input=$ENCODED_CONTENT"
open --background "$URI"
決定版!!
パラメータ記載の通り、Raycast-fleeting
というQuickaddのCapture型Choiceを別で作った。
Raycast-fleeting
は以下の通り設定する。
###### {{time}}
{{VALUE:raycast_input}}
これで、Obsidianを開いているとき向けの既存の複数行入力用Choiceとの競合も避けられる。
参考
時間がかかってしまった...