> For the complete documentation index, see [llms.txt](https://docs.navigaglobal.com/content-agent/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.navigaglobal.com/content-agent/developer/develop-with-content-agent.md).

# Develop with Content Agent

### Getting started

Content Agent gives you methods to use in your plugin such as `opencontent` to be able to do search/suggest requests from OpenContent by passing your search query for example!

Content Agent register it's own methods with [Dashboard Actions](https://docs.navigaglobal.com/dashboard-plugin/components/agent/actions)

You can use any of these actions in your plugin.

### Available actions

| ID                                    | Descriptions                                                                                                 |
| ------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| com.naviga.content-agent:getProviders | An action to return all available provider names (from config)                                               |
| com.naviga.content-agent:getInstance  | An action returns the instance of content agent with Opencontent, Querystreamer, Infocaster and CCA methods. |

####

#### With getInstance action you will get an object that has four main instances:

* **opencontent**:
  * search -  *promise request.*
  * request -  *promise request*
  * suggest -  *promise request*
* **querystreamer**
  * activeStreams
  * createStream
  * deleteStream
* **infocaster**
  * activeSubscriptions
  * broadcast
  * subscribe
  * unsubscribe
* **cca**
  * Tools
    * ConvertToNewsml
    * ConvertToDocument
  * Files
    * GetStatus
    * GetArtifact
    * GetDownloadStatus
    * CreateUpload
    * CreateDownload
  * NewsML
    * GetNewsMLDocument
    * WriteNewsMLDocument
    * DeleteNewsMLDocument
    * NewsMLDocumentExists
  * Documents
    * GetDocument
    * WriteDocument
    * DeleteDocument
    * DocumentExists

### An example to how to get Content Agent instance

In your plugin you can import **getAction** from Plugin, so you can "import" Content Agent actions to your plugin.

{% tabs %}
{% tab title="Hook component" %}

```jsx
import { useRef, useState, useEffect } from 'react'
import { Plugin } from '@root'

const { getAction } = Plugin

const MyAwesomeComponent = props => {
    const CA = useRef()

    const [ready, setReady] = useState(false)
    
    useEffect(() => {
        const getInstance = getAction('com.naviga.content-agent:getInstance')
        const Instance = getInstance()
        
        CA.current = new Instance({
            onStatusChange: caReady => {
                setReady(caReady)
            }
        })
    }, [])
}
```

{% endtab %}

{% tab title="Class component" %}

```jsx
import { Component } from 'react'
import { Plugin } from '@root'

const { getAction } = Plugin

class MyAwesomeComponent extends Component {
    constructor(props) {
        super(props)
        
        this.CA = null
        
        this.state = {
            ready: false
        }
    }
    
    componentDidMount() {
        const getInstance = getAction('com.naviga.content-agent:getInstance')
        const Instance = getInstance()
        
        this.CA = new Instance({
            onStatusChange: caReady => {
                this.setState({
                    ready: caReady
                })
            }
        })
    }
}
```

{% endtab %}
{% endtabs %}

Here we used `com.naviga.content-agent:getInstance` action to get and initiate our CA instance, and listening on CA status changes with `onStatusChange`&#x20;

### Open Content

To access Open Content you call `CA.opencontent()` with the name of content provider you want to use (from config).

Access to `search` and `suggest` is simplified by two helper functions, but any OC REST API endpoint can be reached using the `request` function. The functions returns promises.

Open Content API Documentation can be found at \
url-to-open-content-server:8080/opencontent/apidocs/

#### Search

```javascript
const searchQuery = {
    q: "*:*"
}

CA.opencontent('im-demo').search(searchQuery).then(searchResult => {
    console.log(searchResult)
})
```

#### Suggest

```javascript
const suggestQuery = {
    'field': ['Authors'],
    'incompleteWord': ['P'],
    'type': 'ngram'
}

CA.opencontent('im-demo').suggest(suggestQuery).then(suggestResult => {
    console.log(suggestResult)
})
```

#### Generic OC API request

```javascript
const params = {
    'endpoint': 'eventlog',
    'method': 'GET',
    'qs': {
      'event' : -1
    }
}

CA.opencontent('im-demo').request(params).then(eventlogRes => {
    console.log(eventlogRes)
})
```

{% hint style="info" %}
search, suggest and request actions works the same as accessing them from CA.opencontent

by passing the provider as first argument and the request params as a second argument
{% endhint %}

### QueryStreamer

To handle streams in QueryStreamer you call `CA.querystreamer()` with the name of content provider you want to use (from config).

createStream and deleteStream is enabled on this instance.

[QueryStreamer API Documentation](https://querystreamer.lcc.infomaker.io/documentation)

[ElasticSearch Query Format Documentation](https://www.elastic.co/guide/en/elasticsearch/reference/current/_introducing_the_query_language.html)

#### Create stream

When calling create stream, pass a request object and a callback function as parameters. This will return a promise that resolves with a stream ID. New events will land in the callback function you provided.

```javascript
const BUNDLE = "@plugin_bundle";
const VERSION = "@plugin_version";

const onStreamEvent = (event) => {
    const ocEvent = event.data.payload.result
    const noLongerMatching = event.data.payload.parameters.noLongerMatchingQuery
}

const req = {
    query : {
        query_string: {
            query : '*:*'
        }
    },
    config : {
        'notifyOnNoLongerMatchingQuery' : true
    },
    meta : {
        origin : {  // Add bundle and version to meta.origin. This helps when troubleshooting.
            bundle : BUNDLE,
            version : VERSION
        }
    }
}

const querystreamer = this.lcc.querystreamer('im-demo')
const updateStreamId = res => {
    // This will be called when a stream resumes after a disconnect as well
    // as initially with a temporary streamId in order to be able to clean up
    // if connection is broken before stream is fully setup
    this.streamId = res.streamId
}

return querystreamer.createStream(req, onStreamEvent, updateStreamId).then(res => {
    this.streamId = res.streamId
})
```

#### Delete stream

```javascript
CA.querystreamer('im-demo').deleteStream(STREAM_ID)
```

#### Cleanup

When a stream is no longer needed, **delete** it.

Please don't forget call `deleteStream(streamId)`&#x20;

* If you are creating a stream in a class component you can delete the stream when your component unmounted with `componentWillUnmount`.
* If you are creating a stream in a hook component you can delete the stream when your component unmounted with returning a function with `useEffect`&#x20;
* If you are creating a stream in the Agent you can delete the stream when your Agent close with `close`&#x20;

{% hint style="info" %}
You can handle events easily with querystreamer by passing qsInstance to [QueryEventWrapper](https://github.com/Infomaker/Dashboard-Plugin/wiki/ViewUtil#queryeventwrapper)
{% endhint %}

###

### Content Creation API (CCA)

In order to communicate with the Content Creation API you'll need to have added the [baseUrl to the cca part in the configuration](/content-agent/admin/config.md#example-using-cca-integration) as well as added [valid client credentials.](/content-agent/admin/config.md#example-using-client-credentials)

When this is done you're free to utilise the Content Creation API and the different endpoints, which you can read more about [here](https://docs.navigaglobal.com/cca-api-documentation/api).

```javascript
/**
*    A basic example of utilising CCA GetDocument
*/

const CCA = CA.cca('content-provider')

const document = await CCA.Documents.GetDocument({
    UUID: '1f672ac4-86ff-4a34-a264-80f26324be09'
})
```
