bluesky-social / atproto

Social networking technology created by Bluesky
Other
7.49k stars 536 forks source link

detectFacets() doesn't add the `did` #834

Closed PatrickHeneise closed 1 year ago

PatrickHeneise commented 1 year ago

https://github.com/zentered/bluesky-post-action/blob/main/src/post.js#L20

Although I'm passing the agent configuration, facets[0].features[0].did is undefined and throws an error in the post validation.

thinkverse commented 1 year ago

Facets support two features, mentions and links, the mentioned user needs to be prefixed with @, otherwise it could be treated as a link. For example, given this post.

const rt = new RichText({
  text: 'thinkverse.dev @thinkverse.dev',
});

await rt.detectFacets(agent)

Which returns the following facets array. If it doesn't find a mention or link it doesn't return anything.

[
  {
    "index": {
      "byteStart": 0,
      "byteEnd": 14
    },
    "features": [
      {
        "$type": "app.bsky.richtext.facet#link",
        "uri": "https://thinkverse.dev"
      }
    ]
  },
  {
    "$type": "app.bsky.richtext.facet",
    "index": {
      "byteStart": 15,
      "byteEnd": 30
    },
    "features": [
      {
        "$type": "app.bsky.richtext.facet#mention",
        "did": "did:plc:ulnarqqnh4qpoh4m4eafyofb"
      }
    ]
  }
]

Which user were you trying to mention that returned an empty did? Could be helpful for the team to debug.

You could also always add mentions and links yourself if you need them to contain custom text that the detection might not find as @aliceisjustplaying atproto starter kit does.

thinkverse commented 1 year ago

Ok, I could reproduce the issue, it's caused by detectFacets setting the did to be an empty string if it cannot resolve the did from the handle. Which I'd consider a bug @pfrazee?

https://github.com/bluesky-social/atproto/blob/c70cb2b6e5a350233d451c3d9a5f6cd5f2c003a4/packages/api/src/rich-text/rich-text.ts#L340-L346

For now, you can use some quick filtering to filter out any potential facets that have features with not set values. Here's a quick and dirty version. 👍

// Automatically detect facets.
await rt.detectFacets(agent);

// Filter out any facets with features 
// that have no value set value.
let facets = null

if (rt.facets) {
  facets = rt.facets
    .filter(facet => {
      const features = facet.features
        .filter(feature =>
          feature?.uri && feature?.uri !== '' ||
          feature?.did && feature?.did !== ''
        );

      return features.length > 0;
    });
}

const postRecord = {
  $type: 'app.bsky.feed.post',
  text: rt.text,
  ...facets && { facets },
  createdAt: new Date().toISOString()
}

Might not be the cleanest but it does pass the validation if no facets where detected, and if there where some found it'll filter out those with no values on their features. And if it happens that you have a single facets with no feature value it'll attach facets with an empty array which again passes validation and posts just fine. 👍

PatrickHeneise commented 1 year ago

Thanks for the workaround and the clarification; wasn't aware exactly what's happening there but that'll help in the future!

Updated the action with the suggested workaround.

chandrn7 commented 11 months ago

Still seeing this behavior with detectFacets. did incorrectly returns as empty string for every handle I've tried.

{'text': 'gobo test @chandrn.bsky.social', 
'createdAt': '2023-12-10T18:13:09.981+00:00', 
'facets': [{'$type': 'app.bsky.richtext.facet', 'index': {'byteStart': 10, 'byteEnd': 30}, 'features': [{'$type': 'app.bsky.richtext.facet#mention', 'did': ''}]}]}