Confused by the smart links module documentation

I have several questions:

  • The atlassian:remote-link used in the tutorial example app doesn’t appear documented on the object type documentation
  • Making guesses from the tutorial app:
    • Should I generate a new entity id for every request?
    • Is there a format for the ids ? Should it be parseable as a number?
  • The module documentation mentions "Smart Links retrieve information from third-party apps in real time as the link is rendered", but it appears that there is some kind of cache, as not every page refresh triggers a call to the forge resolveSmartLinks function.
  • I’m unclear as to what the entities[i].meta values are doing: changing the access and visibility to restricted and forbidden doesn’t appear to affect the smart link card displayed at all.

My use case should be pretty simple:

  • A user inserts a link https://app.requirementyogi.com?requirement=<entityId>
  • I parse the link for the entity, and retrieve informations about the entity via a remote api call if the user has the authorizations needed to see the object
  • I display the information in the smart link card.

But I’m getting stuck at the start, simply changing the id seems to completely break the rendering:
Here is the output in a Confluence page: The tutorial app renders the thumbnail, displayName and description, but not my other app.

#manifest.yml

app:
  #...
  
  # Allow cross-app modules. Necessary to access the graph API for Smart Links.
  compatibility:
    confluence:
      required: true
    jira:
      required: false


modules:
# ...
  graph:smartLink:
    - key: ry-smartlink
      icon: resource:media;logo.svg
      name: Requirement Yogi
      function: getEntityByUrlFn
      domains:
        - app.requirementyogi.com
      subdomains: true
      patterns:
        - '^https:\/\/app\.requirementyogi\.com\/.*'
// resolver.ts extract. Other functions are the same as the tutorial app.
async function processUrl(url: string): Promise<ResolveUrlEntityResult> {
    const parsed = new URL(url);

    const reqKey = parsed.searchParams.get("reqKey");
    const spaceKey = parsed.searchParams.get("spaceKey");
    const variantId = parsed.searchParams.get("variantId");

    const id = `${spaceKey}/${variantId}/${reqKey}`;

    return {
        identifier: {
            url: url,
        },
        meta: {
            access: "granted",
            visibility: "public",
        },
        entity: {
            schemaVersion: "2.0",
            id: id,
            updateSequenceNumber: 222,
            displayName: `Hello World ${id}!`,
            description: `Well done you ! ${id}`,
            url,
            "atlassian:remote-link": {
                type: "document",
            },
            createdAt: new Date().toISOString(),
            lastUpdatedAt: new Date().toISOString(),
            thumbnail: {
                externalUrl: `https://picsum.photos/200`,
            },
            createdBy: {
                accountId: "6076c075c642ff0070ef3787",
            },
        },
    };
}

Hi Corentin,

atlassian:remote-link is a legitimate value rather than a tutorial artefact. The shipped @forge/manifest schema enumerates 28 object types for a connector’s objectTypes, and it sits in that list next to atlassian:document, atlassian:work-item and atlassian:repository. The tutorial is not using something undocumented.

The object types page may look empty to you for a mechanical reason. Its list is rendered client-side and no identifier appears in the served HTML at all, so anything scripted against that page finds nothing either.

Your ids are a different matter, and here I can only give you a negative. The manifest schema constrains nothing about them. Its one entities key belongs to app.storage, which is Forge SQL and has no relationship to what your resolver returns. Whatever governs id format or reuse lives in the runtime, and reading the schema will not settle it.

I have not reproduced the caching or the meta behaviour you describe, and I can’t tell you what the resolver does with a changed id.

Has anyone had the id constraints confirmed, or is everyone still guessing from the tutorial?