Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Javascript library for logging events for Querymon (https://querymon.com) search product analytics.
If you are working in a Javascript environment, either frontend or backend, you can use the vanilla JS module in NPM. The module should work in any environment or framework due to its simplicity. The library has a single dependency, uuid
, is extremely simple and is designed to be a very light wrapper around the Querymon API.
📘 You can find a full demo app with the integration on Github
Note that the above shows a search-as-type implementation with all appropriate Querymon tracking implemented. All below sample code is pulled from this demo application.
The Javascript SDK should work in any environment, and can be added quickly from NPM.
npm install querymon
yarn add querymon
Initializing the SDK is simple, but needs to be done in a location that will persist the instance of Querymon throughout the lifecycle of search, returning results and clicking. It should NOT re-instantiate mid cycle.
Below is a sample of initializing the SDK in App.js of a simple React app.
// Once added via NPM
import { Querymon } from 'querymon';
/* @param {object} configuration
* REQUIRED @param {string} configuration.searchInterfaceKey - The Search Interface Key
* OPTIONAL @param {integer} configuration.debounceTime - The debounce time in ms for the search, defaults to 1000ms
* OPTIONAL @param {string} configuration.userId - The userId to log for all events. If not provided, a random uuid will be generated
*/
const querymon = new Querymon({
searchInterfaceKey: 'Your API key from https://app.querymon.com/search',
userId: 'the persistent user ID to tie conversions, and do other reporting like cohorts'
});
export default function MyApp() {
// Your application code
Note that for convenience, you can pass the userId
here a single time, and it will automatically be appended to all future requests. If inconvenient, you can always pass the userId
along with each request below.
The most basic logging can happen with a simple call to logSearch
with the user query as show below.
// Register query with Querymon. Async fire and forget
querymon.logSearch('search query here');
If you need further customization, such as analytics tagging and segmentation, to pass the user ID or override the timestamp that the query occurred, you can pass these parameters via the options object.
/* Method to log search query
* REQUIRED @param {string} query - The search query
* OPTIONAL @param {object} options - An object of optional parameters
* OPTIONAL @param {list of strings} options.metadata - An array of up to 4 strings to categorize the search query
* OPTIONAL @param {string} options.userId - The userId to log for all events to override the userId provided in the constructor
* OPTIONAL @param {int} options.queryTime - The time the query began (ms since 1970), defaults to the time of method invocation
*/
querymon.logSearch('search query here', {
metadata: ['variant A', 'split C'],
userId: 'user 1234',
queryTime: 1695674081849
});
When the results are returned from the query, you can pass them to the result logging method call as shown below. Be careful to mind the format of the result objects.
// Register results with Querymon. Fire and forget.
querymon.logResults('search query here', yourResults.map((item, index) => {
return {
entityId: item.id,
name: item.name,
description: item.description,
url: item.url,
index: index
};
}));
You also have the ability to specify the userId
and pass a specific timestamp if being logged later. Full example below:
/* Method to log results that were returned
* REQUIRED @param {string} query - The search query
* REQUIRED @param {list} results - The list of the results returned from the search engine
* Example format: [{index: row number integer, entityId: 'identifier for the result', name: 'name of result string', description: 'short description of the result', url: 'url for result'}]
* OPTIONAL @param {object} options - An object of optional parameters
* OPTIONAL @param {string} options.userId - The userId to log for all events to override the userId provided in the constructor
* OPTIONAL @param {int} options.resultReturnTime - The time the results were returned (ms since 1970), defaults to the time of method invocation
*/
querymon.logResults('search query here', yourResults.map((item, index) => {
return {
entityId: item.id,
name: item.name,
description: item.description,
url: item.url,
index: index
};
}), {
userId: 'user 1234',
resultReturnTime: 1695674081849
});
After you return the results to the user, if the user selects one of the results, you can log the click on the results with the following method.
The simplest version just logs the result row and name for matching.
// Register interaction with Querymon
querymon.logClick('search query here', result.index, result.name);
Again, you also have the ability to pass further parameters to specify the userId
or interaction time if logging later than the actual event.
/* Method to log clicks on results
* REQUIRED @param {string} query - The search query
* REQUIRED @param {int} resultRow - The row for the result that was clicked
* REQUIRED @param {string} resultName - The name of the result that was clicked
* OPTIONAL @param {object} options - An object of optional parameters
* OPTIONAL @param {string} options.userId - The userId to log for all events to override the userId provided in the constructor
* OPTIONAL @param {int} options.interactionTime - The time the result was clicked (ms since 1970), defaults to the time of method invocation
*/
querymon.logClick('search query here', result.index, result.name, {
userId: 'user 1234',
interactionTime: 1695674081849
});
Presumably this will happen later, on a different page from the search experience. Because of that, there is no need to pass the search query. Please do ensure to use the same searchInterfaceKey
as used before to map the conversion data back to you search interface.
// Register conversion event with Querymon
querymon.logConversion('purchase');
Again, you also have the ability to pass further parameters to specify the userId
or event time if logging the event later. We also recommend that you pass the eventValue
in cents to track revenue attribution.
/* Method to log a conversion event tied to the specific search interface
* REQUIRED @param {string} eventName - The name of the conversion event
* OPTIONAL @param {object} options - An object of optional parameters
* OPTIONAL @param {string} options.eventValue - The value of the conversion event, in cents. No decimals.
* OPTIONAL @param {string} options.userId - The userId to log for all events to override the userId provided in the constructor
* OPTIONAL @param {int} options.eventTime - The time the conversion event occurred (ms since 1970), defaults to the time of method invocation
*/
querymon.logConversion('purchase', {
eventValue: 999,
userId: 'user 1234',
eventTime: 1695674081849
});
FAQs
Javascript library for logging events for Querymon (https://querymon.com) search product analytics.
We found that querymon demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.