Limitless AI Pendant から Todoリストとライフログを作ろう(Obsidianに置くよ)

PC周りスキル

まずはじめに

「作ろう」とタイトルに書きましたが、親切に解説する記事じゃないです🙏
単に何をやったか自分用のメモです。やったこと無い事はAIに手順を聞いてその通りにやっているので、何をやったか忘れちゃうんですよね。ということで自分用の備忘録です。

Limitless AI Pendant とは?

そのうちこれについて熱く語る記事を書きたいと思います。
それぐらい良い!
https://www.limitless.ai/
もちろんAI好き・ガジェット好きの人におすすめだとは思うんですが、それよりもADHD気質の人におすすめしたいです。自分もそうなんじゃないかと思ってるんですが。

人生を全部録音してライフログを作るツールと説明しておきます。
競合には「会議を録音・AIでまとめる」商品があるんですが、Limitlessのライフログというコンセプトが良かったのでこちらを選びました。
あ、あとは転送の手間がないので。

何をしたいか

これを使ってやりたいことはいろいろありますが、欲張っちゃいけない。
まずは以下をやることにしました。

① Todoリスト・買い物リストを翌日のカレンダーに予定として登録する
② 1日の行動を記録する

①について。ADHDなのか元から忘れっぽいのか老化なのか分かりませんが、とにかく毎日やらなきゃいけないことを忘れる!
というわけで、Limitless Pendant を自分のメモとして使っています。
一番最強のメモだと思います。メモ帳とボールペン、またはスマホを出す手間がない。声で録音できるからね。

②については特に必要ではありませんが、せっかくのライフログツールなので記録してみようかなと。試しにやってみることにしました。
※ちなみに Limitless もデフォルトでインサイトというAIまとめ機能があります。しかも優秀✨Limitless用にかなり特化しています。
ですがこちらは今のところObsidianに転送する方法が分からないので(コピペするしかない?)、とりあえず自作のライフログを作ることにしました。

【手順】カレンダーにTodo登録 & ライフログ出力

ここから具体的な方法です。

obsidianとの連携

自分の記録として obsidian を使っているので(まだ試行錯誤中)、土台は obsidian です。
カレンダーへの登録は obsidian である必要は全然ないですが。

さて連携方法ですが、obsidian に limitless pendant と連携するプラグインがあります。
Limitless Lifelogs
こちらをコミュニティプラグインからインストールするだけです。
Limitless API の取得方法や設定方法などは検索すれば出ると思うので、各自お願いします!

ツールの選定

決めなければいけないのは2つ。

① フローの実行ツール(AIでTodoや1日の行動を抜き出して、Googleカレンダーやマークダウンファイルに出力する流れを何で実行するか)
② AI選定(会話の中からTodoなどを抜き出したり、1日の行動を要約するのに使うAI)

①フローの実行ツール

あまり詳しくないのですが、思いついたのはn8n。
あとはPythonや、GeminiCLIでできるんじゃないかな?ということでこれらでできるのか、他にツールがあるのかAIに聞いてみました。
するとまさに

1番おススメ:n8n
2番目におススメ:Python
3番目におススメ:GeminiCLI

こんな感じでした。理由などはAIに聞いてください。(適当)

しかしですね。n8nは使ったことないのですが、無料で使うならDockerを立ち上げるというじゃないですか。
私のパソコン、ちょっとくたびれてきてDockerが重いんです😭
立ち上がるのにも時間がかかるし、立ち上げてるときはファンの音がすごい。なるべく使いたくありません。

という訳で Python で一連の流れは実行することにしました。

②AI選定

これはですね。要はどのAPIなら無料で使えるか、という問題です。
課金するのであれば何の問題もなく、お好きなAIを選べばいいですね。

簡単に2025年10月現在の状況は以下の通りです。

ChatGPT API : 無料クレジットが付与されるけど使いきったら終わり & 特定のバージョンでデータ共有をOKにするなら無料トークンが付与される
Claude API : 有料
Gemini API : 無料枠あり

