2026-02-15 23:28:29
File: backend/atproto_client.py
import logging
from typing import Optional
-from atproto import Client
+from atproto import Client, models
from atproto.exceptions import AtProtocolError
from backend.config import AtprotoConfig
def announce_host(self, host: dict, screenshot_path: Optional[str] = None, proto
with open(screenshot_path, "rb") as f:
image_data = f.read()
- self.client.send_image(
+ post_ref = self.client.send_image(
text=text,
image=image_data,
image_alt=f"{proto} login screen",
)
logger.info(f"Announced {proto} host to Bluesky with screenshot")
+
+ # Post follow-up reply if configured
+ if self.config.follow_up_template and post_ref:
+ self._send_follow_up(post_ref, proto)
+
return True
except AtProtocolError as e:
logger.error(f"Failed to post to Bluesky: {e}")
return False
except Exception as e:
logger.error(f"Unexpected error posting to Bluesky: {e}")
return False
+
+ def _send_follow_up(self, parent_ref, proto: str) -> None:
+ """Post a follow-up reply to an announcement."""
+ try:
+ owner = self.config.owner_username.strip()
+ text = self.config.follow_up_template.format(
+ owner_username=f"@{owner}" if owner else "",
+ proto=proto,
+ )
+ if len(text) > 300:
+ text = text[:297] + "..."
+
+ strong_ref = models.ComAtprotoRepoStrongRef.Main(
+ uri=parent_ref.uri,
+ cid=parent_ref.cid,
+ )
+ reply_ref = models.AppBskyFeedPost.ReplyRef(
+ root=strong_ref,
+ parent=strong_ref,
+ )
+ self.client.send_post(text=text, reply_to=reply_ref)
+ logger.info("Posted follow-up reply to announcement")
+ except Exception as e:
+ logger.error(f"Failed to post follow-up reply: {e}")
File: backend/config.py
class AtprotoConfig:
service_url: str = "https://bsky.social"
username: str = ""
app_password: str = ""
+ owner_username: str = ""
post_template: str = "Jackpot! Found an open {proto} host{hostname_suffix}\n{asn}\n{ip_type}"
+ follow_up_template: str = ""
@dataclass
File: config.example.toml
enabled = false
service_url = "https://bsky.social"
username = ""
app_password = ""
+owner_username = ""
post_template = "Jackpot! Found an open {proto} host{hostname_suffix}\n{asn}\n{ip_type}"
+follow_up_template = "If you are the owner, you may contact {owner_username} to claim your prize!"
Read more...