Botmation Documentation

IndexedDB

IndexedDB

These BotAction's interact with the Page's IndexedDB.

Except for the assembling indexedDBStore()(), these BotAction's are BotIndexedDBAction's. They are designed to accept customization through their higher-order params, injects, and even piping.

Higher-order params override all. Piping params override injects. Therefore, injects is a nice way to set the defaults for the majority, then on a case by case basis, can be overrideen by either other way.

IndexedDBStore

This sets the first few injects for BotIndexedDBAction's.

const indexedDBStore = (databaseName: string, storeName: string, databaseVersion?: number) =>
(...actions: BotAction<PipeValue|void>[]): BotAction<any> =>
pipe()(
inject(databaseVersion, databaseName, storeName)(
...actions
)
)

The second call assembles all BotAction's for running in a Pipe with the databaseVersion, databaseName, and storeName injected, in that order.

This is not required, in order to assemble BotIndexedDBAction's. It simply allows you to express those injected values once, for the assembled BotAction's.

For an usage example, see the Instagram isGuest BotAction.

Set IndexedDB Value

This sets a value by key in a Store for a particular Database name and optionally version.

The storeName, databaseName, databaseVersion can be passed through their higher-order params or by injecting. Higher-order params override injected ones.

The key and value can be passed through their higher-order params or by piping. Higher-order params override piped values.

const setIndexedDBValue =
(key?: string, value?: any, storeName?: string, databaseName?: string, databaseVersion?: number): BotIndexedDBAction<void> =>
async(page, ...injects) => {
const [pipedValue, injectDatabaseVersion, injectDatabaseName, injectStoreName] = unpipeInjects<getQueryKeyValue>(injects, 3)
if (!value) {
if (pipedValue) {
if (isObjectWithValue(pipedValue)) {
value = pipedValue.value
} else {
value = pipedValue
}
}
}
if (!key) {
if (isObjectWithKey(pipedValue)) {
key = pipedValue.key
}
}
await page.evaluate(
setIndexedDBStoreValue,
databaseName ? databaseName : injectDatabaseName ? injectDatabaseName : 'missing-db-name',
databaseVersion ? databaseVersion : injectDatabaseVersion ? injectDatabaseVersion : undefined,
storeName ? storeName : injectStoreName ? injectStoreName : 'missing-store',
key ? key : 'missing-key',
value ? value : 'missing-value'
)
}

If a value is missing to complete the operation, a safe missing-* default is used.

For an usage example, see Pipe BotAction.

Get IndexedDB Value

This gets a value by key in a Store for a particular Database name and optionally version.

The storeName, databaseName, databaseVersion can be passed through their higher-order params or by injecting. Higher-order params override injected ones.

The key and value can be passed through their higher-order params or by piping. Higher-order params override piped values.

const getIndexedDBValue =
(key?: string, storeName?: string, databaseName?: string, databaseVersion?: number): BotIndexedDBAction<PipeValue> =>
async(page, ...injects) => {
const [pipeValue, injectDatabaseVersion, injectDatabaseName, injectStoreName] = unpipeInjects<getQueryKey>(injects, 3)
if (!key) {
if (pipeValue) {
if (isObjectWithKey(pipeValue)) {
key = pipeValue.key
} else {
key = pipeValue
}
}
}
return page.evaluate(
getIndexedDBStoreValue,
databaseName ? databaseName : injectDatabaseName ? injectDatabaseName : 'missing-db-name',
databaseVersion ? databaseVersion : injectDatabaseVersion ? injectDatabaseVersion : undefined,
storeName ? storeName : injectStoreName ? injectStoreName : 'missing-store',
key ? key : 'missing-key'
) as PipeValue
}

If a value is missing to complete the operation, a safe missing-* default is used.

For an usage example, see the Instagram isGuest BotAction.

Helpers

In order to interact with IndexedDB in the Puppeteer Page, separate functions need to be "evaluated" in the Page. Therefore, the following Helper functions are setup as if running inside a Browser Page, instead of NodeJS.

If you console.log() in an evaluated Page function, don't look for it in NodeJS's console, but the Puppeteer Page's console.

setIndexedDBStoreValue()

function setIndexedDBStoreValue(databaseName: string, databaseVersion: number, storeName: string, key: string, value: any) {
return new Promise((resolve, reject) => {
const openRequest = indexedDB.open(databaseName, databaseVersion)
openRequest.onerror = function(this: IDBRequest<IDBDatabase>, ev: Event) {
ev.stopPropagation()
return reject(this.error)
}
openRequest.onupgradeneeded = function(this: IDBOpenDBRequest, ev: IDBVersionChangeEvent): any {
if (!this.result.objectStoreNames.contains(storeName)) {
this.result.createObjectStore(storeName)
}
}
openRequest.onsuccess = function(this: IDBRequest<IDBDatabase>, ev: Event) {
const db = this.result
try {
db.transaction(storeName, 'readwrite')
.objectStore(storeName)
.put(value, key)
.onsuccess = function(this, ev) {
db.close()
return resolve()
}
} catch (error) {
db.close()
return reject(error)
}
}
})
}

getIndexedDBStoreValue()

function getIndexedDBStoreValue(databaseName: string, databaseVersion: number, storeName: string, key: string) {
return new Promise((resolve, reject) => {
const openRequest = indexedDB.open(databaseName, databaseVersion)
openRequest.onerror = function(this: IDBRequest<IDBDatabase>, ev: Event) {
return reject(this.error)
}
openRequest.onsuccess = function(this: IDBRequest<IDBDatabase>, ev: Event) {
const db = this.result
try {
const tx = db.transaction(storeName, 'readonly')
.objectStore(storeName)
.get(key)
tx.onsuccess = function(this: IDBRequest<any>, ev: Event) {
const result = this.result
db.close()
return resolve(result)
}
} catch (error) {
db.close()
return reject(error)
}
}
})
}
Edit this page on GitHub
Baby Bot