ということで Gemini にします!
いや~、こういうのってGoogleは無料枠作るよね。将来なにか起きないだろうか?と思いつつ、使っちゃいます。

Pythonバージョン確認

Pythonで作るということでバージョンの確認です。
Python 3.10以上が推奨のようです。
ターミナルで確認しましょう。

操作の流れの確認

気になったのが、obsidianのプラグインでLimitlessの会話を取得するところ。
プラグインではobsidianの左のメニューにある「Sync Limitless Lifelogs」というボタンを押すんです。これをPythonのコードで書けるのか?と思ったんですが無理みたい。

そっかー。そうだよね。
なので時間が来たら自動で実行するとかはできないので(できるけどその時点でLimitlessデータを読み込んでいないかも)カレンダーやファイル出力も手動でPythonを実行することにしました。
まあ今も毎日ツイッターに日誌を書いているし、それほど手間ではないでしょう。

ただその日のうちに出力するとは限らないので、日付は指定できるようにしました。

流れをまとめるとこんな感じです。

1. Limitless Lifelogsから指定日付のmdファイルを読み込み
2. Gemini APIでタスク抽出と行動まとめを生成
3. 翌日のGoogleカレンダーに終日予定登録
4. Lifelogsフォルダにマークダウン出力

ちなみにGoogleカレンダーに「予定」じゃなく「タスク」で登録することも考えたんですが、数が多くなりそうだし完了ボタンが押せなかったら悔しいので「予定」にしました。ちょっと弱気ですね。

APIキーの取得

2つ準備しなければいけません。

  1. Gemini API
  2. GoogleカレンダーAPI

意外とこれが面倒でした!
詳しくは各自調べるとして、ざっと簡単に述べると以下の手順です。

  1. Gemini API
    • Google AI Studioを利用
    • 「APIキーを作成」というようなボタンを押し、プロジェクト名を適当に名付ける
    • キーを取得。(たぶん)一度しか表示されないのでコピーして安全な場所に保管
  2. GoogleカレンダーAPI
    • こちらが面倒だった!
    • 「Google Cloud Console」から取得する
    • 気を付けるのが「Google Calendar API」だと読み込みしかできないので「OAuth 2.0 クライアント ID」を作成する
    • OAuth 同意画面の設定
      • [OAuth 同意画面]から必要情報を入力
    • [認証情報を作成]
      • [OAuth クライアント ID]
      • 「デスクトップアプリ」を選択
      • 名前は適当に
      • スコープの範囲を設定(もしかしてしなくても大丈夫だったのかも)
      • テストユーザーを自分のGoogleメアドに設定(※内部が選べなくて外部を選ぶ場合)
    • これらを設定するとAPI?キーとJSONファイルのダウンロードがでてきます
      • JSONをダウンロードし、ファイル名を credentials.json にリネームして、Pythonスクリプトと同じ場所に置きます

Pythonプログラミング

やっとプログラミングです。

置き場所を設定

本当はここはおすすめではないんですが、obsidian保管庫の中に置くことにしました。
分かりやすいし、最終的にPythonを実行する時に階層を移動しなくて良いので便利だし。

ちなみにおすすめじゃない理由は、保管庫をGoogleドライブの中に作っているからです。
APIキーを書いているので、ネットワークは良くないかなと。
でもGoogleドライブで何か流出したとかそういう話は聞いたことがないですよね。大丈夫だと思いますが、一応自己責任で!

プログラミング

もうAIにお任せです! lifelog_sync.py というファイルを作ってくれましたよ。これに先ほどAPI設定のときに作った credentials.json を一緒のフォルダに入れて完成です。

ちなみにAIへのプロンプトは以下でした。(初期よりちょっと変えました)

以下は音声ログから取得した1日の会話内容です。
この内容から以下の2つを抽出してください:

1. Todoリストと買い物リスト(箇条書き)
   - 今やることではなく、後でやろうと考えてるタスクや後で買おうと思っているものを抽出
   - 各項目は簡潔に

2. 1日の行動まとめ(箇条書き、だいたいの時間付き)
   - 誰が何をしていたか時系列で整理(誰がは分からなくてもOK)
   - 時間は概算でOK(例:午前中、14時頃、夕方など)

出力は以下のJSON形式で返してください:
{{
  "tasks": ["タスク1", "タスク2", ...],
  "activities": ["9:00頃 - 朝食を食べた", "10:00頃 - 会議に参加", ...]
}}

コードも一応載せておきます
lifelog_sync.py

import os
import sys
from datetime import datetime, timedelta
from pathlib import Path
import json
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from googleapiclient.discovery import build
import google.generativeai as genai
from dotenv import load_dotenv

# 環境変数の読み込み
load_dotenv()

# 設定
SCOPES = ['https://www.googleapis.com/auth/calendar']
BASE_PATH = Path(r"obsidianの保管庫のパスを入力")
SCRIPT_PATH = BASE_PATH / "Pythonファイルがあるフォルダを入力"
INPUT_PATH = BASE_PATH / "Limitlessを同期しているフォルダを入力"
OUTPUT_PATH = BASE_PATH / "一日のまとめを出力したいフォルダを入力"

def get_target_date():
    """コマンドライン引数から日付を取得、なければ今日の日付"""
    if len(sys.argv) > 1:
        try:
            return datetime.strptime(sys.argv[1], "%Y-%m-%d")
        except ValueError:
            print("日付のフォーマットが正しくありません。YYYY-MM-DD形式で指定してください。")
            sys.exit(1)
    return datetime.now()

def authenticate_google_calendar():
    """Google Calendar APIの認証"""
    creds = None
    token_path = SCRIPT_PATH / "token.json"
    credentials_path = SCRIPT_PATH / "credentials.json"
    
    if token_path.exists():
        creds = Credentials.from_authorized_user_file(str(token_path), SCOPES)
    
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                str(credentials_path), SCOPES)
            creds = flow.run_local_server(port=0)
        
        with open(token_path, 'w') as token:
            token.write(creds.to_json())
    
    return build('calendar', 'v3', credentials=creds)

def read_lifelog(date):
    """Limitless Lifelogsからファイルを読み込み"""
    filename = date.strftime("%Y-%m-%d") + ".md"
    filepath = INPUT_PATH / filename
    
    if not filepath.exists():
        print(f"エラー: {filepath} が見つかりません。")
        sys.exit(1)
    
    with open(filepath, 'r', encoding='utf-8') as f:
        return f.read()

def extract_with_gemini(content):
    """Gemini APIでタスクと行動まとめを抽出"""
    api_key = os.getenv('GEMINI_API_KEY')
    if not api_key:
        print("エラー: GEMINI_API_KEYが.envファイルに設定されていません。")
        sys.exit(1)
    
    genai.configure(api_key=api_key)
    model = genai.GenerativeModel('gemini-2.5-flash')
    
    prompt = f"""
以下は音声ログから取得した1日の会話内容です。
この内容から以下の2つを抽出してください:

1. Todoリストと買い物リスト(箇条書き)
   - 今やることではなく、後でやろうと考えてるタスクや後で買おうと思っているものを抽出
   - 各項目は簡潔に

2. 1日の行動まとめ(箇条書き、だいたいの時間付き)
   - 誰が何をしていたか時系列で整理(誰がは分からなくてもOK)
   - 時間は概算でOK(例:午前中、14時頃、夕方など)

出力は以下のJSON形式で返してください:
{{
  "tasks": ["タスク1", "タスク2", ...],
  "activities": ["9:00頃 - 朝食を食べた", "10:00頃 - 会議に参加", ...]
}}

会話内容:
{content}
"""
    
    response = model.generate_content(prompt)
    
    # JSONを抽出(マークダウンのコードブロックを除去)
    response_text = response.text.strip()
    if response_text.startswith("```json"):
        response_text = response_text[7:]
    if response_text.startswith("```"):
        response_text = response_text[3:]
    if response_text.endswith("```"):
        response_text = response_text[:-3]
    
    return json.loads(response_text.strip())

