Created
July 27, 2025 00:46
-
-
Save sriganesh/cdb08435125278ad5b7c1f76f26c3e2d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import json | |
import time | |
import random | |
import requests | |
from PIL import Image | |
from io import BytesIO | |
BASE32_ALPHABET = "234567abcdefghijklmnopqrstuvwxyz" | |
def generate_tid(): | |
timestamp_us = int(time.time() * 1_000_000) | |
clock_id = random.randint(0, 1023) | |
tid_int = (timestamp_us << 10) | clock_id | |
result = [] | |
for _ in range(13): | |
result.append(BASE32_ALPHABET[tid_int & 0x1f]) | |
tid_int >>= 5 | |
return ''.join(reversed(result)) | |
def main(): | |
# Update these values | |
HANDLE = "sriganesh.bsky.social" #handle | |
PASSWORD = "abcd-efgh-ijkl-mnop" #app password | |
IMAGE_PATH = "img/spidermanblob.jpg" #change to your image | |
print("Starting...") | |
print(f"Handle: {HANDLE}") | |
# Login | |
print("\nLogging in...") | |
session_url = "https://bsky.social/xrpc/com.atproto.server.createSession" | |
login_response = requests.post(session_url, json={ | |
"identifier": HANDLE, | |
"password": PASSWORD | |
}) | |
if login_response.status_code != 200: | |
print(f"Login failed: {login_response.text}") | |
return | |
auth = login_response.json() | |
token = auth["accessJwt"] | |
did = auth["did"] | |
print(f"Logged in!") | |
print(f"DID: {did}") | |
# Upload image | |
print(f"\nProcessing image: {IMAGE_PATH}") | |
with Image.open(IMAGE_PATH) as img: | |
print(f"Original size: {img.size}") | |
print(f"Format: {img.format}") | |
if img.mode != 'RGB': | |
img = img.convert('RGB') | |
img.thumbnail((800, 800), Image.Resampling.LANCZOS) | |
print(f"Resized image: {img.size}") | |
output = BytesIO() | |
img.save(output, format='JPEG', quality=85) | |
image_data = output.getvalue() | |
print(f"Final size: {len(image_data):,}") | |
print("\nUploading image to PDS...") | |
upload_response = requests.post( | |
"https://bsky.social/xrpc/com.atproto.repo.uploadBlob", | |
headers={ | |
"Authorization": f"Bearer {token}", | |
"Content-Type": "image/jpeg" | |
}, | |
data=image_data | |
) | |
if upload_response.status_code != 200: | |
print(f"Upload failed: {upload_response.text}") | |
return | |
blob = upload_response.json()["blob"] | |
print(f"Image uploaded!") | |
print(f"Blob: {blob['ref']['$link']}") | |
print(f"Size: {blob['size']:,}") | |
# Create self-referential post | |
print("\nGenerating TID...") | |
tid = generate_tid() | |
print(f"TID: {tid}") | |
post_url = f"https://bsky.app/profile/{HANDLE}/post/{tid}" | |
print(f"Post URL: {post_url}") | |
post_text = f"""This is a self-referential post. | |
It contains its own record key ({tid}) | |
It links to itself: | |
{post_url} | |
#atprotoing""" | |
# Calculate byte positions for the link | |
post_bytes = post_text.encode('utf-8') | |
url_start = post_bytes.find(post_url.encode('utf-8')) | |
url_end = url_start + len(post_url.encode('utf-8')) | |
record = { | |
"$type": "app.bsky.feed.post", | |
"text": post_text, | |
"createdAt": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()), | |
"embed": { | |
"$type": "app.bsky.embed.external", | |
"external": { | |
"uri": "https://media.tenor.com/QXVs4QWLlzkAAAAC/spider-man.gif?hh=354&ww=498", | |
"thumb": blob, | |
"title": "Spider-Man pointing at Spider-Man", | |
"description": "ALT: Two Spider-Men pointing at each other (self-referential post!)" | |
} | |
}, | |
"facets": [{ | |
"index": {"byteStart": url_start, "byteEnd": url_end}, | |
"features": [{"$type": "app.bsky.richtext.facet#link", "uri": post_url}] | |
}] | |
} | |
print("\nCreating post...") | |
post_response = requests.post( | |
"https://bsky.social/xrpc/com.atproto.repo.createRecord", | |
headers={ | |
"Authorization": f"Bearer {token}", | |
"Content-Type": "application/json" | |
}, | |
json={ | |
"repo": did, | |
"collection": "app.bsky.feed.post", | |
"rkey": tid, | |
"record": record | |
} | |
) | |
if post_response.status_code == 200: | |
print(f"\nSuccess!!!") | |
print(f"TID: {tid}") | |
print(f"Posted at: {post_url}") | |
else: | |
print(f"\nFailed to create post: {post_response.text}") | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment