small bsky embedder @ boobsky.app - kinda mid but works - mirror of git.fomx.gay/rooot/embedthing

feat: resolve did:plc to fix embedding of non-bsky pds media

Signed-off-by: rooot <hey@rooot.gay>

+264 -5
+215 -1
Cargo.lock
··· 109 109 ] 110 110 111 111 [[package]] 112 + name = "atomic-waker" 113 + version = "1.1.2" 114 + source = "registry+https://github.com/rust-lang/crates.io-index" 115 + checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" 116 + 117 + [[package]] 112 118 name = "atrium-api" 113 119 version = "0.24.7" 114 120 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 256 262 checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 257 263 258 264 [[package]] 265 + name = "cfg_aliases" 266 + version = "0.2.1" 267 + source = "registry+https://github.com/rust-lang/crates.io-index" 268 + checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" 269 + 270 + [[package]] 259 271 name = "chrono" 260 272 version = "0.4.38" 261 273 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 418 430 "dotenvy", 419 431 "ipld-core", 420 432 "lazy_static", 433 + "reqwest", 421 434 "rocket", 422 435 "serde", 423 436 "serde_json", ··· 631 644 ] 632 645 633 646 [[package]] 647 + name = "h2" 648 + version = "0.4.6" 649 + source = "registry+https://github.com/rust-lang/crates.io-index" 650 + checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" 651 + dependencies = [ 652 + "atomic-waker", 653 + "bytes", 654 + "fnv", 655 + "futures-core", 656 + "futures-sink", 657 + "http 1.1.0", 658 + "indexmap", 659 + "slab", 660 + "tokio", 661 + "tokio-util", 662 + "tracing", 663 + ] 664 + 665 + [[package]] 634 666 name = "hashbrown" 635 667 version = "0.15.0" 636 668 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 726 758 "futures-channel", 727 759 "futures-core", 728 760 "futures-util", 729 - "h2", 761 + "h2 0.3.26", 730 762 "http 0.2.12", 731 763 "http-body 0.4.6", 732 764 "httparse", ··· 749 781 "bytes", 750 782 "futures-channel", 751 783 "futures-util", 784 + "h2 0.4.6", 752 785 "http 1.1.0", 753 786 "http-body 1.0.1", 754 787 "httparse", ··· 757 790 "smallvec", 758 791 "tokio", 759 792 "want", 793 + ] 794 + 795 + [[package]] 796 + name = "hyper-rustls" 797 + version = "0.27.3" 798 + source = "registry+https://github.com/rust-lang/crates.io-index" 799 + checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" 800 + dependencies = [ 801 + "futures-util", 802 + "http 1.1.0", 803 + "hyper 1.5.0", 804 + "hyper-util", 805 + "rustls", 806 + "rustls-pki-types", 807 + "tokio", 808 + "tokio-rustls", 809 + "tower-service", 810 + "webpki-roots", 760 811 ] 761 812 762 813 [[package]] ··· 1268 1319 checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac" 1269 1320 1270 1321 [[package]] 1322 + name = "quinn" 1323 + version = "0.11.5" 1324 + source = "registry+https://github.com/rust-lang/crates.io-index" 1325 + checksum = "8c7c5fdde3cdae7203427dc4f0a68fe0ed09833edc525a03456b153b79828684" 1326 + dependencies = [ 1327 + "bytes", 1328 + "pin-project-lite", 1329 + "quinn-proto", 1330 + "quinn-udp", 1331 + "rustc-hash", 1332 + "rustls", 1333 + "socket2", 1334 + "thiserror", 1335 + "tokio", 1336 + "tracing", 1337 + ] 1338 + 1339 + [[package]] 1340 + name = "quinn-proto" 1341 + version = "0.11.8" 1342 + source = "registry+https://github.com/rust-lang/crates.io-index" 1343 + checksum = "fadfaed2cd7f389d0161bb73eeb07b7b78f8691047a6f3e73caaeae55310a4a6" 1344 + dependencies = [ 1345 + "bytes", 1346 + "rand", 1347 + "ring", 1348 + "rustc-hash", 1349 + "rustls", 1350 + "slab", 1351 + "thiserror", 1352 + "tinyvec", 1353 + "tracing", 1354 + ] 1355 + 1356 + [[package]] 1357 + name = "quinn-udp" 1358 + version = "0.5.6" 1359 + source = "registry+https://github.com/rust-lang/crates.io-index" 1360 + checksum = "e346e016eacfff12233c243718197ca12f148c84e1e84268a896699b41c71780" 1361 + dependencies = [ 1362 + "cfg_aliases", 1363 + "libc", 1364 + "once_cell", 1365 + "socket2", 1366 + "tracing", 1367 + "windows-sys 0.52.0", 1368 + ] 1369 + 1370 + [[package]] 1271 1371 name = "quote" 1272 1372 version = "1.0.37" 1273 1373 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1388 1488 "async-compression", 1389 1489 "base64", 1390 1490 "bytes", 1491 + "encoding_rs", 1391 1492 "futures-core", 1392 1493 "futures-util", 1494 + "h2 0.4.6", 1393 1495 "http 1.1.0", 1394 1496 "http-body 1.0.1", 1395 1497 "http-body-util", 1396 1498 "hyper 1.5.0", 1499 + "hyper-rustls", 1397 1500 "hyper-tls", 1398 1501 "hyper-util", 1399 1502 "ipnet", ··· 1404 1507 "once_cell", 1405 1508 "percent-encoding", 1406 1509 "pin-project-lite", 1510 + "quinn", 1511 + "rustls", 1407 1512 "rustls-pemfile", 1513 + "rustls-pki-types", 1408 1514 "serde", 1409 1515 "serde_json", 1410 1516 "serde_urlencoded", 1411 1517 "sync_wrapper", 1518 + "system-configuration", 1412 1519 "tokio", 1413 1520 "tokio-native-tls", 1521 + "tokio-rustls", 1414 1522 "tokio-util", 1415 1523 "tower-service", 1416 1524 "url", 1417 1525 "wasm-bindgen", 1418 1526 "wasm-bindgen-futures", 1419 1527 "web-sys", 1528 + "webpki-roots", 1420 1529 "windows-registry", 1530 + ] 1531 + 1532 + [[package]] 1533 + name = "ring" 1534 + version = "0.17.8" 1535 + source = "registry+https://github.com/rust-lang/crates.io-index" 1536 + checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" 1537 + dependencies = [ 1538 + "cc", 1539 + "cfg-if", 1540 + "getrandom", 1541 + "libc", 1542 + "spin", 1543 + "untrusted", 1544 + "windows-sys 0.52.0", 1421 1545 ] 1422 1546 1423 1547 [[package]] ··· 1508 1632 checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" 1509 1633 1510 1634 [[package]] 1635 + name = "rustc-hash" 1636 + version = "2.0.0" 1637 + source = "registry+https://github.com/rust-lang/crates.io-index" 1638 + checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" 1639 + 1640 + [[package]] 1511 1641 name = "rustix" 1512 1642 version = "0.38.38" 1513 1643 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1521 1651 ] 1522 1652 1523 1653 [[package]] 1654 + name = "rustls" 1655 + version = "0.23.16" 1656 + source = "registry+https://github.com/rust-lang/crates.io-index" 1657 + checksum = "eee87ff5d9b36712a58574e12e9f0ea80f915a5b0ac518d322b24a465617925e" 1658 + dependencies = [ 1659 + "once_cell", 1660 + "ring", 1661 + "rustls-pki-types", 1662 + "rustls-webpki", 1663 + "subtle", 1664 + "zeroize", 1665 + ] 1666 + 1667 + [[package]] 1524 1668 name = "rustls-pemfile" 1525 1669 version = "2.2.0" 1526 1670 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1534 1678 version = "1.10.0" 1535 1679 source = "registry+https://github.com/rust-lang/crates.io-index" 1536 1680 checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" 1681 + 1682 + [[package]] 1683 + name = "rustls-webpki" 1684 + version = "0.102.8" 1685 + source = "registry+https://github.com/rust-lang/crates.io-index" 1686 + checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" 1687 + dependencies = [ 1688 + "ring", 1689 + "rustls-pki-types", 1690 + "untrusted", 1691 + ] 1537 1692 1538 1693 [[package]] 1539 1694 name = "rustversion" ··· 1740 1895 ] 1741 1896 1742 1897 [[package]] 1898 + name = "subtle" 1899 + version = "2.6.1" 1900 + source = "registry+https://github.com/rust-lang/crates.io-index" 1901 + checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" 1902 + 1903 + [[package]] 1743 1904 name = "syn" 1744 1905 version = "1.0.109" 1745 1906 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1768 1929 checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" 1769 1930 dependencies = [ 1770 1931 "futures-core", 1932 + ] 1933 + 1934 + [[package]] 1935 + name = "system-configuration" 1936 + version = "0.6.1" 1937 + source = "registry+https://github.com/rust-lang/crates.io-index" 1938 + checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" 1939 + dependencies = [ 1940 + "bitflags", 1941 + "core-foundation", 1942 + "system-configuration-sys", 1943 + ] 1944 + 1945 + [[package]] 1946 + name = "system-configuration-sys" 1947 + version = "0.6.0" 1948 + source = "registry+https://github.com/rust-lang/crates.io-index" 1949 + checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" 1950 + dependencies = [ 1951 + "core-foundation-sys", 1952 + "libc", 1771 1953 ] 1772 1954 1773 1955 [[package]] ··· 1898 2080 ] 1899 2081 1900 2082 [[package]] 2083 + name = "tokio-rustls" 2084 + version = "0.26.0" 2085 + source = "registry+https://github.com/rust-lang/crates.io-index" 2086 + checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" 2087 + dependencies = [ 2088 + "rustls", 2089 + "rustls-pki-types", 2090 + "tokio", 2091 + ] 2092 + 2093 + [[package]] 1901 2094 name = "tokio-stream" 1902 2095 version = "0.1.16" 1903 2096 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2098 2291 checksum = "eb066959b24b5196ae73cb057f45598450d2c5f71460e98c49b738086eff9c06" 2099 2292 2100 2293 [[package]] 2294 + name = "untrusted" 2295 + version = "0.9.0" 2296 + source = "registry+https://github.com/rust-lang/crates.io-index" 2297 + checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" 2298 + 2299 + [[package]] 2101 2300 name = "url" 2102 2301 version = "2.5.2" 2103 2302 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2219 2418 ] 2220 2419 2221 2420 [[package]] 2421 + name = "webpki-roots" 2422 + version = "0.26.6" 2423 + source = "registry+https://github.com/rust-lang/crates.io-index" 2424 + checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958" 2425 + dependencies = [ 2426 + "rustls-pki-types", 2427 + ] 2428 + 2429 + [[package]] 2222 2430 name = "winapi" 2223 2431 version = "0.3.9" 2224 2432 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2465 2673 "quote", 2466 2674 "syn 2.0.86", 2467 2675 ] 2676 + 2677 + [[package]] 2678 + name = "zeroize" 2679 + version = "1.8.1" 2680 + source = "registry+https://github.com/rust-lang/crates.io-index" 2681 + checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
+1
Cargo.toml
··· 14 14 serde = "1.0.213" 15 15 serde_json = "1.0.132" 16 16 url = "2.5.2" 17 + reqwest = { version = "*", features = ["rustls-tls", "json"] }
+27 -3
src/bsky.rs
··· 1 1 use crate::meow::{ 2 - BotCheck, EmbedAuthor, EmbedMedia, EmbedResponse, EmbedSource, EmbedThingy, GenericError, 3 - MissingElementError, 2 + BotCheck, DidPlcResponse, EmbedAuthor, EmbedMedia, EmbedResponse, EmbedSource, EmbedThingy, 3 + GenericError, MissingElementError, 4 4 }; 5 5 use crate::ManagedBskyAgent; 6 6 use bsky_sdk::api::app::bsky::embed::images::ImageData; ··· 97 97 if let Some(embeds) = record.get_key_value("embed") { 98 98 let embeds = embeds.1; 99 99 100 + // for bsky.social we're gonna take a shortcut, as we're pretty much 100% sure that the PDS will be at bsky.social 101 + let pds_endpoint = if name.ends_with(".bsky.social") { 102 + "https://bsky.social".to_string() 103 + } else { 104 + resolve_plc_did(did).await? 105 + }; 106 + 100 107 // multiple? images 101 108 let images = match embeds.get("images") { 102 109 Ok(Some(Ipld::List(images))) => { ··· 135 142 }; 136 143 137 144 for blob in blobs { 138 - let url = format!("https://bsky.social/xrpc/com.atproto.sync.getBlob?did={}&cid={}", did, blob.r#ref.0); 145 + let url = format!("{}/xrpc/com.atproto.sync.getBlob?did={}&cid={}", pds_endpoint, did, blob.r#ref.0); 139 146 if blob.mime_type.starts_with("image/") { 140 147 media_embeds.push(EmbedMedia::Image(url)); 141 148 } else { ··· 172 179 Err(()) 173 180 } 174 181 } 182 + 183 + async fn resolve_plc_did(did: &str) -> Result<String, GenericError> { 184 + let meow = reqwest::Client::new() 185 + .get(format!("https://plc.directory/{}", did)) 186 + .send() 187 + .await? 188 + .json::<DidPlcResponse>() 189 + .await?; 190 + 191 + let pds_service = meow 192 + .service 193 + .iter() 194 + .find(|service| service.id == "#atproto_pds") 195 + .ok_or(GenericError::TooTired)?; 196 + 197 + Ok(pds_service.service_endpoint.clone()) 198 + }
+21 -1
src/meow.rs
··· 5 5 use rocket::response::{Redirect, Responder}; 6 6 use rocket::{response, Request, Response}; 7 7 use serde::ser::SerializeMap; 8 - use serde::Serialize; 8 + use serde::{Deserialize, Serialize}; 9 9 use thiserror::Error; 10 10 use url::Url; 11 11 ··· 217 217 218 218 #[error("bsky sdk error")] 219 219 Bsky(#[from] bsky_sdk::Error), 220 + 221 + #[error("reqwest error")] 222 + Reqwest(#[from] reqwest::Error), 220 223 } 221 224 222 225 impl Serialize for GenericError { ··· 231 234 GenericError::GetBlob(e) => e.to_string(), 232 235 GenericError::InvalidCID(e) => e.to_string(), 233 236 GenericError::Bsky(e) => e.to_string(), 237 + _ => self.to_string(), 234 238 }; 235 239 let mut map = serializer.serialize_map(Some(2))?; 236 240 map.serialize_entry("error", &format!("{}: {}", self, &error_message))?; ··· 305 309 Outcome::Success(Self(false)) 306 310 } 307 311 } 312 + 313 + #[derive(Serialize, Deserialize)] 314 + pub struct PlcService { 315 + pub id: String, 316 + #[serde(rename = "type")] 317 + pub type_: String, 318 + 319 + #[serde(rename = "serviceEndpoint")] 320 + pub service_endpoint: String, 321 + } 322 + 323 + #[derive(Serialize, Deserialize)] 324 + pub struct DidPlcResponse { 325 + pub id: String, 326 + pub service: Vec<PlcService>, 327 + }