Add some untested version of publishing a feed
Also adjust names of different env vars, and also adjust setup instructions
This commit is contained in:
parent
5128bf9d4a
commit
e95c4923d6
|
@ -1,3 +1,6 @@
|
||||||
|
PUBLISHER_BLUESKY_HANDLE="..."
|
||||||
|
PUBLISHER_BLUESKY_PASSWORD="..."
|
||||||
|
PUBLISHER_DID="..."
|
||||||
CHAT_GPT_API_KEY="fake-chat-gpt-key"
|
CHAT_GPT_API_KEY="fake-chat-gpt-key"
|
||||||
DATABASE_URL="postgres://postgres:password@localhost/nederlandskie"
|
DATABASE_URL="postgres://postgres:password@localhost/nederlandskie"
|
||||||
HOSTNAME="..."
|
FEED_GENERATOR_HOSTNAME="..."
|
||||||
|
|
|
@ -75,6 +75,54 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstream"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"anstyle-parse",
|
||||||
|
"anstyle-query",
|
||||||
|
"anstyle-wincon",
|
||||||
|
"colorchoice",
|
||||||
|
"utf8parse",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b84bf0a05bbb2a83e5eb6fa36bb6e87baa08193c35ff52bbf6b38d8af2890e46"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-parse"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333"
|
||||||
|
dependencies = [
|
||||||
|
"utf8parse",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-query"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b"
|
||||||
|
dependencies = [
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-wincon"
|
||||||
|
version = "2.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anyhow"
|
name = "anyhow"
|
||||||
version = "1.0.75"
|
version = "1.0.75"
|
||||||
|
@ -430,6 +478,52 @@ dependencies = [
|
||||||
"unsigned-varint",
|
"unsigned-varint",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap"
|
||||||
|
version = "4.4.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b1d7b8d5ec32af0fadc644bf1fd509a688c2103b185644bb1e29d164e0703136"
|
||||||
|
dependencies = [
|
||||||
|
"clap_builder",
|
||||||
|
"clap_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_builder"
|
||||||
|
version = "4.4.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5179bb514e4d7c2051749d8fcefa2ed6d06a9f4e6d69faf3805f5d80b8cf8d56"
|
||||||
|
dependencies = [
|
||||||
|
"anstream",
|
||||||
|
"anstyle",
|
||||||
|
"clap_lex",
|
||||||
|
"strsim",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_derive"
|
||||||
|
version = "4.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873"
|
||||||
|
dependencies = [
|
||||||
|
"heck",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.35",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_lex"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "colorchoice"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "compact_str"
|
name = "compact_str"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
|
@ -2248,6 +2342,7 @@ dependencies = [
|
||||||
"chat-gpt-lib-rs",
|
"chat-gpt-lib-rs",
|
||||||
"chrono",
|
"chrono",
|
||||||
"ciborium",
|
"ciborium",
|
||||||
|
"clap",
|
||||||
"dotenv",
|
"dotenv",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"futures",
|
"futures",
|
||||||
|
@ -3284,6 +3379,12 @@ dependencies = [
|
||||||
"unicode-normalization",
|
"unicode-normalization",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strsim"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strum"
|
name = "strum"
|
||||||
version = "0.24.1"
|
version = "0.24.1"
|
||||||
|
@ -3658,6 +3759,12 @@ version = "0.7.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
|
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "utf8parse"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vcpkg"
|
name = "vcpkg"
|
||||||
version = "0.2.15"
|
version = "0.2.15"
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
name = "nederlandskie"
|
name = "nederlandskie"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
default-run = "nederlandskie"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
@ -14,6 +15,7 @@ axum = "0.6.20"
|
||||||
chat-gpt-lib-rs = "0.2.1"
|
chat-gpt-lib-rs = "0.2.1"
|
||||||
chrono = "0.4.31"
|
chrono = "0.4.31"
|
||||||
ciborium = "0.2.1"
|
ciborium = "0.2.1"
|
||||||
|
clap = { version = "4.4.4", features = ["derive"] }
|
||||||
dotenv = "0.15.0"
|
dotenv = "0.15.0"
|
||||||
env_logger = "0.10.0"
|
env_logger = "0.10.0"
|
||||||
futures = "0.3.28"
|
futures = "0.3.28"
|
||||||
|
|
28
README.md
28
README.md
|
@ -15,14 +15,32 @@ Heavily WIP. Doesn't work yet at all, but does read the stream of posts as they
|
||||||
- [ ] Publish the feed
|
- [ ] Publish the feed
|
||||||
- [ ] Handle deleting of posts
|
- [ ] Handle deleting of posts
|
||||||
|
|
||||||
## Initial setup
|
## Configuration
|
||||||
|
|
||||||
Copy `.env.example` into `.env` and set up the environment variables within:
|
1. Copy `.env.example` into `.env` and set up the environment variables within:
|
||||||
|
|
||||||
- `CHAT_GPT_API_KEY` for your ChatGPT key
|
- `PUBLISHER_BLUESKY_HANDLE` to your Bluesky handle
|
||||||
- `DATABASE_URL` for PostgreSQL credentials
|
- `PUBLISHER_BLUESKY_PASSWORD` to Bluesky app password that you created in settings
|
||||||
- `HOSTNAME` to the hostname of where you intend to host the feed
|
- `CHAT_GPT_API_KEY` for your ChatGPT key
|
||||||
|
- `DATABASE_URL` for PostgreSQL credentials
|
||||||
|
- `FEED_GENERATOR_HOSTNAME` to the hostname of where you intend to host the feed
|
||||||
|
|
||||||
|
2. Determine your own DID and put it in `PUBLISHER_DID` env variable in `.env`:
|
||||||
|
|
||||||
|
```
|
||||||
|
cargo run --bin who_am_i
|
||||||
|
```
|
||||||
|
|
||||||
## Running
|
## Running
|
||||||
|
|
||||||
|
### Populate and serve the feed
|
||||||
|
|
||||||
`cargo run`
|
`cargo run`
|
||||||
|
|
||||||
|
### Determine your own did for publishing
|
||||||
|
|
||||||
|
`cargo run --bin who_am_i`
|
||||||
|
|
||||||
|
### Publish the feed
|
||||||
|
|
||||||
|
`cargo run --bin publish_feed -- --help`
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
extern crate nederlandskie;
|
||||||
|
|
||||||
|
use std::env;
|
||||||
|
|
||||||
|
use anyhow::{Context, Result};
|
||||||
|
use clap::Parser;
|
||||||
|
use dotenv::dotenv;
|
||||||
|
|
||||||
|
use nederlandskie::services::Bluesky;
|
||||||
|
|
||||||
|
#[derive(Parser, Debug)]
|
||||||
|
struct Args {
|
||||||
|
/// Short name of the feed. Must match one of the defined algos.
|
||||||
|
#[arg(long)]
|
||||||
|
name: String,
|
||||||
|
|
||||||
|
/// Name that will be displayed in Bluesky interface
|
||||||
|
#[arg(long)]
|
||||||
|
display_name: String,
|
||||||
|
|
||||||
|
/// Description that will be displayed in Bluesky interface
|
||||||
|
#[arg(long)]
|
||||||
|
description: String,
|
||||||
|
|
||||||
|
/// Filename of the avatar that will be displayed
|
||||||
|
#[arg(long)]
|
||||||
|
avatar_filename: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() -> Result<()> {
|
||||||
|
dotenv()?;
|
||||||
|
|
||||||
|
let args = Args::parse();
|
||||||
|
|
||||||
|
let handle = env::var("PUBLISHER_BLUESKY_HANDLE")
|
||||||
|
.context("PUBLISHER_BLUESKY_HANDLE environment variable must be set")?;
|
||||||
|
|
||||||
|
let password = env::var("PUBLISHER_BLUESKY_PASSWORD")
|
||||||
|
.context("PUBLISHER_BLUESKY_PASSWORD environment variable must be set")?;
|
||||||
|
|
||||||
|
let feed_generator_did = format!("did:web:{}", env::var("FEED_GENERATOR_HOSTNAME")?);
|
||||||
|
|
||||||
|
let bluesky = Bluesky::new("https://bsky.social");
|
||||||
|
|
||||||
|
let session = bluesky.login(&handle, &password).await?;
|
||||||
|
|
||||||
|
let mut avatar = None;
|
||||||
|
if let Some(path) = args.avatar_filename {
|
||||||
|
let bytes = std::fs::read(path)?;
|
||||||
|
avatar = Some(bluesky.upload_blob(bytes).await?);
|
||||||
|
}
|
||||||
|
|
||||||
|
bluesky
|
||||||
|
.publish_feed(
|
||||||
|
&session.did,
|
||||||
|
&feed_generator_did,
|
||||||
|
&args.name,
|
||||||
|
&args.display_name,
|
||||||
|
&args.description,
|
||||||
|
avatar,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
extern crate nederlandskie;
|
||||||
|
|
||||||
|
use std::env;
|
||||||
|
|
||||||
|
use anyhow::{Context, Result};
|
||||||
|
use dotenv::dotenv;
|
||||||
|
|
||||||
|
use nederlandskie::services::Bluesky;
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() -> Result<()> {
|
||||||
|
dotenv()?;
|
||||||
|
|
||||||
|
let bluesky = Bluesky::new("https://bsky.social");
|
||||||
|
|
||||||
|
let handle = env::var("PUBLISHER_BLUESKY_HANDLE")
|
||||||
|
.context("PUBLISHER_BLUESKY_HANDLE environment variable must be set")?;
|
||||||
|
|
||||||
|
let password = env::var("PUBLISHER_BLUESKY_PASSWORD")
|
||||||
|
.context("PUBLISHER_BLUESKY_PASSWORD environment variable must be set")?;
|
||||||
|
|
||||||
|
let session = bluesky.login(&handle, &password).await?;
|
||||||
|
|
||||||
|
println!("{}", session.did);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
|
@ -5,9 +5,9 @@ use std::env;
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub chat_gpt_api_key: String,
|
pub chat_gpt_api_key: String,
|
||||||
pub database_url: String,
|
pub database_url: String,
|
||||||
pub service_did: String,
|
pub feed_generator_did: String,
|
||||||
pub publisher_did: String,
|
pub publisher_did: String,
|
||||||
pub hostname: String,
|
pub feed_generator_hostname: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
|
@ -17,9 +17,9 @@ impl Config {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
chat_gpt_api_key: env::var("CHAT_GPT_API_KEY")?,
|
chat_gpt_api_key: env::var("CHAT_GPT_API_KEY")?,
|
||||||
database_url: env::var("DATABASE_URL")?,
|
database_url: env::var("DATABASE_URL")?,
|
||||||
hostname: env::var("HOSTNAME")?,
|
feed_generator_hostname: env::var("FEED_GENERATOR_HOSTNAME")?,
|
||||||
service_did: format!("did:web:{}", env::var("HOSTNAME")?),
|
feed_generator_did: format!("did:web:{}", env::var("FEED_GENERATOR_HOSTNAME")?),
|
||||||
publisher_did: "".to_owned(), // TODO
|
publisher_did: env::var("PUBLISHER_DID")?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ pub async fn describe_feed_generator(
|
||||||
State(state): State<FeedServerState>,
|
State(state): State<FeedServerState>,
|
||||||
) -> Json<FeedGeneratorDescription> {
|
) -> Json<FeedGeneratorDescription> {
|
||||||
Json(FeedGeneratorDescription {
|
Json(FeedGeneratorDescription {
|
||||||
did: state.config.service_did.clone(),
|
did: state.config.feed_generator_did.clone(),
|
||||||
feeds: state
|
feeds: state
|
||||||
.algos
|
.algos
|
||||||
.iter_names()
|
.iter_names()
|
||||||
|
|
|
@ -22,11 +22,11 @@ pub struct Service {
|
||||||
pub async fn did_json(State(state): State<FeedServerState>) -> Json<Did> {
|
pub async fn did_json(State(state): State<FeedServerState>) -> Json<Did> {
|
||||||
Json(Did {
|
Json(Did {
|
||||||
context: vec!["https://www.w3.org/ns/did/v1".to_owned()],
|
context: vec!["https://www.w3.org/ns/did/v1".to_owned()],
|
||||||
id: state.config.service_did.clone(),
|
id: state.config.feed_generator_did.clone(),
|
||||||
service: vec![Service {
|
service: vec![Service {
|
||||||
id: "#bsky_fg".to_owned(),
|
id: "#bsky_fg".to_owned(),
|
||||||
type_: "BskyFeedGenerator".to_owned(),
|
type_: "BskyFeedGenerator".to_owned(),
|
||||||
service_endpoint: format!("https://{}", state.config.hostname),
|
service_endpoint: format!("https://{}", state.config.feed_generator_hostname),
|
||||||
}],
|
}],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,12 +38,12 @@ impl PostIndexer {
|
||||||
|
|
||||||
let cursor = self
|
let cursor = self
|
||||||
.database
|
.database
|
||||||
.fetch_subscription_cursor(&self.config.service_did)
|
.fetch_subscription_cursor(&self.config.feed_generator_did)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
if cursor.is_none() {
|
if cursor.is_none() {
|
||||||
self.database
|
self.database
|
||||||
.create_subscription_state(&self.config.service_did)
|
.create_subscription_state(&self.config.feed_generator_did)
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,10 +91,10 @@ impl CommitProcessor for PostIndexer {
|
||||||
if commit.seq % 20 == 0 {
|
if commit.seq % 20 == 0 {
|
||||||
info!(
|
info!(
|
||||||
"Updating cursor for {} to {}",
|
"Updating cursor for {} to {}",
|
||||||
self.config.service_did, commit.seq
|
self.config.feed_generator_did, commit.seq
|
||||||
);
|
);
|
||||||
self.database
|
self.database
|
||||||
.update_subscription_cursor(&self.config.service_did, commit.seq)
|
.update_subscription_cursor(&self.config.feed_generator_did, commit.seq)
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
|
use atrium_api::blob::BlobRef;
|
||||||
use atrium_api::client::AtpServiceClient;
|
use atrium_api::client::AtpServiceClient;
|
||||||
use atrium_api::client::AtpServiceWrapper;
|
use atrium_api::client::AtpServiceWrapper;
|
||||||
|
use atrium_api::records::Record;
|
||||||
use atrium_xrpc::client::reqwest::ReqwestClient;
|
use atrium_xrpc::client::reqwest::ReqwestClient;
|
||||||
|
use chrono::Utc;
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use log::error;
|
use log::error;
|
||||||
use tokio_tungstenite::{connect_async, tungstenite};
|
use tokio_tungstenite::{connect_async, tungstenite};
|
||||||
|
@ -14,6 +17,11 @@ pub struct ProfileDetails {
|
||||||
pub description: String,
|
pub description: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct SessionDetails {
|
||||||
|
pub did: String,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Bluesky {
|
pub struct Bluesky {
|
||||||
client: AtpServiceClient<AtpServiceWrapper<ReqwestClient>>,
|
client: AtpServiceClient<AtpServiceWrapper<ReqwestClient>>,
|
||||||
}
|
}
|
||||||
|
@ -25,6 +33,77 @@ impl Bluesky {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn login(&self, handle: &str, password: &str) -> Result<SessionDetails> {
|
||||||
|
use atrium_api::com::atproto::server::create_session::Input;
|
||||||
|
|
||||||
|
let result = self
|
||||||
|
.client
|
||||||
|
.service
|
||||||
|
.com
|
||||||
|
.atproto
|
||||||
|
.server
|
||||||
|
.create_session(Input {
|
||||||
|
identifier: handle.to_owned(),
|
||||||
|
password: password.to_owned(),
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(SessionDetails { did: result.did })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn upload_blob(&self, blob: Vec<u8>) -> Result<BlobRef> {
|
||||||
|
let result = self
|
||||||
|
.client
|
||||||
|
.service
|
||||||
|
.com
|
||||||
|
.atproto
|
||||||
|
.repo
|
||||||
|
.upload_blob(blob)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(result.blob)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn publish_feed(
|
||||||
|
&self,
|
||||||
|
publisher_did: &str,
|
||||||
|
feed_generator_did: &str,
|
||||||
|
name: &str,
|
||||||
|
display_name: &str,
|
||||||
|
description: &str,
|
||||||
|
avatar: Option<BlobRef>,
|
||||||
|
) -> Result<()> {
|
||||||
|
use atrium_api::com::atproto::repo::put_record::Input;
|
||||||
|
|
||||||
|
self.client
|
||||||
|
.service
|
||||||
|
.com
|
||||||
|
.atproto
|
||||||
|
.repo
|
||||||
|
.put_record(Input {
|
||||||
|
collection: "app.bsky.feed.generator".to_owned(),
|
||||||
|
record: Record::AppBskyFeedGenerator(Box::new(
|
||||||
|
atrium_api::app::bsky::feed::generator::Record {
|
||||||
|
avatar,
|
||||||
|
created_at: Utc::now().to_string(),
|
||||||
|
description: Some(description.to_owned()),
|
||||||
|
description_facets: None,
|
||||||
|
did: feed_generator_did.to_owned(),
|
||||||
|
display_name: display_name.to_owned(),
|
||||||
|
labels: None,
|
||||||
|
},
|
||||||
|
)),
|
||||||
|
repo: publisher_did.to_owned(),
|
||||||
|
rkey: name.to_owned(),
|
||||||
|
swap_commit: None,
|
||||||
|
swap_record: None,
|
||||||
|
validate: None,
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn fetch_profile_details(&self, did: &str) -> Result<ProfileDetails> {
|
pub async fn fetch_profile_details(&self, did: &str) -> Result<ProfileDetails> {
|
||||||
let result = self
|
let result = self
|
||||||
.client
|
.client
|
||||||
|
@ -41,7 +120,7 @@ impl Bluesky {
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let profile = match result.value {
|
let profile = match result.value {
|
||||||
atrium_api::records::Record::AppBskyActorProfile(profile) => profile,
|
Record::AppBskyActorProfile(profile) => profile,
|
||||||
_ => return Err(anyhow!("Big bad, no such profile")),
|
_ => return Err(anyhow!("Big bad, no such profile")),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue