This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

first working version

here is the first working version of the bot

+144
+81
index.ts
··· 1 + import { BskyAgent } from "@atproto/api"; 2 + import * as dotenv from "dotenv"; // Added dotenv import 3 + import { CronJob } from "cron"; 4 + import * as process from "process"; 5 + import { generateWolfNoiseString } from "./wolf-noise-generator"; // Import the function 6 + 7 + // Load environment variables from the config.env file 8 + dotenv.config({ path: "./config.env" }); 9 + 10 + // Create a Bluesky Agent 11 + const agent = new BskyAgent({ 12 + service: "https://bsky.social", 13 + }); 14 + 15 + async function main() { 16 + // Check for empty environment variables and abort if needed 17 + if (!process.env.BLUESKY_USERNAME || !process.env.BLUESKY_PASSWORD) { 18 + console.error( 19 + "Missing required environment variables: BLUESKY_USERNAME and BLUESKY_PASSWORD. Aborting script." 20 + ); 21 + return; // Exit the function if variables are empty 22 + } 23 + 24 + try { 25 + await agent.login({ 26 + identifier: process.env.BLUESKY_USERNAME!, 27 + password: process.env.BLUESKY_PASSWORD!, 28 + }); 29 + 30 + // Generate a random wolf noise string 31 + let randomNoise; 32 + do { 33 + randomNoise = generateWolfNoiseString(); 34 + } while (randomNoise.trim().length === 0); // Loop until a non-empty string is generated 35 + 36 + if (randomNoise) { 37 + await agent.post({ 38 + text: randomNoise.trim(), // Use the generated string (trimmed) 39 + langs: ["en-US"], 40 + createdAt: new Date().toISOString(), 41 + }); 42 + console.log("Just posted:", randomNoise.trim()); 43 + } else { 44 + console.log("Failed to generate a valid wolf noise string after multiple attempts."); 45 + } 46 + } catch (error) { 47 + console.error("Error during posting:", error); 48 + // You can optionally implement retry logic or notify someone here 49 + } 50 + } 51 + 52 + main(); 53 + 54 + // Function to generate a random delay within 1-3 hours (in seconds) 55 + function getRandomDelay() { 56 + const minHours = 1; // Minimum hours for delay 57 + const maxHours = 3; // Maximum hours for delay 58 + 59 + // Convert hours to seconds 60 + const minDelaySeconds = minHours * 60 * 60; 61 + const maxDelaySeconds = maxHours * 60 * 60; 62 + 63 + // Generate a random number within the desired range (inclusive) 64 + const randomDelay = 65 + Math.floor(Math.random() * (maxDelaySeconds - minDelaySeconds + 1)) + 66 + minDelaySeconds; 67 + 68 + return randomDelay; 69 + } 70 + 71 + // Run this on a cron job 72 + const scheduleExpression = "0 * * * *"; // Every hour (used as a base for randomization) 73 + 74 + const job = new CronJob(scheduleExpression, async () => { 75 + const delay = getRandomDelay(); 76 + console.log(`Waiting for ${delay / 3600} hours before running main...`); 77 + await new Promise((resolve) => setTimeout(resolve, delay * 1000)); // Wait for the random delay 78 + main(); 79 + }); 80 + 81 + job.start();
+53
wolf-noise-generator.ts
··· 1 + import * as fs from "fs"; // File system module 2 + 3 + // Function to getRandomInt 4 + function getRandomInt(min: number, max: number): number { 5 + return Math.floor(Math.random() * (max - min + 1)) + min; 6 + } 7 + 8 + // Function to read the JSON data 9 + function getWolfNoises(): { 10 + howl: string[]; 11 + playful: string[]; 12 + scared: string[]; 13 + punctuation: { [category: string]: string[]; }; // Nested object for category-specific punctuation 14 + } { 15 + try { 16 + const data = fs.readFileSync("./wolf-noises.json", "utf-8"); 17 + return JSON.parse(data); 18 + } catch (error) { 19 + console.error("Error reading wolf-noises.json:", error); 20 + throw error; // Re-throw the error for handling 21 + } 22 + } 23 + 24 + export function generateWolfNoiseString(): string { 25 + const wolfNoises = getWolfNoises(); // Read JSON data 26 + const category = getRandomInt(0, Object.keys(wolfNoises).length - 1); // Pick a random category key 27 + const randomWords = wolfNoises[Object.keys(wolfNoises)[category]]; // Get words for that category 28 + 29 + let result = ""; 30 + let currentSentenceLength = 0; 31 + 32 + const maxLength = 280; // Set maximum length for the generated string 33 + 34 + while (result.length < maxLength) { 35 + const randomWord = randomWords[getRandomInt(0, randomWords.length - 1)]; 36 + const wordLength = randomWord.length; 37 + 38 + // Check if adding the word exceeds the maximum length 39 + if (result.length + wordLength <= maxLength) { 40 + // Add a space if it's not the first word and result is not empty 41 + if (result.length > 0) { 42 + result += " "; 43 + } 44 + result += randomWord; 45 + currentSentenceLength += wordLength; 46 + } else { 47 + // Break the loop if adding the word would exceed the maximum length 48 + break; 49 + } 50 + } 51 + 52 + return result.trim(); // Remove any leading/trailing whitespace 53 + }
+10
wolf-noises.json
··· 1 + { 2 + "howl": ["awoo", "awoooooo", "awooooooooooo"], 3 + "playful": ["yip", "yap", "arf", "bark"], 4 + "scared": ["whine", "whimper", "eep", "sniff"], 5 + "punctuation": { 6 + "howl": [".", "!"], 7 + "playful": [".", "?"], 8 + "scared": [".", "?"] 9 + } 10 + }