def create_calendar_event(service, date, tasks):
    """Google Calendarに終日イベントを作成"""
    next_day = date + timedelta(days=1)
    
    # タスクを箇条書きに整形
    description = "## Todoリスト・買い物リスト\n\n"
    for task in tasks:
        description += f"- {task}\n"
    
    event = {
        'summary': 'Todo・買い物リスト',
        'description': description,
        'start': {
            'date': next_day.strftime('%Y-%m-%d'),
        },
        'end': {
            'date': next_day.strftime('%Y-%m-%d'),
        },
    }
    
    event = service.events().insert(calendarId='primary', body=event).execute()
    print(f"✓ Googleカレンダーに登録しました: {next_day.strftime('%Y-%m-%d')}")

def save_lifelog_summary(date, activities):
    """行動まとめをマークダウンファイルとして保存"""
    filename = date.strftime("%Y-%m-%d") + ".md"
    filepath = OUTPUT_PATH / filename
    
    # フォルダが存在しない場合は作成
    OUTPUT_PATH.mkdir(parents=True, exist_ok=True)
    
    content = f"# {date.strftime('%Y年%m月%d日')}の行動\n\n"
    for activity in activities:
        content += f"- {activity}\n"
    
    with open(filepath, 'w', encoding='utf-8') as f:
        f.write(content)
    
    print(f"✓ 行動まとめを保存しました: {filepath}")

def main():
    print("=== Lifelog Sync 開始 ===\n")
    
    # 対象日付の取得
    target_date = get_target_date()
    print(f"対象日付: {target_date.strftime('%Y-%m-%d')}\n")
    
    # Lifelogの読み込み
    print("1. Lifelogを読み込んでいます...")
    content = read_lifelog(target_date)
    print(f"   読み込み完了 ({len(content)} 文字)\n")
    
    # Gemini APIで抽出
    print("2. Gemini APIで分析中...")
    result = extract_with_gemini(content)
    print(f"   抽出完了 (タスク: {len(result['tasks'])}件, 行動: {len(result['activities'])}件)\n")
    
    # Google Calendarに登録
    print("3. Google Calendarに登録中...")
    calendar_service = authenticate_google_calendar()
    create_calendar_event(calendar_service, target_date, result['tasks'])
    print()
    
    # Obsidianに保存
    print("4. 行動まとめを保存中...")
    save_lifelog_summary(target_date, result['activities'])
    print()
    
    print("=== 完了 ===")

if __name__ == "__main__":
    main()

こちらのファイルも必要です。
.env

# Gemini API Key
# https://makersuite.google.com/app/apikey から取得
GEMINI_API_KEY=ここにGEMINIのAPIキーを入力

あとは先ほど作った credentials.json を一緒のフォルダに入れるのを忘れずに!

実行

ターミナルでPythonファイルを入れたフォルダに移動し、以下のどちらかを実行します。

今日のログを出したいとき

py lifelog_sync.py

日付を指定してログを出したいとき

py lifelog_sync.py 2025-10-12

※ py なのは私の環境なので、python と入力する場合もあります。

最初は認証画面などが出ます。
そして token.json が作られます。

結果

無事出力できました!
我が家のある日のリストはこちらです。

いいんでない!?
便利便利!

一日のまとめはあまりにプライベートなので内緒です🤫
というより Limitless がまとめてくれるインサイトの方が面白い!!
プロンプトを工夫するか、インサイトをObsidianに入力する方法を探るか、どちらが良いか考え中です。

まとめ

他にもやりたいことはあります。
一日のまとめはObsidianのテンプレートを通して出力して、そこに自分が書き込める欄も作るとか。
自動で出力するのもいいけど、何かしら自分で書くことも大事だと思っているんです。
そういえば私はツイッターで「今日の予定」「日誌」を書いているので、それを転記してもいいかも。
というわけで Limitless AI Pendant × Obsidian 、まだまだ使い方を探ろうと思っています。

タイトルとURLをコピーしました