Posting to Bluesky via the API from PHP – Part Seven – Handling Multiple Images

It really is very gratifying when people use your code in their own projects and get in touch to ask questions, suggest changes or, heaven forbid, highlight bugs! Yesterday, someone raised an issue asking if it was possible to upload four images to a post. Let’s take a look and see…

Who Wants Multiple Images Anyway?

To be honest, when I wrote PHP2Bluesky it was very much for my own project and that only required one image per post. However, Bluesky allows up to four images to be uploaded per post and so I can understand why others would want this.

When I looked at uploading images previously I built an array that contained a single images element within the embed element. This array is passed to BlueSky to tell it what images you want associated with your post. It looks something like this when printed out.

Array
(
     => Array
        (
            [$type] => app.bsky.embed.images
            [images] => Array
                (
                    [0] => Array
                        (
                            [alt] =>
                            [image] => stdClass Object
                                (
                                    [$type] => blob
                                    [ref] => stdClass Object
                                        (
                                            [$link] => bafkreiesp7r2r6cxm4srwimjdaf4x2yybodspu35gmadon4
                                        )

                                    [mimeType] => image/jpeg
                                    [size] => 825655
                                )

                        )

                )

        )

)

According to the official documentation on image embeds to send multiple images you need to:

  1. upload each of the images separately and keep the returned details
  2. build the arguments with a separate images element wrapped within the embed element
  3. post as normal.

Building the Arguments

Given that the post_to_bluesky function currently takes the filename to be uploaded as the second parameter I was keen not to change this. Therefore, to accept multiple images in addition to a single image we need to pass the details as an array.

Now the code detects if an array has been passed and if it has it cycles through it building the parameters required. If it is not an array then the string is handled as before.

        // add any media - will accept multiple images in an array or a single image as a string
        $embed = '';
        if (!empty($media)){
            if (is_array($media)){
                $k = 0;
                $mediaArray = array();
                while ($k < count($media) && $k < maxImageUpload){
                    array_push($mediaArray, [
                        'alt' => '',
                        'image' => $media[$k],
                        ]);
                    $k++;    
                }
            }else{
                $mediaArray = [
                    [
                    'alt' => '',
                    'image' => $media,
                    ]
                ];
            }
        
            $embed = [
                'embed' => [
                    '$type' => 'app.bsky.embed.images',
                    'images' => $mediaArray,
                ],
            ];
        }

A Call to Action

Now with the code able to handle up to four images let’s take a look at how that is done in a call. The code below uses a mixture of both local and remote images to show how the process works. You can see that we call upload_media_to_bluesky four times, one for each of the images, saving the result from each call. We then take these four responses and put them into an array before passing to post_to_bluesky.

    $handle = '<your handle>';
    $password = '<your password>';
    $filename1 = 'https://www.spokenlikeageek.com/wp-content/uploads/2023/10/IMG_5334.jpeg';
    $filename2 = '/Users/neilthompson/Downloads/2024-01-02 15-22-08.png';
    $filename3 = 'https://www.neilthompson.co.uk/wp-content/uploads/2023/12/2023-12-07-10.43.53.jpg';
    $filename4 = '/Users/neilthompson/Downloads/2024-01-02 15-21-15.png';
    $text = 'Hey look! four images!';

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

    // send multiple images with text
    $image1 = upload_media_to_bluesky($connection, $filename1);
    $image2 = upload_media_to_bluesky($connection, $filename2);
    $image3 = upload_media_to_bluesky($connection, $filename3);
    $image4 = upload_media_to_bluesky($connection, $filename4);
    $imageArray= array($image1, $image2, $image3, $image4);
    $response = post_to_bluesky($connection, $text, $imageArray);
    print_r($response);

And that’s all there is to it! If you want to send a single image use the example shown on the original post.

You can download the updated code on my Github page and if you spot any other improvements I can make let me know.

Leave a Reply

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