1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Bash と Caddy サーバで ActivityPub のインスタンス(8) reply.sh もフォロワーに送りつける

Last updated at Posted at 2024-01-17

reply.sh を改造する

Note と同じく、誰かへのリプライも自分のフォロワーへ配送しなければならない。(ここでは公開範囲を考えないことにする)
なので note.sh と同様に

  • followers ファイルから各フォロワーの inbox エンドポイントを取得して配列にし
  • reply する相手がフォロワーにいなかったら、その配列に加えるが
  • フォロワーにいたらその配列には加えず
  • その配列の各エンドポイントへ全部配送する

というようにする。以下がそのスクリプトである。

reply.sh
#!/bin/bash


read -p "@myself@my_instance: " MY
MY_arry=(${MY//@/ })
myself=${MY_arry[0]}
my_instance=${MY_arry[1]}
echo

read -p "@to@to_instance: " TO
TO_arry=(${TO//@/ })
to=${TO_arry[0]}
to_instance=${TO_arry[1]}
echo

read -p "which id do you wanna reply?: " id_of_reply_to
echo

if [ -n "$id_of_reply_to" ]; then
	id_of_reply_to=\"$id_of_reply_to\"
else id_of_reply_to="null"
fi

read -p "what do you wanna mention?: " content
echo


URL=$(curl https://$to_instance/.well-known/webfinger?resource=acct:$to@$to_instance | jq -r '.links[] | select (.rel == "self")'.href | tr -d "\"")
INBOX=$(curl -H "Accept: application/activity+json" $URL | jq .inbox | tr -d "\"")
REQUEST_TARGET=$(echo  "/"$(sed -E 's/^.*(https):\/\/([^/]+).([^/]+)/\3/g' <<< $INBOX))

unixtime=$(date "+%s")
date_now=$(date -uR  | head -c -6 | sed -e 's/$/GMT/')

sed -e "s/{id}/$unixtime/g" ./json_templates/reply.json > live
sed -i "s/{myself}/$myself/g" live
sed -i "s/{my_instance}/$my_instance/g" live
sed -i "s/{to}/$to/g" live
sed -i "s/{to_instance}/$to_instance/g" live
sed -i "s/{date_now}/$date_now/g" live
sed -i "s|{id_of_reply_to}|$id_of_reply_to|g" live
sed -i "s|{URL}|"$URL"|g" live
sed -i "s/{content}/$content/g" live


body=$(cat live | jq -c .)
digest_val=$(echo -n "$body" | sha256sum | xxd -r -p | base64)


### フォロワーの inbox 一覧を followers ファイルから取得
while read -r line; do
	followers_inbox_URL+=( $(echo $line) ) # 配列に
done < followers

## followers_inbox_URL 配列に reply する相手がいたら追加
if echo "${followers_inbox_URL[*]}" | grep -qw "$INBOX"; then
	:
else
	followers_inbox_URL+=($INBOX)
fi

# for で followers_inbox_URL 配列内の inbox へ、署名して配送
for INBOX in ${followers_inbox_URL[*]}; do

	to_instance=$(sed -E 's/^.*(http|https):\/\/([^/]+).*/\2/g' <<< $INBOX)
	REQUEST_TARGET=$(echo "/"$(sed -E 's/^.*(http|https):\/\/([^/]+).([^/]+)/\3/g' <<< $INBOX))

	signature_headers="(request-target): post ${REQUEST_TARGET}\ndate: ${date_now}\nhost: ${to_instance}\ndigest: SHA-256=${digest_val}"
	echo -e "$signature_headers" > 4_sig_headers # 後に見返すためにファイルに
	sig_val=$(echo -en $signature_headers | openssl dgst -binary -sign ./personal/private -sha256 | openssl enc -A -base64)
	signature="Signature: keyId=\"https://${my_instance}/users/${myself}#main-key\",algorithm=\"rsa-sha256\",headers=\"(request-target) date host digest\",signature=\"$sig_val\""

	curl -H "Date: $date_now" -H "Digest: SHA-256=$digest_val" -H "$signature" $INBOX -d "$body"

done

echo $body | jq .object > ./statuses/$unixtime
echo $body > ./post/$unixtime

配列に変数 INBOX と同じ文字列があるかどうかを調べるのに grep -qw を使っているあたり以外は、元の reply.sh と note.sh をそれなりに混ぜただけである。
前回と同様に

bash ./script/reply.sh

と実行する。

参考記事

Bash 配列に値が含まれているかどうかを確認する方法

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?