ai/at
ai/at
1
0
This commit is contained in:
syui 2024-11-12 16:38:53 +09:00
parent e7471b20e4
commit 0403ba0bc4
Signed by: syui
GPG Key ID: 5417CFEBAD92DF56
2 changed files with 190 additions and 0 deletions

140
at.zsh Executable file
View File

@ -0,0 +1,140 @@
#!/bin/zsh
help=(
at.zsh d handle
at.zsh u at-uri
at.zsh c at-uri -r
at.zsh docs
)
host=(
bsky.social
public.api.bsky.app
plc.directory
)
lexicon=(
com.atproto.repo.describeRepo
com.atproto.repo.getRecord
com.atproto.repo.listRecords
com.atproto.identity.resolveHandle
com.atproto.server.createSession
com.atproto.server.refreshSession
)
function at-env() {
host=bsky.social
at_uri=at://did:plc:4hqjfn7m6n5hno3doamuhgef/ai.syui.game.user/syui
docs_uri=https://docs.bsky.app/docs/api
handle=yui.syui.ai
did=`echo $at_uri|cut -d / -f 3`
collection=`echo $at_uri|cut -d / -f 4`
rkey=`echo $at_uri|cut -d / -f 5`
d=${0:a:h}
f=~/.config/.at-zsh.json
}
function at-uri-search() {
if [ -n "$1" ];then
at_uri=$1
fi
req=/xrpc/com.atproto.repo.getRecord
url=https://${host}${req}
did=`echo $at_uri|cut -d / -f 3`
collection=`echo $at_uri|cut -d / -f 4`
rkey=`echo $at_uri|cut -d / -f 5`
curl -sL "$url?repo=$did&collection=$collection&rkey=$rkey"|jq .
}
function at-did-search() {
if [ -n "$1" ];then
handle=$1
fi
req=/xrpc/com.atproto.repo.describeRepo
url=https://${host}${req}
curl -sL "$url?repo=$handle"|jq .
}
function at-collection-search() {
reverse=false
if [ -n "$1" ];then
at_uri=$1
fi
if [ "$2" = "-r" ];then
reverse=true
fi
req=/xrpc/com.atproto.repo.listRecords
url=https://${host}${req}
did=`echo $at_uri|cut -d / -f 3`
collection=`echo $at_uri|cut -d / -f 4`
curl -sL "$url?repo=$did&collection=$collection&reverse=$reverse"|jq .
}
function at-docs() {
for i in $lexicon; do
req=`echo $i|tr '.' '-'|sed 's/[A-Z]/-&/g'|tr '[A-Z]' '[a-z]'`
url=$docs_uri/$req
echo $url
done
}
function at-login() {
if [ -z "$1" ] || [ -z "$2" ];then
echo handle password
exit
fi
handle=$1
password=$2
echo $password
json="{\"identifier\":\"$handle\",\"password\":\"$password\"}"
req=/xrpc/com.atproto.server.createSession
url=https://${host}${req}
if [ ! -d ~/.config ];then
mkdir -p ~/.config
fi
t=`curl -sL -X POST -H "Content-Type: application/json" -d $json $url`
if echo $t |jq .;then
echo $t >! $f
fi
unset t password
}
function at-refresh() {
echo $f
token=`cat $f|jq -r .accessJwt`
refresh=`cat $f|jq -r .refreshJwt`
req=/xrpc/com.atproto.server.refreshSession
url=https://${host}${req}
t=`curl -sL -X POST -H "Content-Type: application/json" -H "Authorization: Bearer $refresh" $url`
if echo $t |jq .;then
echo $t >! $f
fi
unset t token refresh
}
at-env
case $1 in
uri|u)
at-uri-search $2
;;
did|d)
at-did-search $2
;;
collection|c)
at-collection-search $2 $3
;;
at-docs|docs)
at-docs
;;
login|l)
at-login $2 $3
;;
refresh|r)
at-refresh
;;
*)
echo "${help[@]}"
echo "${host[@]}"
echo "${lexicon[@]}"
;;
esac

View File

@ -0,0 +1,50 @@
import "server-only";
import { z } from "zod";
import { ensureUser } from "../user";
import { DataLayerError } from "../error";
import { fetchAuthenticatedAtproto } from "@/lib/auth";
import { AtUri } from "./uri";
const PutRecordResponse = z.object({
uri: AtUri,
cid: z.string(),
});
type PutRecordInput = {
rkey?: string;
record: unknown;
collection: string;
};
export async function atprotoPutRecord({
rkey,
record,
collection,
}: PutRecordInput) {
const user = await ensureUser();
const pdsUrl = new URL(user.pdsUrl);
pdsUrl.pathname = "/xrpc/com.atproto.repo.putRecord";
const response = await fetchAuthenticatedAtproto(pdsUrl.toString(), {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
rkey: rkey || "self",
repo: user.did,
collection,
validate: false,
record: record,
}),
});
if (!response.ok) {
throw new DataLayerError(`Failed to create record ${response.status}`, {
cause: response,
});
}
return PutRecordResponse.parse(await response.json());
}