2023-02-25 / syui

bluesky , atproto

blueskyのclientを少しだけやってみた

今回は、blueskyのclientを作ってcliからpostしてみたので、なにか書きます。

これはbsky.social特有のものかもしれませんが、requestを投げる先と投げる要素が結構変わっていたので、ハマりました。あとtypoに気づかずmatrixに質問を投げるなどやらかしていました。

基本的には公式のlexiconsを見ていけばいい感じでした。

https://atproto.com/lexicons/com-atproto-account

blueskyではpostの一式をrecordと呼びます。

createdAtを自分で入れなきゃなのなぜでしょう。あと、validatetrueなのでfalseにしてもいいかも。

下記のscriptは解説のために載せているだけなので読み替えてください。

例えば、date %3Nはgnu-dateです。

#!/bin/sh
# com.atproto.session.create
# com.atproto.repo.createRecord

#brew install coreutils
#PATH="/opt/homebrew/opt/coreutils/libexec/gnubin:$PATH"
date=`date "+%Y-%m-%dT%H:%M:%S.%3NZ"`

host=bsky.social
user=$USER
pass=xxx
curl -X POST -H "Content-Type: application/json" \
 -d "{\"handle\":\"$user.$host\",\"password\":\"$pass\"}" \
 https://$host/xrpc/com.atproto.session.create > token.json

token=`cat token.json|jq -r .accessJwt`
did=`cat token.json|jq -r .did`
url=https://$host/xrpc/com.atproto.repo.createRecord

json='{
  "did": "did:plc:xxx",
  "collection": "app.bsky.feed.post",
  "record": {
    "text": "t",
    "createdAt": "2023-02-25T05:06:50.330Z",
    "$type": "app.bsky.feed.post"
  }
}'
curl -X POST -H "Content-Type: application/json" \
 -H "Authorization: Bearer $token" \
 -d "$json" $url
#[tokio::main]
async fn feed_req(url: String, user: String, col: String) -> reqwest::Result<()> {
    let client = reqwest::Client::new();
    let body = client.get(url)
        .query(&[("user", &user),("collection", &col)])
        .send()
        .await?
        .text()
        .await?;
    println!("{}", body);
    Ok(())
}

#[allow(unused_must_use)]
fn feed_com(c :&Context) -> reqwest::Result<()> {
    let data = Datas::new().unwrap();
    let data = Datas {
        host: data.host,
        user: data.user,
        pass: data.pass,
    };
    let url = "https://".to_owned() + &data.host + &"/xrpc/com.atproto.repo.listRecords";
    let col = "app.bsky.feed.post".to_string();
    if let Ok(user) = c.string_flag("user") {
        feed_req(url, user, col);
    } else {
        let user = data.user + &"." + &data.host.to_string();
        feed_req(url, user, col);
    }
    Ok(())
}

fn feed(c: &Context) {
    feed_com(c).unwrap();
}

今回もrustで書いていたのですが、時間がかかりそうだったので、途中からshellでした。また、時間がある時にrustで書き直すかも。