Core plugins extend SecretAgent's backend functionality at the Core level. These plugins have full control over TCP fingerprinting, header order, HTML rendering, audio codecs and thousands of other variables that allow undetectable emulation of any browser you desire.
Adding a new plugin is as simple as creating a javascript class with the correct properties and methods, then registering it with agent.use().
We recommend using the CorePlugin base class provided by @secret-agent/plugin-utils, which handles setting most of the required properties and methods, everything except the static id property. Here's a simple plugin that adds a single hello() method to agent, which outputs to the browser's console.
import { ClientPlugin, CorePlugin } from '@secret-agent/plugin-utils';
export class ClientHelloPlugin extends ClientPlugin {
static readonly id = 'hello-plugin';
onAgent(agent, sendToCore) {
agent.hello = async (name) => await sendToCore('hello-plugin', name));
}
}
export class CoreHelloPlugin extends CorePlugin {
static readonly id = 'hello-plugin';
onClientCommand({ puppetPage }, name) {
`Hello ${name}`);
}
}As shown above, you can export multiple plugins from the same file. Also a client/core plugin combination can share the same id (unlike two core plugins, which must each have unique ids).
To register this plugin in SecretAgent, just pass it to agent.use(). In the following example we pass through a path to the plugin file instead of the plugin class itself -- we're doing this because by default Core runs in a separate process from Client.
import agent from 'secret-agent';
agent.use(require.resolve('./HelloPlugin'));
await agent.hello('World');The rest of this page documents the various functionalities you can add to your class.
New instance of CorePlugin is created for every agent instance. The createOptions object has three properties.
object Receives the following:UserAgentOption. An object containing various attributes of the chosen userAgent (name, version, etc).BrowserEngine. An instance containing the current BrowserEngine.Plugins. An instance containing the current instance of Plugins attached to this session.BoundLog. An instance of logger you can use to log output.This should usually be set to the plugin's npm package name.
stringThis tells SecretAgent that the plugin is a CorePlugin. It must always be set.
string. This must always be set to 'CorePlugin'.The following methods are optional. Add them to your plugin as needed.
This hook is called during the initialization of a session/browserEmulator as well as every time agent.configure is called from the client.
object Receives any (or none) of the following:Viewport. This is an object containing browser width and height as well as screenWidth and screenHeight, among other properties.Geolocation. This is an object containing longtitude and latitude, among other properties.string. The configured unicode TimezoneId or host default (eg, America/New_York).string. The configured locale in use (eg, en-US).Modify any value in the object to change it session-wide.
voidThis method is called every time a ClientPlugin calls sendToCore to this plugin's ID.
OnClientommandMeta. This object currently has a single property - puppetPage.any[]. Whatever args the ClientPlugin passed through sendToCore.Promise | voidConfigures the DNS over TLS connection that Chrome defaults to using if your DNS provider supports it.
Promise | voidSome Tcp settings vary based on the Operating System making http requests. Current supports:
windowSizettlAlter the object's values to change session-wide.
Promise | voidEmulate the ClientHello signature, which can vary between browser versions
Promise | voidA callback is provided for each HTTP2 Session that is created allowing you to customize the initial SETTINGS and WINDOW_UPDATE frames.
Current Supports
settings. Http2RequestSettings using keys from Node.js settings (https://nodejs.org/api/http2.html#http2_settings_object)localWindowSize. A value to trigger a WINDOW_UPDATE frame with the initial connect.Alter the object's values per Http2 Session.
Promise | voidA callback is provided for each HTTP request where you are given the opportunity to re-order, re-case, and add or remove headers so that they resemble real browser requests. Headless Chrome is known to provide headers is different order on occasion from headed. See https://github.com/ulixee/double-agent for details.
Promise | voidCallbacks on each cookie set, and to return the valid list of cookies. This callback can be used to simulate cookie behavior that varies from the underlying browser - for instance Safari 13.
Promise | voidThis is called every time a new page/iframe is loaded. Use this hook to modify the DOM environment (i.e., to emulate various browser features) before a website loads.
PromiseThis is called every time a new worker is loaded within a page. Use this hook to modify the DOM environment (i.e., to emulate various browser features) before a website loads.
PromiseCallback to indicate a domain has "first-party" interaction. Some browsers, like Safari 13.1, started granting cookie storage to websites only after a user has directly interacted with them.
Promise | voidUse this method if you want to change the speed or randomness of user Interactions (mouse movements, typing, etc).
PromiseThis is used within Core to run the mouse Interactions correctly.
Promise