Browser
This Aptitude, combined with the Olive Helps browser extension, allows an author to interact with your browser.
This Aptitude only works if you have the Olive Helps browser extension installed. Currently, we have extensions for Chrome, Firefox, and Edge.
Please note: Microsoft Edge operates as a Chrome plugin.
These documents will reference frameId and parentFrameId - for more information on frames, check out the Chrome Extension Docs here.
API
Example
Permissions

listenNavigation

Calls callback on any navigation event pushed from a browser running the Olive Helps extension.
1
import { browser } from '@oliveai/ldk';
2
3
const URL_TO_OPEN = 'https://www.oliveai.dev/';
4
const newTabId = await browser.openTab(URL_TO_OPEN);
5
6
const browserListener = await browser.listenNavigation((navDetails) => {
7
/*
8
navDetails will be:
9
{
10
frameId: number,
11
navigationType: string (real | history)
12
parentFrameId: number,
13
tabId: number,
14
timestamp: number,
15
url: string
16
}
17
*/
18
19
// navDetails.url === URL_TO_OPEN: true
20
// navDetails.tabId === newTabId: true
21
22
// Cancel the listener when a specific URL is opened by the user
23
if (navDetails.url === URL_TO_OPEN) {
24
browserListener.cancel();
25
}
26
})
Copied!

listenTextSelection

Calls callback on any text selection event pushed from a browser running the Olive Helps extension.
1
import { browser } from '@oliveai/ldk';
2
3
const browserTextListener = await browser.listenTextSelection((value) => {
4
// Cancel the listener when a specific string is selected in the browser
5
const TEXT_WE_NEED = 'The quick brown fox jumped';
6
if (value === TEXT_WE_NEED) {
7
browserTextListener.cancel();
8
}
9
}
Copied!

listenNetworkActivity

Listens for any network activity by the browser. The resulting callback for the listener takes in an activity event with the following structure.
1
export interface NetworkActivityDetails {
2
tabId: number; // Which tab the activity originated from
3
requestUrl: string; // The url for fetching data
4
method: string; // The HTTP method used in the request
5
requestBody: null | string; // Null or a string of the request payload
6
domain: string; // The originating url
7
}
8
Copied!
1
import { browser } from '@oliveai/ldk';
2
3
const networkActivityListener= await browser.listenNetworkActivity((event) => {
4
console.log(JSON.stringify(event)); // This will produce the structure above
5
networkActivityListener.cancel();
6
}
Copied!

openTab

Opens a tab in the browser running the Olive Helps extension.
1
import { browser } from '@oliveai/ldk';
2
3
const URL_TO_OPEN = 'https://www.oliveai.dev/';
4
5
// This will open a new tab in your browser, and return the new tab's ID
6
const newTabId = await browser.openTab(URL_TO_OPEN);
7
8
// This will open a new tab in your browser and return both the tab id and the source html for the page
9
const {id, sourceHTML}= await browser.openTab(URL_TO_OPEN, {includeSouce: true});
Copied!

openWindow

Opens a window in the browser running the Olive Helps extension.
1
import { browser } from '@oliveai/ldk';
2
3
const URL_TO_OPEN = 'https://www.oliveai.dev/';
4
5
// This will open a new window in your browser, and return the new window's ID
6
const newWindowId = await browser.openWindow(URL_TO_OPEN);
7
8
// This will open a new window in your browser, and return the new windows id and the source html for the page
9
const {id, sourceHTML} = await browser.openWindow(URL_TO_OPEN, { includeSource: true});
Copied!

sourceHTML

Retrieves the html source for a given address.
1
import { browser } from '@oliveai/ldk';
2
const URL_TO_READ = 'https://www.oliveai.dev/';
3
const { id, sourceHTML } = await browser.sourceHTML(URL_TO_READ);
Copied!

listenTabChange

Listen for tab change event within the browser. The resulting callback for the listener takes in an TabChangeDetails event with the following structure:
1
export interface TabChangeDetails {
2
tabId: number;
3
title: string;
4
url: string;
5
windowId: number;
6
}
Copied!
1
import { browser } from '@oliveai/ldk';
2
3
(async () => {
4
const cancellable = await browser.listenTabChange((tabDetails) => {
5
if (tabDetails.title === 'Olive Developers Hub') {
6
cancellable.cancel();
7
}
8
});
9
})();
Copied!

listenUIElement

Attaches to an event listener for a single or set of elements for a specific webpage.
1
import { browser } from '@oliveai/ldk';
2
3
const cancellable = await browser.listenUIElement(
4
{
5
address: 'https://oliveai.dev',
6
selector: '#frameId',//
7
listenerType: 'click' | 'input' // optional, will default to click
8
},
9
(details) => {
10
const { tabId, title, url, windowId } = details;
11
if (tabId === 1541 && title === 'Olive Developer Hub') {
12
cancellable.cancel();
13
}
14
});
Copied!
In this example, let's assume we have a Whisper with a button, this instructs you to click the button in order to open a browser window that automatically navigates to your profile page for your insurance provider. And after doing so, you'll instructed to select the insurance ID and group ID.
1
import { browser } from '@oliveai/ldk';
2
3
export async function getInsuranceInfo() {
4
// Assume we know the 9-digit ID will be on the page as 'ID: 123456789'
5
// and the 8-digit group as 'Group: 12345678'
6
const ID_SELECTION_PATTERN = /ID: .{9}/g
7
const GROUP_SELECTION_PATTERN = /Group: .{8}/g
8
const CIGNA_USER_PROFILE_URL = 'https://my.cigna.com'
9
10
await browser.openWindow(CIGNA_USER_PROFILE_URL);
11
12
let insuranceId;
13
let insuranceGroup;
14
15
const browserListener = await browser.listenTextSelection(value => {
16
const idMatches = value.match(ID_SELECTION_PATTERN);
17
const groupMatches = value.match(GROUP_SELECTION_PATTERN);
18
19
// If there is a match, assign the variable
20
if (idMatches) insuranceId = idMatches[0];
21
if (groupMatches) insuranceGroup = groupMatches[0];
22
23
// If insuranceId and insuranceGroup are defined, we can close
24
// the listener and continue with the rest of the logic of our loop
25
if (insuranceId && insuranceGroup) {
26
browserListener.cancel();
27
// Create/update whispers or execute other logic here
28
// using the ID and Group
29
}
30
}
31
}
Copied!
To use the Browser aptitude, you will need to specify which domains your Loop will be using in your package.json under the ldk object like shown below. If you do not specify a domain your Loop attempts to access, Olive Helps will reject the request. This is done to ensure you feel confident that a Loop isn't sending or getting information to something unexpected.
The URLs you add will need to include a path suffix /*
1
...
2
"ldk": {
3
"permissions":
4
{
5
"browser": {
6
"urlDomains": [
7
{
8
"value": "*.fda.gov", // Allows any subdomain of fda.gov, but
9
}, // not any path
10
{
11
"value": "*.fda.gov/*", // Allows any subdomain and path of fda.gov
12
},
13
...
14
],
15
},
16
}
17
},
18
...
Copied!
API
Example
Permissions

listenNavigation

Calls callback on any navigation event pushed from a browser running the Olive Helps extension.
1
import { browser } from '@oliveai/ldk';
2
3
const URL_TO_OPEN = 'https://www.oliveai.dev/';
4
const newTabId = await browser.openTab(URL_TO_OPEN);
5
6
const browserListener = await browser.listenNavigation((navDetails) => {
7
/*
8
navDetails will be:
9
{
10
frameId: number,
11
navigationType: string (real | history)
12
parentFrameId: number,
13
tabId: number,
14
timestamp: number,
15
url: string
16
}
17
*/
18
19
// navDetails.url === URL_TO_OPEN: true
20
// navDetails.tabId === newTabId: true
21
22
// Cancel the listener when a specific URL is opened by the user
23
if (navDetails.url === URL_TO_OPEN) {
24
browserListener.cancel();
25
}
26
})
Copied!

listenTextSelection

Calls callback on any text selection event pushed from a browser running the Olive Helps extension.
1
import { browser } from '@oliveai/ldk';
2
3
const browserTextListener = await browser.listenTextSelection((value) => {
4
// Cancel the listener when a specific string is selected in the browser
5
const TEXT_WE_NEED = 'The quick brown fox jumped';
6
if (value === TEXT_WE_NEED) {
7
browserTextListener.cancel();
8
}
9
}
Copied!

listenNetworkActivity

Listens for any network activity by the browser. The resulting callback for the listener takes in an activity event with the following structure.
1
export interface NetworkActivityDetails {
2
tabId: number; // Which tab the activity originated from
3
requestUrl: string; // The url for fetching data
4
method: string; // The HTTP method used in the request
5
requestBody: null | string; // Null or a string of the request payload
6
domain: string; // The originating url
7
}
8
Copied!
1
import { browser } from '@oliveai/ldk';
2
3
const networkActivityListener= await browser.listenNetworkActivity((event) => {
4
console.log(JSON.stringify(event)); // This will produce the structure above
5
networkActivityListener.cancel();
6
}
Copied!

openTab

Opens a tab in the browser running the Olive Helps extension.
1
import { browser } from '@oliveai/ldk';
2
3
const URL_TO_OPEN = 'https://www.oliveai.dev/';
4
5
// This will open a new tab in your browser, and return the new tab's ID
6
const newTabId = await browser.openTab(URL_TO_OPEN);
7
8
// This will open a new tab in your browser and return both the tab id and the source html for the page
9
const {id, sourceHTML}= await browser.openTab(URL_TO_OPEN, {includeSouce: true});
Copied!

openWindow

Opens a window in the browser running the Olive Helps extension.
1
import { browser } from '@oliveai/ldk';
2
3
const URL_TO_OPEN = 'https://www.oliveai.dev/';
4
5
// This will open a new window in your browser, and return the new window's ID
6
const newWindowId = await browser.openWindow(URL_TO_OPEN);
7
8
// This will open a new window in your browser, and return the new windows id and the source html for the page
9
const {id, sourceHTML} = await browser.openWindow(URL_TO_OPEN, { includeSource: true});
Copied!

sourceHTML

Retrieves the html source for a given address.
1
import { browser } from '@oliveai/ldk';
2
const URL_TO_READ = 'https://www.oliveai.dev/';
3
const { id, sourceHTML } = await browser.sourceHTML(URL_TO_READ);
Copied!
In this example, let's assume we have a Whisper with a button, this instructs you to click the button in order to open a browser window that automatically navigates to your profile page for your insurance provider. And after doing so, you'll instructed to select the insurance ID and group ID.
1
import { browser } from '@oliveai/ldk';
2
3
export async function getInsuranceInfo() {
4
// Assume we know the 9-digit ID will be on the page as 'ID: 123456789'
5
// and the 8-digit group as 'Group: 12345678'
6
const ID_SELECTION_PATTERN = /ID: .{9}/g
7
const GROUP_SELECTION_PATTERN = /Group: .{8}/g
8
const CIGNA_USER_PROFILE_URL = 'https://my.cigna.com'
9
10
await browser.openWindow(CIGNA_USER_PROFILE_URL);
11
12
let insuranceId;
13
let insuranceGroup;
14
15
const browserListener = await browser.listenTextSelection(value => {
16
const idMatches = value.match(ID_SELECTION_PATTERN);
17
const groupMatches = value.match(GROUP_SELECTION_PATTERN);
18
19
// If there is a match, assign the variable
20
if (idMatches) insuranceId = idMatches[0];
21
if (groupMatches) insuranceGroup = groupMatches[0];
22
23
// If insuranceId and insuranceGroup are defined, we can close
24
// the listener and continue with the rest of the logic of our loop
25
if (insuranceId && insuranceGroup) {
26
browserListener.cancel();
27
// Create/update whispers or execute other logic here
28
// using the ID and Group
29
}
30
})
31
}
Copied!
To use the Browser aptitude, you will need to specify which domains your Loop will be using in your package.json under the ldk object like shown below. If you do not specify a domain your Loop attempts to access, Olive Helps will reject the request. This is done to ensure you feel confident that a Loop isn't sending or getting information to something unexpected.
The URLs you add will need to include a path suffix /*
1
...
2
"ldk": {
3
"permissions":
4
{
5
"browser": {
6
"urlDomains": [
7
{
8
"value": "*.fda.gov", // Allows any subdomain of fda.gov, but
9
}, // not any path
10
{
11
"value": "*.fda.gov/*", // Allows any subdomain and path of fda.gov
12
},
13
...
14
]
15
},
16
...
17
}
18
},
19
...
Copied!
Copy link