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.
string
This 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.
void
This 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
| void
Configures the DNS over TLS connection that Chrome defaults to using if your DNS provider supports it.
Promise
| void
Some Tcp settings vary based on the Operating System making http requests. Current supports:
windowSize
ttl
Alter the object's values to change session-wide.
Promise
| void
Emulate the ClientHello signature, which can vary between browser versions
Promise
| void
A 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
| void
A 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
| void
Callbacks 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
| void
This 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.
Promise
This 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.
Promise
Callback 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
| void
Use this method if you want to change the speed or randomness of user Interactions (mouse movements, typing, etc).
Promise
This is used within Core to run the mouse Interactions correctly.
Promise