greatape/app/commands/follow_actor.go

86 wiersze
1.8 KiB
Go

package commands
import (
"io"
"net/http"
"strings"
"github.com/reiver/greatape/app/activitypub"
. "github.com/reiver/greatape/components/constants"
. "github.com/reiver/greatape/components/contracts"
)
func FollowActor(x IDispatcher, username string, acct string) (IFollowActorResult, error) {
parts := strings.Split(acct, "@")
x.Assert(len(parts) == 2).Or(ERROR_INVALID_PARAMETERS)
webfingerUrl := x.Format("https://%s/.well-known/webfinger?resource=acct:%s", parts[1], acct)
resp, err := http.Get(webfingerUrl)
x.AssertNoError(err)
data, err := io.ReadAll(resp.Body)
x.AssertNoError(err)
webfinger, err := activitypub.UnmarshalWebfinger(data)
x.AssertNoError(err)
subject := ""
for _, link := range webfinger.Links {
if link.Rel == "self" {
subject = *link.Href
break
}
}
if x.IsEmpty(subject) {
return nil, ERROR_INVALID_PARAMETERS
}
identities := x.FilterIdentities(func(identity IIdentity) bool {
return identity.Username() == username
})
x.Assert(identities.HasExactlyOneItem()).Or(ERROR_USER_NOT_FOUND)
identity := identities.First()
follower := x.GetActorId()
followee := &activitypub.Actor{}
if err := x.GetActivityStreamSigned(subject, nil, followee); err != nil {
return nil, err
}
uniqueIdentifier := x.GenerateUUID()
follow := activitypub.NewFollow(follower, followee.ID, uniqueIdentifier)
x.Atomic(func() error {
activity := x.MarshalJson(follow)
x.AddActivityPubOutgoingActivity(
identity.Id(),
uniqueIdentifier,
x.UnixNano(),
follower,
followee.ID,
activitypub.TypeFollow,
activity,
)
x.AddActivityPubFollower(
follower,
followee.Inbox,
followee.ID,
activity,
false,
)
if err := x.PostActivityStreamSigned(followee.Inbox, follow, nil); err != nil {
return err
}
return nil
})
return x.NewFollowActorResult(follow.Id), nil
}