วิธีที่ผมใช้ตั้งเวลาโพสต์ Bluesky โดยไม่ต้องใช้ SaaS
ผมตั้งเวลาโพสต์ Bluesky วันละ 3 โพสต์ โดยใช้ GitHub Actions และไฟล์ JSONL ผมไม่ได้ใช้บริการตั้งเวลาภายนอกเลย
ระบบนี้ทำงานโดยใช้ไฟล์เพียงไฟล์เดียวคือ: content/bluesky-queue.jsonl
แต่ละบรรทัดในไฟล์นี้คือ JSON object
- บรรทัดที่ยังไม่ได้โพสต์จะมีเพียงข้อความเท่านั้น
- บรรทัดที่โพสต์แล้วจะมี timestamp และ post URI รวมอยู่ด้วย
สคริปต์จะอ่านไฟล์จากบนลงล่าง โดยจะหาบรรทัดแรกที่ไม่มี timestamp แล้วทำการโพสต์ จากนั้นจึงอัปเดตบรรทัดนั้น
ทำไมผมถึงใช้ JSONL แทนที่จะใช้ฐานข้อมูล:
- ง่ายต่อการติดตามการเปลี่ยนแปลงใน Git
- งาน CI ใดๆ ก็สามารถเพิ่มบรรทัดใหม่ต่อท้ายไฟล์ได้
- ช่วยให้การตั้งค่าเรียบง่ายและไม่มีค่าใช้จ่าย
การจัดการข้อกำหนดของ Bluesky API
Bluesky ต้องการ "facets" สำหรับลิงก์และแฮชแท็ก คุณไม่สามารถส่งแค่ข้อความไปเฉยๆ ได้ แต่ต้องระบุตำแหน่งไบต์ (byte positions) ที่แน่นอนสำหรับองค์ประกอบเหล่านี้
ผมใช้สคริปต์ในการคำนวณตำแหน่งเหล่านี้ โดยใช้ TextEncoder เพื่อหาค่า UTF-8 byte offsets วิธีนี้จะช่วยป้องกันข้อผิดพลาดเมื่อมีการใช้ emoji เพราะจำนวนตัวอักษรและจำนวนไบต์นั้นไม่เท่ากัน
การเพิ่มประสิทธิภาพ GitHub Actions
GitHub Actions มักจะทำงานล่าช้าหากคุณตั้งเวลาทำงานไว้ที่ต้นชั่วโมงพอดี เพื่อแก้ปัญหานี้ ผมจึงใช้การตั้งเวลาแบบเลี่ยงนาที (off-minute offset) แทนที่จะเป็น 00:00 ผมจะใช้ 23:37 แทน ซึ่งช่วยลดความล่าช้าได้
นอกจากนี้ ผมยังเพิ่มการหน่วงเวลาแบบสุ่มระหว่าง 0 ถึง 5 นาทีก่อนการโพสต์ เพื่อให้รูปแบบการโพสต์ดูเหมือนมนุษย์มากขึ้น และหลีกเลี่ยงการใช้เวลาที่แม่นยำแบบเครื่องจักร ซึ่งอัลกอริทึมบางตัวอาจจะลดความสำคัญลง
การป้องกันการเกิด Infinite Loops
เมื่อสคริปต์อัปเดตคิว มันจะทำการ commit การเปลี่ยนแปลงกลับไปยัง repository ซึ่งอาจไปกระตุ้นให้ workflow ทำงานซ้ำอีกครั้ง
ผมแก้ปัญหานี้ด้วยการใช้ commit message guard:
- สคริปต์จะเพิ่ม
[skip bluesky-queue]ลงใน commit message - workflow จะตรวจสอบหาแท็กนี้
- หากพบแท็กนี้ workflow ก็จะไม่ทำงาน
ระบบนี้เป็นส่วนหนึ่งของการทดลองระยะยาวกับเว็บไซต์ที่คัดสรรเนื้อหาโดย AI มันมีความคล่องตัว (lean) ราคาถูก และเชื่อถือได้
