Skip to content

Instantly share code, notes, and snippets.

@cchana
Last active December 4, 2024 19:00
Show Gist options
  • Save cchana/0317b97aba7e757a7e3ea1598a38cb2b to your computer and use it in GitHub Desktop.
Save cchana/0317b97aba7e757a7e3ea1598a38cb2b to your computer and use it in GitHub Desktop.
A brief script that will log you into Bluesky and post 'Hello, world!'. It saves the session info to bsky.tokens so you can continue to post
<?php
# Login info, set an app password at https://bsky.app/settings/app-passwords
$password = 'p4ssw0rd';
$handle = 'your.handle';
# URL and data for creating a session
$apiKeyUrl ='https://bsky.social/xrpc/com.atproto.server.createSession';
$apiKeyPostData='{"identifier": "'.$handle.'", "password": "'.$password.'" }';
# If the details have been saved, used them
if (file_exists('bsky.tokens')) {
$apiData = json_decode(file_get_contents('bsky.tokens'), true);
# Else, fetch and set the data
} else {
# cURL to login
$ch = curl_init();
$allHeaders = array();
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $apiKeyPostData);
curl_setopt($ch, CURLOPT_URL, $apiKeyUrl);
$apiData = json_decode(curl_exec($ch), true);
curl_close($ch);
# Store the token content so we don't have to keep logging in
file_put_contents('bsky.tokens', $apiData);
}
# Store the DID and JWT
$did = $apiData['did'];
$key = $apiData['accessJwt'];
# Created at date
$date = date('Y-m-d\TH:i:s.Z\Z');
# URL and data for creating a post
$feedPostUrl='https://bsky.social/xrpc/com.atproto.repo.createRecord';
$feedPostData='{"collection":"app.bsky.feed.post", "repo":"'.$did.'", "record":{"text":"Hello, world!", "createdAt":"'.$date.'", "type":"app.bsky.feed.post"}}';
# cURL to post
$ch = curl_init();
$allHeaders = array();
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json', 'Authorization: Bearer '.$key));
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $feedPostData);
curl_setopt($ch, CURLOPT_URL, $feedPostUrl);
$postData = json_decode(curl_exec($ch), true);
curl_close($ch);
# If it was posted OK
if ($postData['validationStatus'] == 'valid') {
$postIdParts = explode('/', $postData['uri']);
$postId = end($postIdParts);
# Display a link to the post
echo '<a href="https://bsky.app/profile/'.$handle.'/post/'.$postId.'">View post on Bluesky</a>';
}
@cchana
Copy link
Author

cchana commented Dec 4, 2024

Sorry, not something I can do right now but if I get time to upload a new gist for image uploads I will. To help get you started, the postData would just be the contents of the image file sent to the end point I shared before. You'll get a response with details of the face that you can then add to the next API call when you're making your pots.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment