Obsidian / Session のログをDaily Note に保存する

ポモドーロに Session – Pomodoro focus timer with analytics をつかっているのだけど、セッション終了時にそのセッション内容を Obsidian の Daily Note に書き込むようにした記録です。

投稿される内容

- [hh:mm] #session #[カテゴリー]/[目標] [note] `([開始時間] - [終了時間])`

▼こんな感じで Obsidian の Daily Note に追記される

必要なもの

1. 準備

Session.app を開いて 設定 > ショートカット で 「Session end」を有効にします。
※ これで、セッション終了時に、ショートカットに登録した 「session_end」というショートカットが実行されるようになります。

ref. Session – Setup session automation on iOS and MacOS with Apple Shortcuts

2. ショートカットの登録

「session_end」という名称でショートカットを作成します。

input

「指定なし」で入力を受け取ります。Session終了後にアプリから引き渡されるデータは以下にまとまっています。

  1. Shortcut input data
    https://www.stayinsession.com/learn/session-automation-on-ios-and-macos-with-apple-shortcuts

JavaScript for Automation を実行

受け取った値を整形して、Obsidian に Advanced URI をつかって引き渡します。

obsidian://advanced-uri?daily=true&mode=append&openmode=silent&data=[整形した投稿内容]

JavaScript for Automation のコード内容
/**
 * Session から受け取ったデータを整形して Obsidian に送信する
 * - function run(input, parameters): ショートカットはこの run 関数を実行する。(JXA ではこの関数を定義する必要がある)
 * - input : 前のアクションからの入力データ。配列 (Array) になっている。 ほとんどの場合、前のステップから渡されたテキスト(やファイルパスなど)はこの配列の最初の要素にはいっており。 input[0] でアクセスできる。
 * - return: この JXA アクションの結果を、さらに次のショートカットアクションに渡したい場合は、run 関数の最後に return で値を返す。
 */
function run(input) {
  // アプリケーションと標準機能の準備
  var app = Application.currentApplication();
  app.includeStandardAdditions = true;

  // 入力データを取得
  var inputData = getInputParsedJson(input);
  if (!inputData) {
    return "run : 入力がありません";
  }

  // 入力データをフォーマット
  var { categoryTitle, title, startDate, endDate, notes } = formatInputData(inputData);

  // 現在の時間を取得し投稿日時を生成
  var prefix = `- ${getNow()}`;

  // 投稿データを生成
  var tag = `#session #${categoryTitle}`
  if ( title ) {
    tag += `/${title}`;
  }
  // - 日付の前後をバッククオートで囲うのはその日付が投稿時間と認識されないように。
  var dataToSend = `${prefix} ${tag} ${notes} \`(${startDate} - ${endDate})\``;

  // 投稿データを送信するURLを生成
  // - advanced-uri : プラグインを使って、Obsidian にデータを送信する
  // - daily=true : daily note に送信する
  // - mode=append : 追記する
  // - openmode=silent : Obsidian を開かずに実行する
  // - data= : 送信するデータ
  var baseUrl = "obsidian://advanced-uri?daily=true&mode=append&openmode=silent&data=";

  // 最終的なURLを組み立て
  var finalUrl = baseUrl + encodeURIComponent(dataToSend);

  try {
    // Obsidian を開く
    app.openLocation(finalUrl);
  } catch (e) {
    app.displayDialog("URLを開けませんでした: " + e);
  }

  // 次アクションでも input データを利用できるように
  return input;
}

/**
 * # ショートカットからの input を JSON としてパースする
 * - input は配列なので、通常は最初の要素 input[0] に目的のテキストが入っています
 * - パース成功したらオブジェクトを、失敗したら null を返します
 */
function getInputParsedJson(input) {
  // input 配列自体が空か、要素がない場合は null を返す
  if (!input || input.length === 0) {
    return null;
  }

  var receivedInputString = input[0]; // 配列の最初の要素を取得 (JSON文字列のはず)
  var receivedData = JSON.parse(receivedInputString);
  return receivedData;
}

/**
 * # 入力データをフォーマットする
 * - sessions.app から渡される json : https://www.stayinsession.com/learn/session-automation-on-ios-and-macos-with-apple-shortcuts
 */
function formatInputData(inputData) {
  var category = inputData.category || {};

  return {
    categoryTitle: category.title || "",
    title: inputData.title || "",
    startDate: formatDateFromDateString(inputData.start_date || ""),
    endDate: formatDateFromDateString(inputData.end_date || ""),
    notes: inputData.notes || ""
  }
}

/**
 * # 日付文字列をフォーマットする
 * - 日付文字列を受け取り、HH:MM 形式に変換します。
 * @param {string} dateString - ISO 8601 形式の日付文字列
 * @returns {string} - フォーマットされた時間 (HH:MM)
 */
function formatDateFromDateString(dateString) {
  return formatTime(new Date(dateString));
}

/**
 * # 現在の時間を取得する
 * @returns {string} - フォーマットされた時間 (HH:MM)
 */
function getNow() {
  var now = new Date();
  return formatTime(now);
}

/**
 * # 時間をフォーマットする
 * param {Date} dateObject - 日付オブジェクト
 * @returns {string} - フォーマットされた時間 (HH:MM)
 */
function formatTime(dateObject) {
  var hour = String(dateObject.getHours()).padStart(2, '0');
  var min = String(dateObject.getMinutes()).padStart(2, '0');
  return `${hour}:${min}`;
}

コメントをどうぞ

メールアドレスが公開されることはありません。 が付いている欄は必須項目です