Invokable > 戻る
2024-07-04
Laravel

Threads APIの使い方

いつものように通知を使いたいのがメインなので最低限のクライアント(機能を増やしたいならmacroで拡張)。
Socialiteも入れたけど公式が対応した場合は削除する。

Contribute to kawax/laravel-threads development by creating an account on GitHub.

  1. ドキュメント
  2. Meta for Developersで「アプリ」を作るまで
  3. ユースケースのカスタマイズ
  4. Socialite用のClient IDとClient Secret
  5. Threadsのトークン
  6. トークンの使用
  7. Threadsテスターに追加した自分のアカウントに投稿
  8. 自分の投稿を取得
  9. Socialiteで認証
  10. 長期トークンの更新

ドキュメント

The Threads API enables businesses to create and publish content on a person’s behalf on Threads and to display those posts within an app solely to the person who created it.

Meta for Developersで「アプリ」を作るまで

Facebook for Developersで、人と人のつながりを広げましょう。AI、ビジネスツール、ゲーム、オープンソース、パブリッシング、ソーシャルハードウェア、ソーシャル統合、バーチャルリアリティを探求できます。開発者の学習と交流を促進するFacebookのグローバルプログラムをご確認ください。

  • Facebookアカウントが必要なはず
  • 「アプリを作成」
  • 「ビジネスポートフォリオをリンクしない」
  • ユースケースでThreads APIを選択

ユースケースのカスタマイズ

アプリのダッシュボードまで進んだら、ユースケースからThreads APIの設定をカスタマイズ。

アクセス許可

threads_basicは必須なので最初から有効。投稿のためにthreads_content_publishを追加。

設定

Threadsテスターに自分のThreadsアカウントを追加。Threadsのウェブサイトで許可。トークンを生成。自分のアカウントに投稿するだけならこのトークンだけでいい。

Socialite/OAuthで認証してトークンを取得するならコールバックURLの設定も必要。これは後からでいい。

Socialite用のClient IDとClient Secret

アプリ設定→ベーシックの「ThreadsアプリID」と「Threads App Secret」を使う。

上側に「アプリID」と「app secret」があるけどこっちは違う。

Threadsのトークン

短期トークンと長期トークンがある。

Socialiteで取得できるのは短期トークン。短期トークンを長期トークンに変換すれば60日か90日間有効なトークンを得られる。長期トークンを更新すれば有効期限が伸びた新しい長期トークンを得られるので更新しながら使えばずっと使える。

Threadsテスターで生成されるのは最初から長期トークンなのでSocialiteは不要。

長期トークンの更新が必要なので.envに書いたままずっと使うことはできない。一人分だとしてもDBかキャッシュに保存して更新できるようにしておく。

APIの利用に必須なのは長期トークンだけなのでトークンについて理解できれば十分。

トークンの使用

ドキュメントではクエリパラメータで使用しているけど

&access_token=<ACCESS_TOKEN>

AuthorizationヘッダーでもいいのでLaravelのHttpクライアントならwithToken()が使える。ちょっと投稿するだけならパッケージ使う必要はなくHttpクライアントでいい。

Http::withToken('')->post();

Threadsテスターに追加した自分のアカウントに投稿

トークンはプロフィールページに入力欄作ってusersテーブルに保存して$user->threads_tokenで使える、と仮定。この辺は好きなように。

Threadsへの投稿は「text, image, videoを投稿する」と「publishで公開する」の2段階の工程が必要。

use Revolution\Threads\Facades\Threads;

Threads::token($user->threads_token);

$id = Threads::createText('test');
Threads::publish($id)

imageやvideoは公開されてるURLが必要。直接アップロードはできない。
Storage内のファイルを使うならurlで指定する。

use Revolution\Threads\Facades\Threads;
use Illuminate\Support\Facades\Storage;

Threads::token($user->threads_token);

$id = Threads::createImage(url: Storage::url('cat.png'), text: 'test');
Threads::publish($id)

動画の場合は30秒待ったほうがいいらしいのでpublish時に何秒sleepを入れるか指定できる。publish時に待ってもいいし、Threads::status()でチェックしてもいいし、キューで30秒遅らせてもいい。

use Revolution\Threads\Facades\Threads;
use Illuminate\Support\Facades\Storage;

Threads::token($user->threads_token);

$id = Threads::createVideo(url: Storage::url('dog.mov'), text: 'test');
Threads::publish($id, sleep: 30)

2段階に分かれてるのは複数のimage, videoをまとめて投稿できるカルーセル機能のためと予想。

use Revolution\Threads\Facades\Threads;
use Illuminate\Support\Facades\Storage;

Threads::token($user->threads_token);

$id1 = Threads::createImage(url: Storage::url('cat1.png'), is_carousel: true);
$id2 = Threads::createImage(url: Storage::url('cat2.png'), is_carousel: true);
$id = Threads::createCarousel(children: [$id1, $id2], text: 'test');
Threads::publish($id)

一時変数を使うのはLaravelらしくない使い方になるけどカルーセルのことを考えるとこれが無難。

自分の投稿を取得

use Revolution\Threads\Facades\Threads;

$posts = Threads::token($user->threads_token)->posts();

$postsはAPIからのレスポンスそのままのただの配列なので使いにくいけどLaravelならCollectionにして好きなように使えばいいので余計な加工はしない。Illuminate\Http\Client\Responseを返すのが便利なので最近はよく使っているけど今回はなし。

        collect($posts['data'] ?? [])->each(function (array $post) {
            //dump($post);
            // $post['text'] ?? '';
            // Arr::get($post, 'text');
        });

投稿データは「画像だけの投稿にはtextがない」とか意外と項目の抜けがあるので注意が必要。

取得件数のデフォルトは25。上限は100。limitで指定できる。

use Revolution\Threads\Facades\Threads;

$posts = Threads::token($user->threads_token)->posts(limit: 50);

全部省略できるけどposts()は引数が多くなった。
名前付き引数が登場してから「配列で渡す」や「専用のクラスを渡す」よりも「省略すればいいだけなので引数を増やす」傾向が強くなった。

Socialiteで認証

configと.envに追加。

config/services.php

    'threads' => [
        // Threads App ID
        'client_id' => env('THREADS_CLIENT_ID'),
        // Threads App Secret
        'client_secret' => env('THREADS_CLIENT_SECRET'),
        'redirect' => env('THREADS_REDIRECT_URL', '/threads/callback'),
    ],

.env

THREADS_CLIENT_ID=
THREADS_CLIENT_SECRET=
THREADS_REDIRECT_URL=/threads/callback

ユースケースのコールバックURLのリダイレクト先を設定。
httpsが必須。localhostでも保存はできるけど実際には動かないかもしれない。
面倒なので最初からサーバーに公開して動かすのが早い。

コールバックURLリダイレクト:https://example.com/threads/callback
他2つは同じでもhttps://example.com/でもいい。必要なら後で設定。

routes/web.phpでの例。

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use Laravel\Socialite\Facades\Socialite;
use Revolution\Threads\Facades\Threads;

Route::get('threads/redirect', function () {
    return Socialite::driver('threads')->redirect();
})->middleware('auth');

Route::get('threads/callback', function (Request $request) {
    if ($request->missing('code')) {
        dd($request);
    }

    /** @var \Laravel\Socialite\Two\User $user */
    $user = Socialite::driver('threads')->user();

    dump($user);

    $long_token = Threads::exchangeToken($user->token, config('services.threads.client_secret'))['access_token'];
    dump($long_token);

    $request->user()->fill(['threads_token' => $long_token])->save();

})->middleware('auth');

いつものSocialiteだけどThreads::exchangeToken()で短期トークンから長期トークンへの変換が必要。
長期トークンさえ取得できれば後はThreadsテスターと同じ。

長期トークンの更新

ここまでは省略してるけど使う時に毎回更新するか、タスクスケジュールで定期的に更新する。

use Revolution\Threads\Facades\Threads;

$token = Threads::token($user->threads_token)->refreshToken()['access_token'] ?? null;
$user->fill(['threads_token' => $token])->save();
投稿者 Invokable
0件のコメントを読むにはログインしてください。
登録 ログイン