איך אני מתזמן פוסטים ב-Bluesky ללא SaaS
אני מתזמן שלושה פוסטים ב-Bluesky בכל יום באמצעות GitHub Actions וקובץ JSONL. אני לא משתמש בשירות תזמון חיצוני.
המערכת עובדת באמצעות קובץ יחיד: content/bluesky-queue.jsonl.
כל שורה בקובץ זה היא אובייקט JSON.
- שורות שטרם פורסמו מכילות טקסט בלבד.
- שורות שכבר פורסמו כוללות חותמת זמן (timestamp) ו-URI של הפוסט.
הסקריפט קורא את הקובץ מלמעלה למטה. הוא מוצא את השורה הראשונה ללא חותמת זמן, מפרסם אותה, ואז מעדכן את השורה הזו.
למה אני משתמש ב-JSONL במקום במסד נתונים:
- קל לעקוב אחר שינויים ב-Git.
- כל משימת CI יכולה להוסיף שורה חדשה לקובץ.
- זה שומר על ההגדרה פשוטה ובחינם.
טיפול בדרישות ה-API של Bluesky
Bluesky דורשת "facets" עבור קישורים והאשטאגים. אי אפשר פשוט לשלוח טקסט. עליך לספק את מיקומי הבתים (byte positions) המדויקים עבור האלמנטים הללו.
אני משתמש בסקריפט כדי לחשב את המיקומים הללו. אני משתמש ב-TextEncoder כדי לקבל את ה-offsets בבתים בפורמט UTF-8. זה מונע שגיאות בשימוש באימוג'ים. תווים ובתים אינם אותו דבר.
אופטימיזציה של GitHub Actions
GitHub Actions לעיתים קרובות רץ באיחור אם מתזמנים משימות בתחילת השעה. כדי לפתור זאת, אני משתמש בסטייה (offset) של דקות. במקום 00:00, אני משתמש ב-23:37. זה מפחית עיכובים.
אני גם מוסיף עיכוב אקראי של בין 0 ל-5 דקות לפני הפרסום. זה גורם לדפוס הפרסום להיראות אנושי יותר. זה מונע תזמון מכני מדויק שאלגוריתמים מסוימים נוטים להוריד לו את החשיבות.
מניעת לולאות אינסופיות
כאשר הסקריפט מעדכן את התור, הוא מבצע commit של השינוי חזרה למאגר (repository). זה עלול להפעיל את ה-workflow שוב.
אני פותר זאת באמצעות הגנה בהודעת ה-commit:
- הסקריפט מוסיף
[skip bluesky-queue]להודעת ה-commit. - ה-workflow בודק אם התגית הזו קיימת.
- אם התגית קיימת, ה-workflow לא ירוץ.
המערכת הזו היא חלק מניסוי ארוך טווח עם אתרים המנוהלים על ידי AI. היא נשארת רזה, זולה ואמינה.
