ソーシャル投稿

Richfolio は買いシグナルを公開ソーシャルアカウント — X/TwitterFacebook ページThreads アカウント、LinkedIn ページ — に、メール+Telegram ブリーフと併せてオプションで投稿できます。動作するのはdailyintraday モードのみです(weekly や refresh では決して投稿しません)。

これは完全にオプトインです。ソーシャルの認証情報を設定しなければ何も投稿されず、Richfolio の他の機能はこれまでどおり動作します — 各プラットフォームは「credentials not set — skipping」という行をログに残して次へ進みます。


投稿される内容

投稿は意図的に汎用的な内容にしてあり、プライベートな情報は一切漏れません:

  • STRONG BUYBUY のシグナルのみ(HOLD/WAIT はスキップ)。
  • 各シグナルにはティッカー、アクション、確信度、短い理由、そしてオプションでバリュー評価が表示されます — それ以外は何もありません。
  • ターゲットポートフォリオと観察リストのティッカーは一律に「シグナル」としてまとめられます — 「ポートフォリオ vs 観察リスト」というラベルはないため、保有銘柄が明かされることは決してありません。
  • 決して投稿されないもの: 配分、ギャップ、推奨買い付け額、株数、ポートフォリオ総額。src/socialContent.ts 内の buildSignalLines() が唯一の許可リストのチョークポイントであり、sanitizeReason() が AI の理由に書き込まれうる配分ギャップ、ドル建ての金額、重複割引のテキストを除去します。どちらもユニットテストでカバーされています。
  • ティッカーは Facebook / Threads / LinkedIn ではクリック可能な #hashtag として描画されます(キャッシュタグは X でのみ機能し、そこでは $cashtag のまま残ります)。X 以外のプラットフォームでは、リーチを高めるために設定可能な汎用ハッシュタグのセットが追加されます。
  • すべての投稿は次の免責事項で終わります:「Not financial advice. Auto-generated by Richfolio.(投資助言ではありません。Richfolio により自動生成されています。)」

有効化/無効化

config.json 内の social ブロックがマスタースイッチです(デフォルト値を表示):

