Posting to Bluesky via the API from PHP – Part Two – Images

In the first of these posts we looked at creating the connection to the Bluesky API and posting a text post. In this second post we are going to extend that out to post images as well as text.

The code posted here are snippets from a larger library of functions that you can drop in and use to post to Bluesky. If some parts look more complex than they need to all will be revealed in the final version.

Uploading Images

In order to post an image to Bluesky you have to take a few steps:

  1. open and ingest the file
  2. get the mime type of the file
  3. upload the file to the Bluesky server
  4. get the image blob from the response
  5. build the parameters and send to Bluesky

The following function carries out the first three points on the above. The filename passed needs to be either a full path name to a local file or the URL to a file. The connection passed in comes from bluesky_connect function from the previous post.

function upload_media_to_bluesky($connection, $filename)
{
    
    // upload the file
    $body = file_get_contents($filename);
    $mime = mime_content_type($filename);

    $response = $connection->request('POST', 'com.atproto.repo.uploadBlob', [], $body, $mime);
    $image = $response->blob;

    return $image;

  }

Build the Parameters

Next we take the response from the above and put that into the parameter array as shown below:

      $embed = [
        'embed' => [
          '$type' => 'app.bsky.embed.images',
          'images' => [
            [
              'alt' => '',
              'image' => $image,
            ],
          ],
        ],
      ];

This then needs to be merged with the parameters that we created for sending text to Bluesky in the previous post. For this we use the array_merge function to slot the image parameters into the correct place in the whole parameter array. Once that’s done we can post.

$args['record'] = array_merge($args['record'], $embed);

// send to bluesky
$connection->request('POST', 'com.atproto.repo.createRecord', $args);

Putting it all Together

Taking all of the above and the previous post together that gives us the following:

    $password = '<your API password>';
    $handle = '<your Bluesky handle>';
    $filename = '<full path to image to be uploaded>';

    // connect to Bluesky API
    $connection = bluesky_connect($handle, $password);

    // build the arguments
    $args = [
      'collection' => 'app.bsky.feed.post',
      'repo' => $connection->getAccountDid(),
      'record' => [
        'text' => 'Hello World!',
        'langs' => ['en'],
        'createdAt' => date('c'),
        '$type' => 'app.bsky.feed.post',
      ],
    ];

    $image = $this->Bluesky_model->upload_media_to_bluesky($connection, $filename);

    $embed = [
       'embed' => [
         '$type' => 'app.bsky.embed.images',
         'images' => [
           [
             'alt' => '',
             'image' => $image,
           ],
         ],
       ],
     ];

    $args['record'] = array_merge($args['record'], $embed);

    // send to bluesky
    $connection->request('POST', 'com.atproto.repo.createRecord', $args);

In the next post we look at how to activate links in your Bluesky posts via the API.

Leave a Reply

Your email address will not be published. Required fields are marked *