···9STAR_THRESHOLD=1
1011# Timeframe in hours to gate posts after a threshold is met (default 24)
12-POST_WINDOW_HOURS=24000
···9STAR_THRESHOLD=1
1011# Timeframe in hours to gate posts after a threshold is met (default 24)
12+POST_WINDOW_HOURS=24
13+14+DATABASE_URL=./stitch_counter.sqlite
15+JETSTREAM_URL="wss://jetstream1.us-east.fire.hose.cam/subscribe"
+52-37
bot/src/main.rs
···6use atrium_api::types::{Collection, Union};
7use dotenv::dotenv;
8use logic::BotApi;
09use rocketman::{
10 connection::JetstreamConnection, handler, ingestion::LexiconIngestor,
11 options::JetstreamOptions, types::event::Operation,
···71 // Run migrations from ./migrations
72 sqlx::migrate!("./migrations").run(&pool).await?;
73000074 // Configure Jetstream to listen to sh.tangled.feed.star
75 let opts = JetstreamOptions::builder()
076 .wanted_collections(vec![atproto_api::sh::tangled::feed::Star::NSID.to_string()])
77 .build();
78···235236 let parsed = parse_uri(&repo_subject)?;
237 let cloned_repo_owner = parsed.did.clone();
238- let stars = fetch_constellation_count(&repo_subject).await?;
00000239 let repo_record = &self
240 .sling_shot
241 .get_record::<atproto_api::sh::tangled::repo::RecordData>(
···269 "https://tangled-search.bigmoves.deno.net/repo-image/{}",
270 encoded_subject
271 );
272- let bytes = reqwest::get(url).await?.bytes().await?.to_vec();
273-274- let blob_upload = &self
275- .bot
276- .agent
277- .api
278- .com
279- .atproto
280- .repo
281- .upload_blob(bytes)
282- .await?;
283284- // let rt = RichText::new_with_detect_facets(format!(
285- // "{handle_and_repo}{description}\n⭐️ {stars} {tangled_sh_url}"
286- // ))
287- // .await?;
288 let post_text =
289 format!("{handle_and_repo}{description}\n⭐️ {stars}");
290291- let image = atrium_api::app::bsky::embed::images::ImageData {
292- alt: format!(
293- "An image showing the same text inside of the post. {post_text}"
294- ),
295- aspect_ratio: Some(
296- atrium_api::app::bsky::embed::defs::AspectRatioData {
297- height: NonZeroU64::try_from(400_u64)?,
298- width: NonZeroU64::try_from(800_u64)?,
299- }
300- .into(),
301- ),
302- //Good lord how many clones is that
303- image: blob_upload.clone().blob.clone(),
00000000000000000000000000304 };
305- let embed = Some(atrium_api::types::Union::Refs(
306- RecordEmbedRefs::AppBskyEmbedImagesMain(Box::new(
307- atrium_api::app::bsky::embed::images::MainData {
308- images: vec![image.into()],
309- }
310- .into(),
311- )),
312- ));
313314 let post = atrium_api::app::bsky::feed::post::RecordData {
315 created_at: atrium_api::types::string::Datetime::now(),
···6use atrium_api::types::{Collection, Union};
7use dotenv::dotenv;
8use logic::BotApi;
9+use rocketman::endpoints::JetstreamEndpoints;
10use rocketman::{
11 connection::JetstreamConnection, handler, ingestion::LexiconIngestor,
12 options::JetstreamOptions, types::event::Operation,
···72 // Run migrations from ./migrations
73 sqlx::migrate!("./migrations").run(&pool).await?;
7475+ let jet_stream = match std::env::var("JETSTREAM_URL") {
76+ Ok(url) => JetstreamEndpoints::Custom(url.into()),
77+ Err(_) => JetstreamEndpoints::default(),
78+ };
79 // Configure Jetstream to listen to sh.tangled.feed.star
80 let opts = JetstreamOptions::builder()
81+ .ws_url(jet_stream)
82 .wanted_collections(vec![atproto_api::sh::tangled::feed::Star::NSID.to_string()])
83 .build();
84···241242 let parsed = parse_uri(&repo_subject)?;
243 let cloned_repo_owner = parsed.did.clone();
244+ let stars = fetch_constellation_count(&repo_subject)
245+ .await
246+ .unwrap_or_else(|err| {
247+ log::error!("Error calling constellation: {:?}", err);
248+ 0
249+ });
250 let repo_record = &self
251 .sling_shot
252 .get_record::<atproto_api::sh::tangled::repo::RecordData>(
···280 "https://tangled-search.bigmoves.deno.net/repo-image/{}",
281 encoded_subject
282 );
283+ log::info!("Attempting to get the picture at: {url}");
00000000002840000285 let post_text =
286 format!("{handle_and_repo}{description}\n⭐️ {stars}");
287288+ let response = reqwest::get(url).await?;
289+290+ let embed = match response.status().is_success() {
291+ true => {
292+ let bytes = response.bytes().await?.to_vec();
293+ let blob_upload = &self
294+ .bot
295+ .agent
296+ .api
297+ .com
298+ .atproto
299+ .repo
300+ .upload_blob(bytes)
301+ .await?;
302+303+ let image = atrium_api::app::bsky::embed::images::ImageData {
304+ alt: format!(
305+ "An image showing the same text inside of the post. {post_text}"
306+ ),
307+ aspect_ratio: Some(
308+ atrium_api::app::bsky::embed::defs::AspectRatioData {
309+ height: NonZeroU64::try_from(400_u64)?,
310+ width: NonZeroU64::try_from(800_u64)?,
311+ }
312+ .into(),
313+ ),
314+ //Good lord how many clones is that
315+ image: blob_upload.clone().blob.clone(),
316+ };
317+ Some(atrium_api::types::Union::Refs(
318+ RecordEmbedRefs::AppBskyEmbedImagesMain(Box::new(
319+ atrium_api::app::bsky::embed::images::MainData {
320+ images: vec![image.into()],
321+ }
322+ .into(),
323+ )),
324+ ))
325+ }
326+ false => None,
327 };
00000000328329 let post = atrium_api::app::bsky::feed::post::RecordData {
330 created_at: atrium_api::types::string::Datetime::now(),