gotosocial/vendor/code.superseriousbusiness.org/activity/streams
tobi 754b7be9cf [feature] Support new model of interaction flow for forward compat with v0.21.0 (#4394)
~~Still WIP!~~

This PR allows v0.20.0 of GtS to be forward-compatible with the interaction request / authorization flow that will fully replace the current flow in v0.21.0.

Basically, this means we need to recognize LikeRequest, ReplyRequest, and AnnounceRequest, and in response to those requests, deliver either a Reject or an Accept, with the latter pointing towards a LikeAuthorization, ReplyAuthorization, or AnnounceAuthorization, respectively. This can then be used by the remote instance to prove to third parties that the interaction has been accepted by the interactee. These Authorization types need to be dereferencable to third parties, so we need to serve them.

As well as recognizing the above "polite" interaction request types, we also need to still serve appropriate responses to "impolite" interaction request types, where an instance that's unaware of interaction policies tries to interact with a post by sending a reply, like, or boost directly, without wrapping it in a WhateverRequest type.

Doesn't fully close https://codeberg.org/superseriousbusiness/gotosocial/issues/4026 but gets damn near (just gotta update the federating with GtS documentation).

Migrations tested on both Postgres and SQLite.

Co-authored-by: kim <grufwub@gmail.com>
Reviewed-on: https://codeberg.org/superseriousbusiness/gotosocial/pulls/4394
Co-authored-by: tobi <tobi.smethurst@protonmail.com>
Co-committed-by: tobi <tobi.smethurst@protonmail.com>
2025-09-14 15:37:35 +02:00
..
impl [feature] Support new model of interaction flow for forward compat with v0.21.0 (#4394) 2025-09-14 15:37:35 +02:00
values [chore] Move deps to code.superseriousbusiness.org (#4054) 2025-04-25 15:15:36 +02:00
vocab [feature] Support new model of interaction flow for forward compat with v0.21.0 (#4394) 2025-09-14 15:37:35 +02:00
gen_consts.go [feature] Support new model of interaction flow for forward compat with v0.21.0 (#4394) 2025-09-14 15:37:35 +02:00
gen_doc.go [chore] Move deps to code.superseriousbusiness.org (#4054) 2025-04-25 15:15:36 +02:00
gen_init.go [feature] Support new model of interaction flow for forward compat with v0.21.0 (#4394) 2025-09-14 15:37:35 +02:00
gen_json_resolver.go [feature] Use hidesToPublicFromUnauthedWeb and hidesCcPublicFromUnauthedWeb properties for web visibility of statuses (#4315) 2025-07-09 16:50:25 +02:00
gen_manager.go [feature] Support new model of interaction flow for forward compat with v0.21.0 (#4394) 2025-09-14 15:37:35 +02:00
gen_pkg_activitystreams_disjoint.go [chore] Move deps to code.superseriousbusiness.org (#4054) 2025-04-25 15:15:36 +02:00
gen_pkg_activitystreams_extendedby.go [chore] Move deps to code.superseriousbusiness.org (#4054) 2025-04-25 15:15:36 +02:00
gen_pkg_activitystreams_extends.go [chore] Move deps to code.superseriousbusiness.org (#4054) 2025-04-25 15:15:36 +02:00
gen_pkg_activitystreams_isorextends.go [chore] Move deps to code.superseriousbusiness.org (#4054) 2025-04-25 15:15:36 +02:00
gen_pkg_activitystreams_property_constructors.go [chore] Move deps to code.superseriousbusiness.org (#4054) 2025-04-25 15:15:36 +02:00
gen_pkg_activitystreams_type_constructors.go [chore] Move deps to code.superseriousbusiness.org (#4054) 2025-04-25 15:15:36 +02:00
gen_pkg_funkwhale_disjoint.go [chore] Move deps to code.superseriousbusiness.org (#4054) 2025-04-25 15:15:36 +02:00
gen_pkg_funkwhale_extendedby.go [chore] Move deps to code.superseriousbusiness.org (#4054) 2025-04-25 15:15:36 +02:00
gen_pkg_funkwhale_extends.go [chore] Move deps to code.superseriousbusiness.org (#4054) 2025-04-25 15:15:36 +02:00
gen_pkg_funkwhale_isorextends.go [chore] Move deps to code.superseriousbusiness.org (#4054) 2025-04-25 15:15:36 +02:00
gen_pkg_funkwhale_type_constructors.go [chore] Move deps to code.superseriousbusiness.org (#4054) 2025-04-25 15:15:36 +02:00
gen_pkg_gotosocial_disjoint.go [chore] Move deps to code.superseriousbusiness.org (#4054) 2025-04-25 15:15:36 +02:00
gen_pkg_gotosocial_extendedby.go [chore] Move deps to code.superseriousbusiness.org (#4054) 2025-04-25 15:15:36 +02:00
gen_pkg_gotosocial_extends.go [chore] Move deps to code.superseriousbusiness.org (#4054) 2025-04-25 15:15:36 +02:00
gen_pkg_gotosocial_isorextends.go [chore] Move deps to code.superseriousbusiness.org (#4054) 2025-04-25 15:15:36 +02:00
gen_pkg_gotosocial_property_constructors.go [feature] Support new model of interaction flow for forward compat with v0.21.0 (#4394) 2025-09-14 15:37:35 +02:00
gen_pkg_gotosocial_type_constructors.go [chore] Move deps to code.superseriousbusiness.org (#4054) 2025-04-25 15:15:36 +02:00
gen_pkg_jsonld_property_constructors.go [chore] Move deps to code.superseriousbusiness.org (#4054) 2025-04-25 15:15:36 +02:00
gen_pkg_litepub_disjoint.go [feature] Use hidesToPublicFromUnauthedWeb and hidesCcPublicFromUnauthedWeb properties for web visibility of statuses (#4315) 2025-07-09 16:50:25 +02:00
gen_pkg_litepub_extendedby.go [feature] Use hidesToPublicFromUnauthedWeb and hidesCcPublicFromUnauthedWeb properties for web visibility of statuses (#4315) 2025-07-09 16:50:25 +02:00
gen_pkg_litepub_extends.go [feature] Use hidesToPublicFromUnauthedWeb and hidesCcPublicFromUnauthedWeb properties for web visibility of statuses (#4315) 2025-07-09 16:50:25 +02:00
gen_pkg_litepub_isorextends.go [feature] Use hidesToPublicFromUnauthedWeb and hidesCcPublicFromUnauthedWeb properties for web visibility of statuses (#4315) 2025-07-09 16:50:25 +02:00
gen_pkg_litepub_type_constructors.go [feature] Use hidesToPublicFromUnauthedWeb and hidesCcPublicFromUnauthedWeb properties for web visibility of statuses (#4315) 2025-07-09 16:50:25 +02:00
gen_pkg_schema_disjoint.go [chore] Move deps to code.superseriousbusiness.org (#4054) 2025-04-25 15:15:36 +02:00
gen_pkg_schema_extendedby.go [chore] Move deps to code.superseriousbusiness.org (#4054) 2025-04-25 15:15:36 +02:00
gen_pkg_schema_extends.go [chore] Move deps to code.superseriousbusiness.org (#4054) 2025-04-25 15:15:36 +02:00
gen_pkg_schema_isorextends.go [chore] Move deps to code.superseriousbusiness.org (#4054) 2025-04-25 15:15:36 +02:00
gen_pkg_schema_property_constructors.go [chore] Move deps to code.superseriousbusiness.org (#4054) 2025-04-25 15:15:36 +02:00
gen_pkg_schema_type_constructors.go [chore] Move deps to code.superseriousbusiness.org (#4054) 2025-04-25 15:15:36 +02:00
gen_pkg_toot_disjoint.go [chore] Move deps to code.superseriousbusiness.org (#4054) 2025-04-25 15:15:36 +02:00
gen_pkg_toot_extendedby.go [chore] Move deps to code.superseriousbusiness.org (#4054) 2025-04-25 15:15:36 +02:00
gen_pkg_toot_extends.go [chore] Move deps to code.superseriousbusiness.org (#4054) 2025-04-25 15:15:36 +02:00
gen_pkg_toot_isorextends.go [chore] Move deps to code.superseriousbusiness.org (#4054) 2025-04-25 15:15:36 +02:00
gen_pkg_toot_property_constructors.go [chore] Move deps to code.superseriousbusiness.org (#4054) 2025-04-25 15:15:36 +02:00
gen_pkg_toot_type_constructors.go [chore] Move deps to code.superseriousbusiness.org (#4054) 2025-04-25 15:15:36 +02:00
gen_pkg_w3idsecurityv1_disjoint.go [chore] Move deps to code.superseriousbusiness.org (#4054) 2025-04-25 15:15:36 +02:00
gen_pkg_w3idsecurityv1_extendedby.go [chore] Move deps to code.superseriousbusiness.org (#4054) 2025-04-25 15:15:36 +02:00
gen_pkg_w3idsecurityv1_extends.go [chore] Move deps to code.superseriousbusiness.org (#4054) 2025-04-25 15:15:36 +02:00
gen_pkg_w3idsecurityv1_isorextends.go [chore] Move deps to code.superseriousbusiness.org (#4054) 2025-04-25 15:15:36 +02:00
gen_pkg_w3idsecurityv1_property_constructors.go [chore] Move deps to code.superseriousbusiness.org (#4054) 2025-04-25 15:15:36 +02:00
gen_pkg_w3idsecurityv1_type_constructors.go [chore] Move deps to code.superseriousbusiness.org (#4054) 2025-04-25 15:15:36 +02:00
gen_resolver_utils.go [feature] Use hidesToPublicFromUnauthedWeb and hidesCcPublicFromUnauthedWeb properties for web visibility of statuses (#4315) 2025-07-09 16:50:25 +02:00
gen_type_predicated_resolver.go [feature] Use hidesToPublicFromUnauthedWeb and hidesCcPublicFromUnauthedWeb properties for web visibility of statuses (#4315) 2025-07-09 16:50:25 +02:00
gen_type_resolver.go [feature] Use hidesToPublicFromUnauthedWeb and hidesCcPublicFromUnauthedWeb properties for web visibility of statuses (#4315) 2025-07-09 16:50:25 +02:00
README.md [chore] Move deps to code.superseriousbusiness.org (#4054) 2025-04-25 15:15:36 +02:00
util.go [bugfix] Remove errant alsoKnownAs inline @context entry (#4280) 2025-06-18 13:39:09 +02:00

streams

ActivityStreams vocabularies automatically code-generated with astool.

Reference & Tutorial

The go-fed website contains tutorials and reference materials, in addition to the rest of this README.

How To Use

go get github.com/go-fed/activity

All generated types and properties are interfaces in github.com/go-fed/streams/vocab, but note that the constructors and supporting functions live in github.com/go-fed/streams.

To create a type and set properties:

var actorURL *url.URL = // ...

// A new "Create" Activity.
create := streams.NewActivityStreamsCreate()
// A new "actor" property.
actor := streams.NewActivityStreamsActorProperty()
actor.AppendIRI(actorURL)
// Set the "actor" property on the "Create" Activity.
create.SetActivityStreamsActor(actor)

To process properties on a type:

// Returns true if the "Update" has at least one "object" with an IRI value.
func hasObjectWithIRIValue(update vocab.ActivityStreamsUpdate) bool {
  objectProperty := update.GetActivityStreamsObject()
  // Any property may be nil if it was either empty in the original JSON or
  // never set on the golang type.
  if objectProperty == nil {
    return false
  }
  // The "object" property is non-functional: it could have multiple values. The
  // generated code has slightly different methods for a functional property
  // versus a non-functional one.
  //
  // While it may be easy to ignore multiple values in other languages
  // (accidentally or purposefully), go-fed is designed to make it hard to do
  // so.
  for iter := objectProperty.Begin(); iter != objectProperty.End(); iter = iter.Next() {
    // If this particular value is an IRI, return true.
    if iter.IsIRI() {
      return true
    }
  }
  // All values are literal embedded values and not IRIs.
  return false
}

The ActivityStreams type hierarchy of "extends" and "disjoint" is not the same as the Object Oriented definition of inheritance. It is also not the same as golang's interface duck-typing. Helper functions are provided to guarantee that an application's logic can correctly apply the type hierarchy.

thing := // Pick a type from streams.NewActivityStreams<Type>()
if streams.ActivityStreamsObjectIsDisjointWith(thing) {
  fmt.Printf("The \"Object\" type is Disjoint with the %T type.\n", thing)
}
if streams.ActivityStreamsLinkIsExtendedBy(thing) {
  fmt.Printf("The %T type Extends from the \"Link\" type.\n", thing)
}
if streams.ActivityStreamsActivityExtends(thing) {
  fmt.Printf("The \"Activity\" type extends from the %T type.\n", thing)
}

When given a generic JSON payload, it can be resolved to a concrete type by creating a streams.JSONResolver and giving it a callback function that accepts the interesting concrete type:

// Callbacks must be in the form:
//   func(context.Context, <TypeInterface>) error
createCallback := func(c context.Context, create vocab.ActivityStreamsCreate) error {
  // Do something with 'create'
  fmt.Printf("createCallback called: %T\n", create)
  return nil
}
updateCallback := func(c context.Context, update vocab.ActivityStreamsUpdate) error {
  // Do something with 'update'
  fmt.Printf("updateCallback called: %T\n", update)
  return nil
}
jsonResolver, err := streams.NewJSONResolver(createCallback, updateCallback)
if err != nil {
  // Something in the setup was wrong. For example, a callback has an
  // unsupported signature and would never be called
  panic(err)
}
// Create a context, which allows you to pass data opaquely through the
// JSONResolver.
c := context.Background()
// Example 15 of the ActivityStreams specification.
b := []byte(`{
  "@context": "https://www.w3.org/ns/activitystreams",
  "summary": "Sally created a note",
  "type": "Create",
  "actor": {
    "type": "Person",
    "name": "Sally"
  },
  "object": {
    "type": "Note",
    "name": "A Simple Note",
    "content": "This is a simple note"
  }
}`)
var jsonMap map[string]interface{}
if err = json.Unmarshal(b, &jsonMap); err != nil {
  panic(err)
}
// The createCallback function will be called.
err = jsonResolver.Resolve(c, jsonMap)
if err != nil && !streams.IsUnmatchedErr(err) {
  // Something went wrong
  panic(err)
} else if streams.IsUnmatchedErr(err) {
  // Everything went right but the callback didn't match or the ActivityStreams
  // type is one that wasn't code generated.
  fmt.Println("No match: ", err)
}

A streams.TypeResolver is similar but uses the golang types instead. It accepts the generic vocab.Type. This is the abstraction when needing to handle any ActivityStreams type. The function ToType can convert a JSON-decoded-map into this kind of value if needed.

A streams.PredicatedTypeResolver lets you apply a boolean predicate function that acts as a check whether a callback is allowed to be invoked.

FAQ

Why Are Empty Properties Nil And Not Zero-Valued?

Due to implementation design decisions, it would require a lot of plumbing to ensure this would work properly. It would also require allocation of a non-trivial amount of memory.