tech-news-digest について
根拠に基づく日次・週次レポートを作成するチーム向けの、設定可能なテックニュース要約ワークフローです。複数の情報源を収集・統合して重複を除き、編集方針に従って検証後、複数形式で出力します。
主な機能
- 016 種類の情報源から並列収集
- 02情報源の統合と重複排除
- 03トピック別の要約選定
- 04日次・週次の編集方針
- 05Markdown 検証と PDF・メール出力
活用シーン
- 01日次テックニュース要約の作成
- 02週次トピック総括の作成
- 03リリースとプロジェクト候補の追跡
- 04メールや PDF 向けレポート出力
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ draco-agent/ tech-news-digest --skill tech-news-digestインストール後、Claude Code で/tech-news-digestを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
README.mdCHANGELOG.mdCONTRIBUTING.md.gitignoreLICENSEREADME_CN.mdrequirements.txt.github/workflows/test.ymlconfig/schema.jsonconfig/defaults/topics.jsonsources.jsonreferences/digest-prompt.mdreferences/templates/email.mddiscord.mdmarkdown.mdpdf.mdscripts/fetch-github.pyenrich-articles.pyconfig_loader.pyfetch-reddit.pyfetch-rss.pyfetch-twitter.pygenerate-pdf.pymerge-sources.pysanitize-html.pyfetch-web.pyrun-pipeline.pysource-health.pysend-email.pysummarize-merged.py詳細
テックニュースダイジェスト
エビデンスに基づくテックダイジェストです。統一された収集方法と、各形式で共有される編集上の選定を採用しています。モードの方針については、信頼できる情報源である references/digest-prompt.md に従ってください。
編集方針
- Daily では、元のセクションを維持します。概要は2~4文です。設定済みトピック(通常は LLM、AI Agent、Crypto、Frontier Tech)ごとに項目を掲載し、各トピックで条件を満たす項目を3~5件目指します。KOL の見解は最大3件、リリースは最大3リポジトリ、プロジェクト発掘は最大3件、ブログ紹介は最大3件、全体で重複のない項目は最大30件です。ニュースやブログの説明は通常、変化、根拠、影響を簡潔な2~3文で記載します。項目がない場合も見出しは残し、カバー状況を注記します。内容を埋めるための水増しはしません。セクション内の内容を最適化します。GitHub リリースを短くする依頼を、レポート全体の再設計や1メッセージのダイジェストに置き換えてはいけません。
- Weekly は重複のない項目を最大35件とし、概要と、設定順(通常は LLM、AI Agent、Crypto、Frontier Tech)に並べた設定済みトピックのセクションを含めます。各トピックで、内容のある要約を2~4件掲載することを目安とします。各要約は、その週の進展、根拠、影響を結び付けた簡潔な2~4文で構成し、見出しを単に連結しません。項目がないトピック、主要リリース、プロジェクト、見解/読み物の各見出しは残し、事実に即した箇条書き以外のカバー状況を注記します。主要リリースは最大5リポジトリ(説明は中国語で80文字以内)、プロジェクトは最大3件、見解/深掘り記事は最大4件です。任意の来週の注目項目は最大3件とし、今後のリリース、修正、不確実性を扱います。実験を無理に含めません。事実に基づく注目項目には出典を付けます。提案されたものの実施されていない実験には、限定的な出典免除を明示して適用します。
- 上限はノルマではありません。要約内の根拠となる出来事と、単独の注目項目を数えます。両モードでトピック別セクションを維持し、全体を3つのテーマに限定しません。本文の上限は、URL のリンク先を除き、Daily は6500文字、Weekly は10000文字です。上限まで埋めてはいけません。
- セキュリティ関連の取り上げは必須です。
references/digest-prompt.mdにある主要アラート/検索の手順と、配信前チェックに従います。既存のトピックは維持します。どちらのモードでも、信頼性の高い緊急インシデントがある場合に限り、概要の後に任意の🛡️ セキュリティ警報を設けます。Weekly では、重大なものの緊急ではないリスクについて、専用のセキュリティ/リスクセクションを任意で設けることもできます。該当する内容がなければ省略し、既存の上限内で数え、重複を排除します。チェックと判断を記録します。収集に失敗したことを、インシデントがなかった証拠として扱ってはいけません。 - 内部スコアよりも関連性、影響、根拠を優先します。例外的な主張には、可能であれば独立した評価に加えて、一次の技術的根拠を必要とします。満たせない場合は除外するか、重要度を下げます。公開スコア、ソーシャル指標、運用統計は掲載しません。Daily では、内容のある重複しない KOL の見解を維持します。重大なカバー不足には、生の件数を示さず、簡潔な但し書きを1件だけ付けることができます。詳細は最終運用ログに記載します。
- レポート全体で、出来事と正規 URL の重複を排除します。Daily で同じ内容を再掲するのは、進展があった場合に限ります。Weekly では Daily で取り上げた内容を統合できます。Daily ではブログ紹介を維持します。Weekly の見解/深掘り記事には、独自の意見、論文、ドキュメント、事後分析、エッセイを含めることができます。
- プロジェクト発掘は、トレンドの検証を意味しません。累計値から成長を推定したり、意味のある変更のない成熟したリポジトリを繰り返し取り上げたりしてはいけません。プロンプトにある重大なリリースのルール、正確なバージョン、公式リンクを維持します。
- 太字のタイトルを付けた通常の箇条書きを使います。Discord のリンクは簡潔な
[出典](<URL>)形式にします。セクション単位に分割した各チャンクは、番号を含めて1700文字以内にします。設定された言語を使用し、指定がある場合は説明を簡体字中国語で記載します。 - 配信前に、
python3 scripts/validate-digest.py --input FILE --mode dailyまたは--mode weeklyを使って正規アーカイブを検証し、すべてのエラーを修正します。Weekly の生成では、設定済みトピックごとに、設定順に--topic-heading '正確なローカライズ済み見出し'を1つずつ追加します。これらのフラグがない場合、検証ゲートはカスタム見出しを推測できません。検証が欠落している、または失敗した場合は配信できません。さらに、要約内の重複しない出来事の件数、必須の非トピック見出しと概要、セキュリティ項目の配置、根拠とカバー状況の誠実さ、フォーマット間の整合性も手動で確認します。 - Discord、Markdown、メール、PDF では、選定内容と判断を同一にします。運用統計と実行時間の帰属は、本文ではなく最終ログに記載します。
- 旧式の
ITEMS_PER_SECTION、BLOG_PICKS_COUNT、EXTRA_SECTIONSは、モード別ポリシーに置き換えられる参考パラメーターです。これらの件数や追加セクションは無視し、特に Weekly のトレンド重複を避けます。
クイックスタート
-
設定のセットアップ:デフォルト設定は
config/defaults/にあります。カスタマイズする場合は、ワークスペースにコピーしてください。mkdir -p workspace/config cp config/defaults/sources.json workspace/config/tech-news-digest-sources.json cp config/defaults/topics.json workspace/config/tech-news-digest-topics.json -
環境変数:
TWITTERAPI_IO_KEY- twitterapi.io API キー(任意、推奨)X_BEARER_TOKEN- Twitter/X 公式 API のベアラートークン(任意、フォールバック)TAVILY_API_KEY- Tavily Search API キー、Brave の代替(任意)WEB_SEARCH_BACKEND- ウェブ検索バックエンド:auto|brave|tavily(任意、デフォルト:auto)BRAVE_API_KEYS- Brave Search API キー。ローテーション用にカンマ区切りで指定します(任意)BRAVE_API_KEY- フォールバック用の単一の Brave キー(任意)GITHUB_TOKEN- GitHub 個人アクセストークン(任意、レート制限が緩和されます)
-
ダイジェストを生成:
# Unified pipeline (recommended) — runs all 6 sources in parallel + merge python3 scripts/run-pipeline.py \ --defaults config/defaults \ --config workspace/config \ --hours 48 --freshness pd \ --archive-dir workspace/archive/tech-news-digest/ \ --output /tmp/td-merged.json --verbose --force -
選択して検証:
references/digest-prompt.mdに従い、Discord、メール、PDF 向けに同じ選択内容を出力する前に、正規の Markdown を検証してください。
設定ファイル
sources.json - 統合データソース
{
"sources": [
{
"id": "openai-rss",
"type": "rss",
"name": "OpenAI Blog",
"url": "https://openai.com/blog/rss.xml",
"enabled": true,
"priority": true,
"topics": ["llm", "ai-agent"],
"note": "Official OpenAI updates"
},
{
"id": "sama-twitter",
"type": "twitter",
"name": "Sam Altman",
"handle": "sama",
"enabled": true,
"priority": true,
"topics": ["llm", "frontier-tech"],
"note": "OpenAI CEO"
}
]
}
topics.json - 強化されたトピック定義
{
"topics": [
{
"id": "llm",
"emoji": "🧠",
"label": "LLM / Large Models",
"description": "Large Language Models, foundation models, breakthroughs",
"search": {
"queries": ["LLM latest news", "large language model breakthroughs"],
"must_include": ["LLM", "large language model", "foundation model"],
"exclude": ["tutorial", "beginner guide"]
},
"display": {
"max_items": 8,
"style": "detailed"
}
}
]
}
スクリプトのパイプライン
run-pipeline.py - 統合パイプライン(推奨)
python3 scripts/run-pipeline.py \
--defaults config/defaults [--config CONFIG_DIR] \
--hours 48 --freshness pd \
--archive-dir workspace/archive/tech-news-digest/ \
--output /tmp/td-merged.json --verbose --force
- 機能:6 つの取得ステップをすべて並列実行し、その後マージ、重複排除、スコアリングを行います
- 出力:レポート生成にすぐ使える、マージ済みの最終 JSON(合計約 30 秒)
- メタデータ:ステップごとの所要時間と件数を
*.meta.jsonに保存します - GitHub 認証:
$GITHUB_TOKENが設定されていない場合、GitHub App トークンを自動生成します - フォールバック:これが失敗した場合は、以下の個別スクリプトを実行してください
個別スクリプト(フォールバック)
fetch-rss.py - RSS フィード取得ツール
python3 scripts/fetch-rss.py [--defaults DIR] [--config DIR] [--hours 48] [--output FILE] [--verbose]
- 並列取得(10 ワーカー、ホストごとに最大 2 件を同時実行)、ジッター付きバックオフで再試行、feedparser と正規表現によるフォールバック
- タイムアウト:フィードごとに 30 秒。
$TECH_NEWS_DIGEST_STATE_DIRで ETag/Last-Modified キャッシュを使用します
fetch-twitter.py - Twitter/X の KOL モニター
python3 scripts/fetch-twitter.py [--defaults DIR] [--config DIR] [--hours 48] [--output FILE] [--backend auto|official|twitterapiio]
- バックエンドを自動検出します:
TWITTERAPI_IO_KEYが設定されていれば twitterapi.io を使用し、そうでなければX_BEARER_TOKENが設定されている場合に公式 X API v2 を使用します - レート制限の処理、エンゲージメント指標、バックオフ付き再試行
fetch-web.py - ウェブ検索エンジン
python3 scripts/fetch-web.py [--defaults DIR] [--config DIR] [--freshness pd] [--output FILE]
- Brave API のレート制限を自動検出します:有料プランではクエリを並列実行し、無料プランでは順次実行します
- API がない場合:エージェント用の検索インターフェースを生成します
fetch-github.py - GitHub リリースモニター
python3 scripts/fetch-github.py [--defaults DIR] [--config DIR] [--hours 168] [--output FILE]
- 並列取得(10 ワーカー)、30 秒のタイムアウト
- 認証の優先順位:
$GITHUB_TOKEN→ GitHub App による自動生成 →ghCLI →releases.atom - トークンがない場合(または 403/429 のレート制限時)は、認証不要で REST のクォータも消費しない
github.com/<repo>/releases.atomを読み込み、torvalds/linuxなどのタグのみのリポジトリも取得します - Atom フィードには すべて のタグが含まれるため、
<major>.<minor>形式のバージョン(v2.13.0、v6.19-rc4)が付いたタグのみを保持します。これにより、PyTorch のtrunk/<sha>やviable/strict/<epoch>など、実際のリリースを押しのける CI タグを除外します
fetch-github.py --trending - プロジェクト探索(旧フラグ)
python3 scripts/fetch-github.py --trending [--hours 48] [--output FILE] [--verbose]
- GitHub API を検索して探索候補を取得します。検索結果だけでは、本当のトレンドであることは確認できません。
- 中立的な内部ベーススコアは 5 で、成長を示すものではありません。
daily_stars_estや累計値から算出した成長指標はありません。日次の探索件数は 3 件以下、週次も 3 件以下とし、そのプロジェクトを試すべき現在の理由が必要です。
fetch-reddit.py - Reddit 投稿取得ツール
python3 scripts/fetch-reddit.py [--defaults DIR] [--config DIR] [--hours 48] [--output FILE]
- 並列取得(4 ワーカー)、認証不要の公開 JSON API
- スコアフィルタリング対象のサブレディット 13 件
enrich-articles.py - 記事全文の拡充
python3 scripts/enrich-articles.py --input merged.json --output enriched.json [--min-score 10] [--max-articles 15] [--verbose]
- スコアの高い記事の全文を取得します
- Cloudflare Markdown for Agents(優先)→ HTML 抽出(フォールバック)→ スキップ(有料記事/ソーシャル)
- スコアのしきい値が低いブログドメインの許可リスト(≥3)
- 並列取得(5 ワーカー、タイムアウト 10 秒)
merge-sources.py - 品質スコアリングと重複排除
python3 scripts/merge-sources.py --rss FILE --twitter FILE --web FILE --github FILE --reddit FILE
- 品質スコアリング、URL の重複排除(トラッキングパラメーターを削除し、クエリは保持)、タイトル類似度による重複排除(75%)、前回のダイジェストによるペナルティ
- 複数ソースのボーナス:同じ記事を裏付けるソースの種類が1つ増えるごとに +5
- トピックの優先順位は
topics.jsonの順序から決まります。同期を維持するには--defaults/--configを渡してください - 出力:トピックごとにグループ化され、スコア順に並んだ記事
validate-config.py - 設定バリデーター
python3 scripts/validate-config.py [--defaults DIR] [--config DIR] [--verbose]
- JSON スキーマ検証、トピック参照チェック、ID の重複検出
generate-pdf.py - PDF レポート生成ツール
python3 scripts/generate-pdf.py --input report.md --output digest.pdf [--verbose]
- Markdown ダイジェストを、中国語のタイポグラフィ(Noto Sans CJK SC)を使用したスタイル付き A4 PDF に変換します
- 絵文字アイコン、ページヘッダー/フッター、青のアクセントテーマ。
weasyprintが必要です。
sanitize-html.py - 安全な HTML メール変換ツール
python3 scripts/sanitize-html.py --input report.md --output email.html [--verbose]
- Markdown をインライン CSS を使った XSS 対策済みの HTML メールに変換します
- URL の許可リスト(http/https のみ)、テキストコンテンツの HTML エスケープ
source-health.py - ソース稼働状況モニター
python3 scripts/source-health.py --rss FILE --twitter FILE --github FILE --reddit FILE --web FILE [--verbose]
$TECH_NEWS_DIGEST_STATE_DIR/source-health.jsonで、過去 7 日間のソースごとの成功/失敗履歴を追跡します- 稼働状況に問題のあるソース(失敗率が 50% 超、サンプル数が 2 件以上)を報告します
summarize-merged.py - マージ済みデータの要約
python3 scripts/summarize-merged.py --input merged.json [--top N] [--topic TOPIC]
- LLM が利用しやすい、マージ済みデータの読みやすい要約
- トピックごとの上位記事をスコアや指標とともに表示します
ユーザーによるカスタマイズ
ワークスペース設定のオーバーライド
workspace/config/ にカスタム設定を配置すると、デフォルト設定をオーバーライドできます。
- ソース:新しいソースを追加し、
"enabled": falseを指定してデフォルトを無効にします - トピック:トピックの定義、検索クエリ、表示設定をオーバーライドします
- マージロジック:
- 同じ
idを持つソース → ユーザー設定版が優先されます - 新しい
idを持つソース → デフォルトに追加されます - 同じ
idを持つトピック → ユーザー設定版がデフォルトを完全に置き換えます
- 同じ
ワークスペース設定のオーバーライド例
// workspace/config/tech-news-digest-sources.json
{
"sources": [
{
"id": "simonwillison-rss",
"enabled": false,
"note": "Disabled: too noisy for my use case"
},
{
"id": "my-custom-blog",
"type": "rss",
"name": "My Custom Tech Blog",
"url": "https://myblog.com/rss",
"enabled": true,
"priority": true,
"topics": ["frontier-tech"]
}
]
}
テンプレートと出力
標準 Markdown(references/templates/markdown.md)
- 日次/週次の構成は
references/digest-prompt.mdで定められます。すべての形式で、検証済みの選定結果を1つ使用します。
Discord テンプレート(references/templates/discord.md)
- シンプルな箇条書き、太字のタイトル、インラインの
[来源](<URL>)リンクを使用します。セクションを考慮して分割し、番号を含めて 1700 文字以下にします。
メールテンプレート(references/templates/email.md)
sanitize-html.pyで検証済みの Markdown を変換し、send-email.pyで HTML ファイルを送信します。- 選定結果は同じものを使い、追加のメタデータセクションや運用統計は含めません。
PDF テンプレート(references/templates/pdf.md)
- 標準レポートと同じ内容で、中国語のタイポグラフィとページ番号を使用した A4 形式です。
scripts/generate-pdf.pyで生成します(weasyprintが必要です)。PDF 独自のコンテンツはありません。
デフォルトソース(216 件が有効)
- RSS フィード(93 件):AI 研究所、arXiv、研究ブログ、テクノロジーニュース、暗号資産ニュース、中国のテクノロジーメディア、YouTube チャンネル
- Twitter/X の KOL(76 件):AI 研究者、モデル研究所、暗号資産のリーダー、テクノロジー企業の幹部
- GitHub リポジトリ(47 件):主要なオープンソースプロジェクト(llama.cpp、vLLM、SGLang、LangGraph、MCP など)
- Reddit(13 件、デフォルトでは無効):Reddit はデータセンターの IP アドレスをブロックします。
REDDIT_CLIENT_ID/REDDIT_CLIENT_SECRETを設定し、オーバーレイで再度有効にしてください - Web 検索(4 トピック):LLM、AI エージェント、暗号資産、最先端テクノロジー
さらに、上流のフィードが停止しているため、デフォルトの RSS/GitHub ソース 7 件は無効な状態で同梱されています。それぞれに理由を示す note が付いています。
すべてのソースには、適切なトピックタグと優先度があらかじめ設定されています。
依存関係
pip install -r requirements.txt
任意ですが、推奨されます:
feedparser>=6.0.0- RSS の解析を改善します(利用できない場合は正規表現にフォールバックします)jsonschema>=4.0.0- 設定を検証します
すべてのスクリプトは Python 3.8+ の標準ライブラリのみで動作します。
モニタリングと運用
ヘルスチェック
# Validate configuration
python3 scripts/validate-config.py --verbose
# Test RSS feeds
python3 scripts/fetch-rss.py --hours 1 --verbose
# Check Twitter API
python3 scripts/fetch-twitter.py --hours 1 --verbose
アーカイブ管理
- ダイジェストは
<workspace>/archive/tech-news-digest/に自動的にアーカイブされます - 前回のダイジェストのタイトルを重複検出に使用します
- 古いアーカイブは自動的に削除されます(90 日以上)
エラー処理
- ネットワーク障害:指数バックオフで再試行します
- レート制限:適切な待機時間を設けて自動的に再試行します
- 無効なコンテンツ:適切に処理を縮退させ、詳細をログに記録します
- 設定エラー:わかりやすいメッセージとともにスキーマを検証します
API キーと環境変数
~/.zshenv などに設定します:
# Twitter (at least one required for Twitter source)
export TWITTERAPI_IO_KEY="your_key" # twitterapi.io key (preferred)
export X_BEARER_TOKEN="your_bearer_token" # Official X API v2 (fallback)
export TWITTER_API_BACKEND="auto" # auto|twitterapiio|official (default: auto)
# Web Search (optional, enables web search layer)
export WEB_SEARCH_BACKEND="auto" # auto|brave|tavily (default: auto)
export TAVILY_API_KEY="tvly-xxx" # Tavily Search API (free 1000/mo)
# Brave Search (alternative)
export BRAVE_API_KEYS="key1,key2,key3" # Multiple keys, comma-separated rotation
export BRAVE_API_KEY="key1" # Single key fallback
export BRAVE_PLAN="free" # Override rate limit detection: free|pro
# Reddit (required to enable the Reddit layer — it ships disabled)
export REDDIT_CLIENT_ID="xxx" # Script-type app from reddit.com/prefs/apps
export REDDIT_CLIENT_SECRET="xxx"
export REDDIT_USERNAME="xxx" # Optional, User-Agent string only
# GitHub (optional, unlocks richer release notes)
export GITHUB_TOKEN="ghp_xxx" # PAT (simplest)
export GH_APP_ID="12345" # Or use GitHub App for auto-token
export GH_APP_INSTALL_ID="67890"
export GH_APP_KEY_FILE="/path/to/key.pem"
- Twitter:
TWITTERAPI_IO_KEYを推奨(月額 $3~5)。フォールバックとしてX_BEARER_TOKENを使用します。autoモードでは、最初に twitterapiio を試します - ウェブ検索:Tavily(
autoモードで推奨)または Brave。オプションです。利用できない場合は、エージェントの web_search にフォールバックします - GitHub:PAT が設定されていない場合は、GitHub App からトークンを自動生成します。認証なしでのフォールバックは 60 件/時です
- Reddit:デフォルトでは無効です。データセンターの IP アドレスからのリクエストは Reddit により 403 を返されます。OAuth API を使用するには、
REDDIT_CLIENT_ID/REDDIT_CLIENT_SECRETを設定し、ソースを再度有効にしてください
Cron/スケジュールタスクとの連携
OpenClaw Cron(推奨)
cron プロンプトにパイプラインの手順をハードコードしないでください。代わりに references/digest-prompt.md を参照し、設定パラメーターのみを渡します。これにより、パイプラインのロジックをスキルリポジトリ内に保ち、すべてのインストール環境で一貫性を維持できます。
既存の cron ジョブでは、引き続き ITEMS_PER_SECTION、BLOG_PICKS_COUNT、EXTRA_SECTIONS が渡される場合があります。互換性のため受け入れますが、割り当て数と追加セクションは無視してください。モードポリシーが優先されます。新しい例では、これらの項目を省略しています。
日次ダイジェストの Cron プロンプト
Read <SKILL_DIR>/references/digest-prompt.md and follow the complete workflow to generate a daily digest.
Replace placeholders with:
- MODE = daily
- TIME_WINDOW = past 1-2 days
- FRESHNESS = pd
- RSS_HOURS = 48
- ENRICH = true
- SUBJECT = Daily Tech Digest - YYYY-MM-DD
- WORKSPACE = <your workspace path>
- SKILL_DIR = <your skill install path>
- DISCORD_CHANNEL_ID = <your channel id>
- EMAIL = (optional)
- LANGUAGE = English
- TEMPLATE = discord
Follow every step in the prompt template strictly. Do not skip any steps.
週次ダイジェストの Cron プロンプト
Read <SKILL_DIR>/references/digest-prompt.md and follow the complete workflow to generate a weekly digest.
Replace placeholders with:
- MODE = weekly
- TIME_WINDOW = past 7 days
- FRESHNESS = pw
- RSS_HOURS = 168
- ENRICH = true
- SUBJECT = Weekly Tech Digest - YYYY-MM-DD
- WORKSPACE = <your workspace path>
- SKILL_DIR = <your skill install path>
- DISCORD_CHANNEL_ID = <your channel id>
- EMAIL = (optional)
- LANGUAGE = English
- TEMPLATE = discord
Follow every step in the prompt template strictly. Do not skip any steps.
このパターンを使用する理由
- 信頼できる唯一の情報源:パイプラインのロジックは cron 設定に分散させず、
digest-prompt.mdにまとめられています - 移植可能:異なる OpenClaw インスタンスでも同じスキルを使用でき、パスとチャンネル ID を変更するだけです
- 保守しやすい:スキルを更新すると、すべての cron ジョブに変更が自動的に反映されます
- アンチパターン:パイプラインの手順を cron プロンプトにコピーしないでください。内容にずれが生じます
複数チャンネルへの配信に関する制限
OpenClaw はプロバイダー間の分離を適用します。1 つのセッションからメッセージを送信できるプロバイダーは 1 つだけです(たとえば、Discord または Telegram のいずれかであり、両方ではありません)。ダイジェストを複数のプラットフォームに配信するには、プロバイダーごとに個別の cron ジョブを作成してください:
# Job 1: Discord + Email
- DISCORD_CHANNEL_ID = <your-discord-channel-id>
- EMAIL = [email protected]
- TEMPLATE = discord
# Job 2: Telegram DM
- DISCORD_CHANNEL_ID = (none)
- EMAIL = (none)
- TEMPLATE = telegram
2 つ目のジョブのプロンプトでは、DISCORD_CHANNEL_ID への配信を対象プラットフォームへの配信に置き換えてください。
これはバグではなくセキュリティ機能です。コンテキストをまたいだデータの漏えいを防ぎます。
セキュリティに関する注意事項
実行モデル
このスキルではプロンプトテンプレートパターンを使用します。エージェントが digest-prompt.md を読み、その指示に従います。これは OpenClaw の標準的なスキル実行モデルです。エージェントはスキルが提供するファイル内の構造化された指示を解釈します。すべての指示はスキルバンドルに含まれており、インストール前に監査できます。
ネットワークアクセス
Python スクリプトは、以下の宛先にリクエストを送信します:
- RSS フィードの URL(
tech-news-digest-sources.jsonで設定) - Twitter/X API(
api.x.comまたはapi.twitterapi.io) - Brave Search API(
api.search.brave.com) - Tavily Search API(
api.tavily.com) - GitHub API(
api.github.com) - Reddit JSON API(
reddit.com)
その他のエンドポイントにデータが送信されることはありません。すべての API キーは、スキルのメタデータで宣言された環境変数から読み込まれます。
シェルの安全性
メールの配信には send-email.py を使用します。このスクリプトは、HTML 本文とオプションの PDF 添付ファイルを含む、適切な MIME マルチパートメッセージを作成します。件名の形式はハードコードされています(Daily Tech Digest - YYYY-MM-DD)。PDF の生成には weasyprint 経由で generate-pdf.py を使用します。プロンプトテンプレートでは、信頼できないコンテンツ(記事のタイトル、ツイートのテキストなど)をシェル引数に展開することを明示的に禁止しています。メールアドレスと件名には、静的なプレースホルダー値のみを使用してください。
ファイルアクセス
スクリプトは config/ から読み込み、workspace/archive/ に書き込みます。ワークスペース外のファイルにはアクセスしません。
サポートとトラブルシューティング
よくある問題
- RSS フィードの取得に失敗する:ネットワーク接続を確認し、詳細を確認するには
--verboseを使用してください - Twitter のレート制限:ソースを減らすか、間隔を長くしてください
- 設定エラー:具体的な問題を確認するには
validate-config.pyを実行してください - 記事が見つからない:時間範囲(
--hours)とソースの有効化状態を確認してください
デバッグモード
すべてのスクリプトは、詳細なログ記録とトラブルシューティングに使える --verbose フラグに対応しています。
パフォーマンスの調整
- 並列ワーカー:システムに合わせてスクリプト内の
MAX_WORKERSを調整してください - タイムアウト設定:ネットワークが遅い場合は
TIMEOUTを増やしてください - 記事数の上限:必要に応じて
MAX_ARTICLES_PER_FEEDを調整してください
セキュリティに関する考慮事項
シェル実行
ダイジェストプロンプトは、エージェントにシェルコマンド経由で Python スクリプトを実行するよう指示します。すべてのスクリプトパスと引数はスキルで定義された定数であり、コマンドにユーザー入力が埋め込まれることはありません。subprocess を使用するスクリプトは 2 つあります。
run-pipeline.pyは子の取得スクリプトをオーケストレーションします(すべてscripts/ディレクトリ内にあります)fetch-github.pyには 2 つのサブプロセス呼び出しがあります。- JWT 署名用の
openssl dgst -sha256 -sign(GH_APP_*環境変数が設定されている場合のみ。自ら構築した JWT ペイロードに署名し、ユーザーコンテンツは関与しません) gh auth tokenCLI フォールバック(ghがインストールされている場合のみ。gh 独自の認証情報ストアから読み取ります)
- JWT 署名用の
ユーザーが提供したコンテンツや取得したコンテンツが、サブプロセスの引数に埋め込まれることは一切ありません。メールの送信には、MIME メッセージをプログラムで構築する send-email.py を使用するため、シェルへの埋め込みはありません。PDF の生成には、weasyprint 経由で generate-pdf.py を使用します。メールの件名は静的な書式文字列のみであり、取得したデータから構築されることはありません。
認証情報とファイルへのアクセス
スクリプトが ~/.config/、~/.ssh/、その他の認証情報ファイルを直接読み取ることはありません。すべての API トークンは、スキルのメタデータで宣言された環境変数から読み取られます。GitHub 認証のフォールバック順は次のとおりです。
$GITHUB_TOKEN環境変数(指定する値はユーザーが管理します)- GitHub App トークンの生成(
GH_APP_ID、GH_APP_INSTALL_ID、GH_APP_KEY_FILEを設定した場合のみ。opensslCLI を使ってインラインで JWT に署名し、外部スクリプトは使用しません) gh auth tokenCLI(gh 独自の安全な認証情報ストアに処理を委任します)- 認証なし(60 req/hr、安全なフォールバック)
認証情報の自動検出を行わない場合は、$GITHUB_TOKEN を設定してください。スクリプトは手順 2~3 を試さず、直接その値を使用します。
依存関係のインストール
このスキルがパッケージをインストールすることはありません。requirements.txt に記載されているのは、参考用のオプションの依存関係(feedparser、jsonschema)のみです。すべてのスクリプトは Python 3.8 以降の標準ライブラリで動作します。オプションの依存関係が必要な場合は、ユーザーが仮想環境にインストールしてください。このスキルが pip install を実行することはありません。
入力のサニタイズ
- URL の解決では、HTTP(S) 以外のスキーム(javascript:、data: など)を拒否します
- RSS のフォールバック解析では、バックトラッキングのない単純な正規表現パターンを使用します(ReDoS のリスクはありません)
- 取得したコンテンツはすべて、表示専用の信頼できないデータとして扱います
ネットワークアクセス
スクリプトは、設定された RSS フィード、Twitter API、GitHub API、Reddit JSON API、Brave Search API、Tavily Search API に HTTP リクエストを送信します。受信接続やリスナーは作成されません。