0
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 のインスタンス(5) 他のインスタンス(Misskey系)の投稿に like する

Posted at

Misskey 系と Mastodon 系の違い

  • アクター名と アクターの ID が違う
  • HTTP 署名で求められるヘッダが多い

アクター名とアクターの ID が違うというのは、例えばアクター名が foobar の場合、Mastodon 系ならばアクターの ID はそのまま foobar だが、Misskey 系はそれとは別にある程度ランダムな英数字の文字列が ID として割り振られている。アドレスとして
https://Misskey系インスタンス/@foobar

https://Misskey系インスタンス/users/ある程度ランダムな英数字の文字列
のエイリアス、というか、下のアドレスは上へリダイレクトされる。
なので webfinger を使って rel => self の href の値を求め、そのアドレスへヘッダに "Accept: application/activity+json" を加えて GET リクエストを送り、返ってくる json の inbox タグの値を求める必要がある。

URL=$(curl https://Misskey系インスタンス/.well-known/webfinger?resource=acct:foobar@Misskey系インスタンス | jq -r '.links[] | select (.rel == "self")'.href)
INBOX=$(curl -H "Accept: application/activity+json" $URL | jq .inbox)

Mastodon 系は(現時点では)ヘッダの Date Digest だけを \n で繋げて署名すれば良かったが、Misskey 系は request-target (POST タグの2番めまでの値。POST /users/foobar/inbox HTTP/1.1 ならば、"post /users/foobar/inbox") と Host も求められるようである。

やること

それ以外は前回とほぼ同じである。前回と違うのは上述の通り。

  • webfinger にリクエストを送り、ID (URL) と inbox のアドレスを取得し
  • request-target date host digest を \n で繋げたものに署名する

前回は引数で like する ID と、その投稿者の inbox を与えていたが、今回は上述の理由(インスタンスとアクター名を webfinger に入れてアクターの ID を取得しなければならない)のため、対話的に投稿者のインスタンスとアクター名、投稿の ID を入力することにする。ついでに自分のインスタンスとアクター名もここで指定することにする。

post_like.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

# like したい投稿の ID を入力
read -p "which id do you wanna like?: " target_post
echo

unixtime=$(date "+%s")

# 投稿者のインスタンス・アクター名から URL と inbox を取得。また " を外しておく
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 は https://インスタンス 以下である(よって最初に "/" を付ける)
REQUEST_TARGET=$(echo  "/"$(sed -E 's/^.*(https):\/\/([^/]+).([^/]+)/\3/g' <<< $INBOX))

sed -e "s/{id}/$unixtime/g" like.json > live
sed -i "s/{myself}/$myself/g" live
sed -i "s/{my_instance}/$my_instance/g" live
sed -i "s|{target_post}|$target_post|g" live

body=$(cat live | jq -c .)
digest_val=$(echo -n "$body" | sha256sum | xxd -r -p | base64)
date_now=$(date -uR  | head -c -6 | sed -e 's/$/GMT/')

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"

基本は前回と変わらないが、微細な違いはコードとコメントを読んでいただきたい。
もちろん Mastodon 系の投稿にもこれで like できるので、以降このスクリプトを基本として他のアクティビティも書く。

0
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
0
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?