Welcome to My Tech Blog - Software Engineering & Cybersecurity

Welcome to my digital homestead, a cozy nook nestled in the vast expanse of the internet. Here, you'll find a curated collection of my recent endeavors, ongoing projects, and various musings. This space serves as both a showcase of my professional journey and a window into my personal interests. Feel free to explore and discover what I've been tinkering with, learning about, and creating in my corner of the digital world.

Add follow-up reply to Bluesky announcements After posting a discovery screensh...

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...

πŸ€– Meet 'nerdbot' - My Personal Robot Project

Introducing 'nerdbot', my ongoing personal robotics project! This little autonomous companion combines computer vision, AI, and mechanical engineering into one adorable package. Built with Python, OpenCV, and a healthy dose of engineering curiosity. Watch as it navigates, learns, and brings a bit of robotic personality to everyday life.
Read more...

πŸ¦‹ Now Cross-posting to Bluesky with AT Protocol

Automated my blog to cross-post new articles to Bluesky using the AT Protocol SDK. Features smart duplicate detection with self-labels, rich link previews, and clean post formatting. No more manual posting - the future of decentralized social media integration is here!