# Advanced Workflows

## Annoto application container

Annoto widget [position](https://developer.mozilla.org/en-US/docs/Web/CSS/position) is set as `absolute` meaning it doesn't influence the website layout. By default the application is contained inside a single DIV that is appended to the BODY.

If you require different behavior, you can put the following DIV anywhere in your DOM:

```markup
<div id="annoto-app"></div>
```

Once this DIV element is present in the DOM, when Annoto.boot() is called, it would be detected automatically by Annoto and serve as container for the Annoto app.

This is especially useful if BODY is not your main scrollable layout.

{% hint style="success" %}
As a rule of thumb always place the container in the same scrollable element as your video.
{% endhint %}

## Custom Widget Fab Button

When the Annoto widget is closed a small Fab button with comments icon is positioned next to the player to allow users to open the widget.

In some cases you might want to implement your own open/close UI and functionality.

To hide the default Fab button set the [fabDisable Ux property](https://annoto.github.io/widget-api/interfaces/config_ux.IWidgetUx.html#fabDisable) to true:

```javascript
var config = {
    ux: {
      widget: {
        fabDisable: true
      }
    }
    // ...
  };

```

{% hint style="info" %}
To show/hide the widget, use the [IAnnotoApi show() and hide() methods](https://annoto.github.io/widget-api/interfaces/Api.IAnnotoApi.html). For more details on how to obtain the api object please refer to [Using the API](https://docs.annoto.net/developers/widget/getting-started#using-the-api).
{% endhint %}

## Annoto Timeline

Annoto Timeline allows users to spot points of interest. The timeline can be embedded in the player or it can be positioned below the player. Lets explore the timeline configuration options:

By default, the timeline will be positioned under the player:

![](/files/-LRv-TV4O54b0oJ9bfHM)

If [overlay](https://annoto.github.io/widget-api/interfaces/config_timeline.ITimelineConfig.html#overlay) is true, the timeline will be positioned inside the controls of the player:

```javascript
timeline: {
    overlay: true
}
```

![](/files/-LRuzqPiUZxQL5aJThO_)

## LTI Outcomes

Annoto supports reporting grading to LMS (Learning Management System) using the [IMS LTI 1.3 AGS](https://www.imsglobal.org/spec/lti-ags/v2p0).

If Annoto is integrated in a 3d party system that is taking the role of LTI Tool that processes the LTI messaging requests, Annoto still supports taking care of managing the outcomes reporting.

The above setup requires the below configurations.

{% hint style="success" %}
Once setup, Annoto backend services will take care of always keeping the grades up to date, including retries (in case of LMS rate limiting).
{% endhint %}

### LTI Outcomes Webhook Integration

{% hint style="info" %}
For Backend Webhook setup please refer to [Webhook integration](/developers/integrations/webhook.md) for details.
{% endhint %}

### LTI Resource Link Request AGS Claim Forwarding

During `LtiResourceLinkRequest` the LMS (Platform) provides the following claims:

```
https://purl.imsglobal.org/spec/lti-ags/claim/endpoint
https://purl.imsglobal.org/spec/lti/claim/resource_link
```

Those claims need to be provided to the [mediaDetails of the widget](https://annoto.github.io/widget-api/interfaces/config_media_details.IMediaDetails.html#outcomes):&#x20;

{% tabs %}
{% tab title="Example Configuration" %}

```typescript
const annotoConfig: IConfig = {
  hooks: {
    mediaDetails: () => {
      return {
        outcomes: {
          clientId: "7f84098a3f85",
          integrationKey: 'U0N7wvTXdXTIx3A204tWg',
          lti: {
              userId: 'abc123',
              resourceLinkId: 'xyz321',
              claim: {
                  lineitems: 'https://example.lms.site/48c52e65-5fb9-4099-9b2e',
                  scope: [
                      'https://purl.imsglobal.org/spec/lti-ags/scope/lineitem',
                      'https://purl.imsglobal.org/spec/lti-ags/scope/lineitem.readonly',
                      'https://purl.imsglobal.org/spec/lti-ags/scope/score',
                      'https://purl.imsglobal.org/spec/lti-ags/scope/result.readonly',
                  ],
              },
          },
        },
        title: 'Quick Start',
        // id: '7245-asfa', // (optional) unique media identifier
        // description: 'Quick start for setup on custom platform', // (optional)
      };
    }
  },
  // rest of the widget configuration
};
```

{% endtab %}

{% tab title="Media details Outcomes Interface" %}

```typescript
export interface IOutcomes {
  /**
   * integration key provided by Annoto during setup
   * required if lti object is provided
   */
  integrationKey?: string;
  /**
   * LTI outcomes parameters provided by the platform during launch
   */
  lti?: ILtiAGSOutcome;
  /**
   * if set to true, outcome passback support is expected for the activity, and if not
   * present via this config (or other means), a warning to user will be shown
   * notifying of potential issue with passing back grades to 3d party platform (such as LMS)
   * @default true
   */
  isExpected?: boolean;
}

export interface ILtiAGSOutcome {
  /**
   * Tool deployment client_id
   * If provided will be forwarded in the Webhook outcome messages
   */
  clientId?: string;
  /**
   * The userId MUST be present and MUST be the same as the resource link LTI parameter 'user_id'.
   */
  userId: string;
  /**
   * id of the https://purl.imsglobal.org/spec/lti/claim/resource_link claim
   */
  resourceLinkId: string;
  /**
  * This claim is included in LTI messages if any of the
  * Assignment and Grade Services are accessible by the tool in the context of the LTI message.
  * https://www.imsglobal.org/spec/lti-ags/v2p0#assignment-and-grade-service-claim
  */
  claim: {
    /**
    * the endpoint URL for accessing the line item container for the current context.
    */
    lineitems: string;
    /**
     * when an LTI message is launching a resource associated to one and only one lineitem,
     * the claim must include the endpoint URL for accessing the associated line item;
     * in all other cases, this property must be either blank or not included in the claim.
     */
    lineitem?: string;
    /**
     * An array of scopes the tool may ask an access token for.
     */
    scope?: LtiAGSScopeType[];
  }
}
```

{% endtab %}
{% endtabs %}

{% hint style="success" %}
`integrationKey` is provided by Annoto during setup.
{% endhint %}

## Custom Video Player

Annoto providers ends users, advanced interaction with video content. In order to do it Annoto requires access to video player API. Before Annoto can perform any action it must obtain the media source and the duration of the media.

We already support a variety of widely used player types, and constantly adding new ones. If you are using a custom player or player we don't support yet, you have 2 options:

1. Implement a [PlayerAdaptorApi](https://annoto.github.io/widget-api/interfaces/PlayerAdaptor.IPlayerAdaptorApi.html) and set it in [Widget's player configuration](https://annoto.github.io/widget-api/interfaces/config_widget.IPlayerConfig.html#adaptorApi). Contributions are very welcome and appreciated :)
2. [Contact us](https://annoto.net), we are happy to help.

## Analytics Events

Annoto widget exposes api to subscribe to analytics events so that can be used in custom integrations, for example ingested and analyzed by custom BI systems.

To listen to the events use the familiar [Annoto.on()](https://annoto.github.io/widget-api/interfaces/Annoto.Annoto-1.html#on) api.

The widget provides two types of events:

### Stats Events

Discrete events of user actions such as submit a comment, vote, read a reply, click on timestamp, first video play, etc.

```javascript
Annoto.on('stats_events', function (ev) {
    console.log(ev);
});
```

For more details on the event callback please refer to the [AnnotoStatsEventCallback](https://annoto.github.io/widget-api/modules/Annoto.html#AnnotoStatsEventCallback) interface. For full list of event types, please refer to [StatsTypeEnum](https://annoto.github.io/widget-api/enums/events_stats_event.StatsTypeEnum.html).

### Video Benchmark Events

Video analytics events that provides details about the current and historical accumulated video consumption of the user.

```javascript
Annoto.on('video_benchmark', function (ev) {
    console.log(ev);
});
```

For more details on the event callback please refer to the [AnnotoVideoBenchmarkCallback](https://annoto.github.io/widget-api/modules/Annoto.html#AnnotoVideoBenchmarkCallback) definition.

### Interactions Stats Events

Interactions events of user actions that provide details about interactions consumed and the results of the activity.

```
Annoto.on('cta_stats_events', function (ev) {
    console.log(ev);
});
```

For more details on the event callback please refer to the [AnnotoCtaStatsEventCallback](https://annoto.github.io/widget-api/modules/Annoto.html#AnnotoCtaStatsEventCallback) definition.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.annoto.net/developers/widget/advanced-workflows.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
