Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save knishioka/43fcd9bc840499e46e6dcd117c07aaeb to your computer and use it in GitHub Desktop.
Save knishioka/43fcd9bc840499e46e6dcd117c07aaeb to your computer and use it in GitHub Desktop.
自然言語でのタスク入力をパースし、Claude 3.7 Sonnet APIを使用してタスクの詳細(サマリー、説明、期限)を分析・抽出した後、適切なプロパティを持つNotion databaseに新しいエントリを作成するAlfred workflowスクリプト。完了時には通知と効果音も含まれています。
#!/bin/bash
# 今日の日付を取得
TODAY=$(date +"%Y-%m-%d")
# タスク内容
TASK_DESCRIPTION="{query}"
# システムメッセージを変数として定義
SYSTEM_MESSAGE='あなたはタスク分析の専門家です。
ユーザーが送信したタスクから以下の情報を抽出し、構造化されたJSONとして返してください:
1. タスクの要約
2. 実行すべきアクションの説明
3. 期限
期限は「due_date」フィールドとしてISO形式(YYYY-MM-DD)で返してください。
タスク内に相対的な日付表現(例:「3日後」「来週の金曜日」)がある場合は、
ユーザーが提供した現在の日付を基準として計算してください。
期限が明示されていない場合は、due_dateフィールドを空の文字列("")と設定してください。'
# リクエストデータをファイルとして作成
ANTHROPIC_REQUEST_FILE=/tmp/alfred-wf_anthropic-request.json
cat > $ANTHROPIC_REQUEST_FILE << EOF
{
"model": "claude-3-7-sonnet-20250219",
"max_tokens": 2048,
"messages": [
{
"role": "user",
"content": "今日の日付は${TODAY}です。以下のタスクから、タスクのサマリー、必要なアクション、期限を抽出してください。タスク:${TASK_DESCRIPTION}"
}
],
"system": $(jq -Rs . <<< "${SYSTEM_MESSAGE}"),
"tools": [
{
"name": "task_analyzer",
"description": "タスクを分析し、サマリー、アクションの説明、期限を抽出する",
"input_schema": {
"type": "object",
"properties": {
"summary": {
"type": "string",
"description": "タスクの簡潔な要約"
},
"description": {
"type": "string",
"description": "タスクを完了するために必要なアクションの詳細説明"
},
"due_date": {
"type": "string",
"description": "タスクの期限をISO形式(YYYY-MM-DD)で表示。期限が未指定の場合は今日の日付に合わせる"
}
},
"required": ["summary", "description", "due_date"]
}
}
]
}
EOF
# 作成したJSONファイルの内容を確認(デバッグ用)
echo "送信するJSONデータ:" >&2
cat $ANTHROPIC_REQUEST_FILE >&2
CLAUDE_RESPONSE=/tmp/alfred-wf_anthropic-response.json
# Claudeがタスク内容を生成
curl -s https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d @$ANTHROPIC_REQUEST_FILE > $CLAUDE_RESPONSE
# エラーチェック関数
check_error() {
local response_file="$1"
# ファイルからレスポンスを読み込む
local response=$(cat "$response_file")
# オーバーロードエラーの検出
if [[ "$response" == *"overloaded_error"* ]]; then
terminal-notifier -title "API エラー" -message "サーバーが過負荷状態です。後で再試行してください。" -sound default
echo "エラー: サーバーが過負荷状態です。後で再試行してください。" >&2
exit 1
fi
# その他のエラー検出
if [[ "$response" == *"\"error\":"* ]]; then
error_message=$(echo "$response" | grep -o '"message":"[^"]*"' | cut -d'"' -f4)
terminal-notifier -title "API エラー" -message "エラーが発生しました: $error_message" -sound default
echo "エラー: $error_message" >&2
exit 1
fi
}
# レスポンスからエラーをチェック
check_error $CLAUDE_RESPONSE >&2
# レスポンス全体を表示(デバッグ用)
echo "APIレスポンス:" >&2
cat $CLAUDE_RESPONSE >&2
# jqを使ってレスポンスから必要な情報を抽出
SUMMARY=$(cat $CLAUDE_RESPONSE | jq -r '.content[] | select(.type=="tool_use").input.summary')
DESCRIPTION=$(cat $CLAUDE_RESPONSE | jq -r '.content[] | select(.type=="tool_use").input.description')
# 期限が空または取得できなかった場合は本日の日付で埋める
DUE_DATE=$(cat $CLAUDE_RESPONSE | jq -r '.content[] | select(.type=="tool_use").input.due_date')
if [ -z "$DUE_DATE" ] || [ "$DUE_DATE" = "取得失敗" ]; then
DUE_DATE="$TODAY"
echo "期限が特定できなかったため、本日の日付($TODAY)を設定しました。" >&2
fi
# 結果を表示
echo "サマリー: $SUMMARY" >&2
echo "説明: $DESCRIPTION" >&2
echo "期限: $DUE_DATE" >&2
# 最終的な結果をJSONとして出力
JSON_RESULT=$(cat <<EOF
{
"summary": "$SUMMARY",
"description": "$DESCRIPTION",
"due_date": "$DUE_DATE"
}
EOF
)
echo "最終結果(JSON):" >&2
echo "$JSON_RESULT" | jq . >&2
# notionにタスクを登録
NOTION_RESPONSE=/tmp/alfred-wf_notion-response.json
NOTION_REQUEST_FILE=/tmp/alfred-wf_notion-request.json
cat > $NOTION_REQUEST_FILE << EOF
{
"parent": {
"database_id": "${DATABASE_ID}"
},
"properties": {
"Name": {
"title": [
{
"text": {
"content": "${SUMMARY}"
}
}
]
},
"Due Date": {
"type": "date",
"date": {
"start": "${DUE_DATE}"
}
},
"Priority": {
"type": "select",
"select": {
"name": "Middle"
}
}
},
"children": [
{
"object": "block",
"type": "paragraph",
"paragraph": {
"rich_text": [
{
"type": "text",
"text": {
"content": "${DESCRIPTION}"
}
}
]
}
}
]
}
EOF
curl -s -X POST "https://api.notion.com/v1/pages" \
-H "Authorization: Bearer ${NOTION_TOKEN}" \
-H 'Content-Type: application/json' \
-H 'Notion-Version: 2022-06-28' \
-d @$NOTION_REQUEST_FILE > $NOTION_RESPONSE 2>/tmp/notion_debug.log
# NotionのページIDを取得
PAGE_ID=$(cat $NOTION_RESPONSE | jq -r '.id')
# NotionのページURLを作成
NOTION_URL="notion://www.notion.so/${PAGE_ID//-/}"
# terminal-notifierで通知
terminal-notifier -title "Notion Task追加" -subtitle "$SUMMARY" -message "\[期限: $DUE_DATE] ${DESCRIPTION}" -open "$NOTION_URL" -sound "Glass"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment