YOU

前回は画像付きのポスト投稿をやってみました。
今回は、指定のURLのリンクカードを使った投稿をしてみます。

今回もアクセストークンは取得済みとします。

// 対象のURL
$uri = 'https://www.cross-clover.info/posts/5';

// OGPを取得
// 今回は取得の方法は割愛します
$ogp = [];
$title = $ogp->meta->title;  // og:title
$description = $ogp->meta->description;  // og:description
$image_url = $ogp->meta->image->url;  // og:image

// og:imageが指定されている場合は、BlueSkyへ画像のアップロードが必要
$thumb = [];
if ($image_url !== '') {
  // 画像データの取得
  // file_get_contents()やgetimagesize()なんかを使ってなんとか取得します
  $image_body = file_get_contents($image_url);
  $mime_type = 'image/png';  // 今回はとりあえずPNGということに

  // BlueSkyへ画像をアップロード
  $headers = [
    'Content-Type: ' . $mime_type ,
    'Authorization: Bearer ' . $accessJwt,
  ];

  $ch = curl_init();
  curl_setopt_array($ch, [
    CURLOPT_URL => 'https://bsky.social/xrpc/com.atproto.repo.uploadBlob',
    CURLOPT_HTTPHEADER => $headers,
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $image_body,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_SSL_VERIFYPEER => false,
  ]);
  $response = curl_exec($ch);
  curl_close($ch);

  $response = json_decode($response, false);
  $thumb = $response->blob;
}

// ポスト投稿
$args = [
  "repo" => $did,
  "collection" => "app.bsky.feed.post",
  "record" => [
      '$type' => "app.bsky.feed.post",
      "text" => "リンクカードのテストだよ",
      "createdAt" => (new \DateTime())->format("c"),
      "langs" => ["ja"],
      "embed" => [
        '$type' => 'app.bsky.embed.external',
        "external" => [
          "uri" => $uri,  // リンク先
          "title" => $title,
          "description" => $description,
          "thumb" => $thumb,  // 画像の情報
        ]
      ]
  ],
];

$headers = [
  'Content-Type: application/json',
  'Authorization: Bearer ' . $accessJwt,
];

$ch = curl_init();
curl_setopt_array($ch, [
  CURLOPT_URL => 'https://bsky.social/xrpc/com.atproto.repo.createRecord',
  CURLOPT_HTTPHEADER => $headers,
  CURLOPT_POST => true,
  CURLOPT_POSTFIELDS => json_encode($args),
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_SSL_VERIFYPEER => false,
]);
$response = curl_exec($ch);
curl_close($ch);

ポストの前に「OGPの取得」「画像のアップロード」が加わるだけで、それ以外の流れに変更はありませんね。

成功すれば、画像付きのリンクカードが投稿されています。
画像が不要な場合は「thumb」のパラメータを外せば良いだけです。

リンク先が404だったり、画像の取得ができなかったりした場合などの対応は必要ですが、基本的な投稿に関する動きはこれで十分そうですね。