"social": {
  "enabled": true,
  "includeLinkInX": false,
  "hashtags": ["investing", "stocks", "stockmarket", "ETFs"]
}
  • enabled: false — 認証情報の有無にかかわらず、すべてのソーシャル投稿を無効化します。
  • includeLinkInX — X の投稿に分析リンクを含めます。リンクを含めると X の従量課金コストが上がるため、デフォルトではオフです。
  • hashtags — Facebook / Threads / LinkedIn で追加される汎用ハッシュタグ(先頭の # は省略可能)。X では追加されません。

各プラットフォームはさらに自身の認証情報でゲートされるため、enabledtrue でもキーが設定されていないプラットフォームはスキップされます。


Secret 一覧

これらをリポジトリの Secret(Settings → Secrets and variables → Actions → Secrets)として追加します。すべてオプションです — 利用したいプラットフォームのみ設定してください。

Secret プラットフォーム 注記
FACEBOOK_PAGE_ID Facebook ページの数値 id
FACEBOOK_PAGE_TOKEN Facebook 長期有効なページアクセストークン
THREADS_USER_ID Threads Threads の数値ユーザー id
THREADS_ACCESS_TOKEN Threads 長期有効なトークン(約 60 日で失効)
THREADS_TOKEN_PAT Threads Threads トークンを自動リフレッシュするためのオプションの PAT(下記参照)
LINKEDIN_ACCESS_TOKEN LinkedIn w_organization_social を持つ OAuth 2.0 トークン
LINKEDIN_ORG_URN LinkedIn 例:urn:li:organization:123456
X_API_KEY / X_API_SECRET X/Twitter OAuth 1.0a コンシューマキー
X_ACCESS_TOKEN / X_ACCESS_TOKEN_SECRET X/Twitter OAuth 1.0a ユーザートークン

Facebook ページのセットアップ

ランタイムが必要とするのは 2 つの値だけです:FACEBOOK_PAGE_ID長期有効な FACEBOOK_PAGE_TOKEN自分のページに管理者として投稿するため、アプリの開発モードのままで構いません — アプリレビューは不要です。

1. Meta アプリを作成

  1. developers.facebook.comMy AppsCreate App に移動。
  2. OtherBusiness のアプリタイプを選び、名前を付けます(例:「Richfolio Poster」)。

2. ページ管理のユースケースを追加

  1. アプリで Use cases を開き、Manage everything on your Page を選択。
  2. その Permissions を開いて Add します(Standard Access で十分です — 「Get Advanced Access」は無視してください):
    • pages_manage_posts — フィードへの投稿(必須のもの)
    • pages_read_engagement
    • pages_show_list

    これらは 「Ready for testing」 と表示されるはずです — これは管理者であるあなたが今すぐ利用できることを意味します。

3. ユーザートークンを取得

  1. Graph API Explorer を開きます。
  2. アプリを選択 → Get User Access Token → 3 つの pages_* 権限にチェック → Generate Access Token → 承認。

4. 長期有効なページトークンを発行

Richfolio にはトークン交換を代行するヘルパーが付属しています。一時的に .env に追加してください:

FACEBOOK_PAGE_ID=your_page_id          # numeric Page id
FACEBOOK_APP_SECRET=...                # App settings → Basic → App secret
FB_USER_TOKEN=...                      # the user token from step 3

そして実行します:

npx tsx smoke/fb-page-token.ts

これは短期有効なユーザートークンを長期有効なものと交換し、あなたのページを見つけて、有効期限のないページトークンを出力します。それを FACEBOOK_PAGE_TOKEN に貼り付け、その後 .env から FACEBOOK_APP_SECRETFB_USER_TOKEN削除してください — これらはセットアップ専用で、ランタイムでは決して使われません。

5. 検証

npx tsx smoke/smoke-facebook.ts             # checks the token (no posting)
npx tsx smoke/smoke-facebook.ts --post --cleanup   # posts a test, then deletes it

PASS が出れば、トークンが有効なページトークンであり、投稿がエンドツーエンドで動作することが確認できます。

6. GitHub に追加

FACEBOOK_PAGE_IDFACEBOOK_PAGE_TOKEN をリポジトリの Secret として追加します。アプリシークレットやユーザートークンは追加しないでください

トークンの寿命: ページトークンは事実上恒久的ですが、Facebook のパスワードを変更したり、アプリを取り消したり、ページ管理者でなくなったりすると失効します。投稿が止まった場合は、ステップ 3 から再発行してください。


Threads のセットアップ

Threads は Facebook と同じ Meta アプリを再利用します。THREADS_USER_ID と長期有効な THREADS_ACCESS_TOKEN が必要です。認可するアカウントが投稿元として表示されるアカウントになります — あなたのブランド用 Threads アカウントを使ってください。アカウントは公開である必要があります。

1. Threads のユースケースを追加 — Meta アプリで Use casesAccess the Threads API。スコープ threads_basicthreads_content_publish を有効にします。

2. 自分を Threads Tester として追加 — App Dashboard → App roles → RolesAdd PeopleThreads Tester → あなたの Threads ユーザー名を入力 → Threads アプリで招待を承認(Settings → Account → Website permissions)。

3. 長期有効なトークンを生成 — Threads ユースケースの Settings にある User Token Generator にあなたのテスターアカウントが一覧表示されます → Generate token。これはすでに長期有効です — 交換は不要です。.envTHREADS_ACCESS_TOKEN として貼り付けてください。

4. ユーザー id を取得して検証

npx tsx smoke/smoke-threads.ts             # prints THREADS_USER_ID; set it in .env
npx tsx smoke/smoke-threads.ts --post --cleanup   # posts a test (delete may be manual)

5. THREADS_USER_IDTHREADS_ACCESS_TOKEN を GitHub Secret に追加します。

トークンの失効と自動リフレッシュ: Threads の長期有効トークンは約 60 日で失効します。ワークフロー .github/workflows/refresh-threads-token.yml が毎月トークンをリフレッシュし、Secret に書き戻します — ただし THREADS_TOKEN_PAT Secret(リポジトリの Secrets: Read and write 権限を持つ fine-grained PAT)も追加した場合に限ります。その PAT がなければ、失効前に手動でトークンをリフレッシュしてください。


LinkedIn ページのセットアップ

LinkedIn は無料ですが、最も制限が厳しいです。必要なもの:

  1. あなたの会社ページに紐付いた LinkedIn Developer アプリ
  2. 「Community Management API」 プロダクト。これが w_organization_social スコープを付与します。これをリクエストするには、アプリの会社紐付けが認証済みである必要があり(Settings タブ)、アクセスフォームの提出が必要です(登録済みの事業者名を求められます)。
  3. ページの管理者によって生成された、w_organization_social を持つ OAuth 2.0 アクセストークン

設定:

  • LINKEDIN_ACCESS_TOKEN — OAuth 2.0 トークン。
  • LINKEDIN_ORG_URN — あなたの organization URN、例:urn:li:organization:123456(数字は会社ページの URL にあります)。
  • LINKEDIN_API_VERSION — オプションの上書き(デフォルトは直近の YYYYMM)。

npx tsx smoke/smoke-linkedin.ts(トークンチェック)と --post --cleanup(投稿テスト)で検証します。

LinkedIn のアクセストークンは約 60 日で期限切れになります(リフレッシュトークンは約 365 日有効)。定期的にリフレッシュする計画を立ててください。組織への投稿には登録済みの事業者が必要です。お持ちでない場合は、セルフサービスの「Share on LinkedIn」プロダクト(w_member_social)を使って個人プロフィールから投稿するようにポスターを書き換えることもできます。


X / Twitter のセットアップ

X には 2026 年 2 月以降、無料の投稿枠がありません。 投稿は従量課金です(1 投稿あたり約 $0.015、リンクを含むとさらに高くなります)。Richfolio には X ポスターが付属していますが、キーを追加するまでは休止状態のままです。

投稿は OAuth 1.0a ユーザーコンテキストを使用します。X Developer PortalRead and Write 権限のプロジェクト/アプリを作成し、以下を生成します:

  • X_API_KEY / X_API_SECRET — コンシューマ(API)キーとシークレット。
  • X_ACCESS_TOKEN / X_ACCESS_TOKEN_SECRET — あなたのアカウントのアクセストークンとシークレット。

1 投稿あたりのコストを抑えるため、config.jsonincludeLinkInX はオフのままにしてください。


動作の仕組み

daily と intraday モードでは、メールと Telegram の送信後に、Richfolio が sendSocialPosts()src/social.ts)を呼び出します。各プラットフォームは自身の try/catch の中で投稿するため、あるプラットフォームの失敗が他のプラットフォーム — あるいはすでに送信済みのメール/Telegram — をブロックすることは決してありません。

Richfolio をフォークした場合、上記のセットアップを自分自身のアカウントで完了するまで、ソーシャル投稿はオフのままです — 各トークンはその所有者のアカウントに投稿するため、認証情報を共有することはできません。


Richfolio — free, open-source portfolio monitoring. · Privacy Policy

This site uses Just the Docs, a documentation theme for Jekyll.