smartshopping-sdk
v0.7.0
Published
Coupon autoapply SDK
Downloads
268
Maintainers
Readme
SmartShopping SDK
Installation
npm i smartshopping-sdk
yarn add smartshopping-sdk
Integration
"storage", "tabs" and "alarms" permissions required
To use the checkAdblockAndCookie
function in Manifest V3 need add "scripting" permission and host_permissions in manifest:
"host_permissions": [
"*://*/*"
],
For Manifest V2 add "management" and "<all_urls>" permissions
Background script
Background script of extension using SmartShopping SDK might look like this:
import { bootstrap } from 'smartshopping-sdk';
import { requirePromocodes } from '../utils';
(async () => {
const { install, startEngine, setCodes, checkAdblockAndCookie } = bootstrap({
clientID: 'demo',
key: 'very secret key',
});
install();
chrome.tabs.onUpdated.addListener(async (tabId, changeInfo) => {
if (changeInfo.status === 'complete') {
startEngine(tabId);
}
});
chrome.tabs.onReplaced.addListener(async (tabId) => {
startEngine(tabId);
});
chrome.runtime.onMessage.addListener(
async (message, sender, sendResponse) => {
const tabId = sender?.tab?.id;
if (!tabId) {
return;
}
if (message.type === 'ready_to_CAA') {
const codes = await requirePromocodes(tabId);
if (codes.length) {
setCodes(tabId, codes);
}
}
if (message.type === 'check_adblock_cookie') {
checkAdblockAndCookie()
.then(({ isAdblockDisabled, isCookieEnabled }) => sendResponse({ isAdblockDisabled, isCookieEnabled }))
.catch(err => console.log(err))
}
}
);
})();
bootstrap
takes three arguments – client ID, secret key (which is used for data decryption) and optional - serverUrl (not used by default). If you dont know your ID and secret key, contact SmartShopping tech support
It returns four functions:
install: () => Promise<void>
uploads and stores merchants data; also sets up message passing between background and content parts of SmartShopping.startEngine: (tabId: number) => Promise<void>
identifies merchant in an active tab, uploads corresponding config and initializesEngine
in a content script. Takes browser tab ID as an argument.setCodes: (tabId: number, codes: string[]) => void
sends to theEngine
a list of coupons Takes browser tab ID and array of promo codes as an argumentscheckAdblockAndCookie: () => Promise<{ isAdblockDisabled: boolean; isCookieEnabled: boolean; }>;
function checks if Adblock extension is disabled and checks if cookies are enabled and returns an object with two boolean keys.
In the example above requirePromocodes
is a function defined by host extension, responsible for finding promocodes which will be passed to setCodes
.
Content Script
In a content script you need to import an engine
instance:
import { engine } from 'smartshopping-sdk';
engine
receives config object from background script and manages coupon autoapply flow or detect a successful coupon.
Coupon autoapply flow stages:
engine.inspect()
– analyzing checkout page and collecting information;engine.apply()
– applying promocodes and storing results into internal execution context;engine.applyBest()
– choosing and applying best promocode;
All three stages can be executed consistently via engine.fullCycle()
.
Detect stage - engine.detect()
– detects if a user tried to apply a coupons;
The execution of the stages: detect
, apply
, applyBest
can be aborted using the engine.abort()
method.
Since it is up to you to show the modal window with the suggestion to apply coupons, call the engine.notifyAboutShowModal()
method before it is shown so that we can get these statistics.
And if the user closes the modal prompting them to apply codes, call the engine.notifyAboutCloseModal()
method.
When a user tries to apply a third-party coupon, you can show them a modal window notifying them that they are trying to apply a third-party coupon, to collect statistics you can use methods:
notifyAboutShow3dPartyModal
- when opening the modal window;notifyAboutClose3dPartyModal
- when closing the modal window;notifyAboutReactivate3dParty
- when reactivating coupon (if you want to offer a user to reactivate a coupon);
Config object looks like this:
type EngineConfig {
version: number;
shopId: string;
shopName: string;
shopUrl: string;
checkoutUrl: string;
inspect: Array<Command>;
detect: Array<Command>;
apply: Array<Command>;
applyBest: Array<Command>;
selectorsToCheck: Array<string>;
}
version
– version of config spec for intrinsic usageshopId
– merchant's unique ID in SmartShopping databaseshopName
– merchant's nameshopUrl
– RegEx matching all merchant's URLscheckoutUrl
– RegEx matching merchant's checkout pageinspect
,detect
,apply
andapplyBest
– arrays of commands for respective stages of auto apply flow.selectorsToCheck
– array of selectors which are necessary to proceed. If any of them are invalid, execution stops with an error.
engine
stores info in the following properties:
config: EngineConfig
Config objectprogress: EngineProgress
Execution status
type EngineProgress =
| 'IDLE'
| 'INSPECT'
| 'INSPECT_END'
| 'DETECT'
| 'APPLY'
| 'APPLY_END'
| 'APPLY-BEST'
| 'APPLY-BEST_END'
| 'ERROR'
| 'CANCEL';
checkoutState: EngineCheckoutState
Info collected duringinspect
stagecheckoutState.total
– cart total before applying any codes
type EngineCheckoutState {
total: number | null;
}
finalCost: EngineFinalCost
This object contains pairs"promocode": "cart total after applying promocode"
type EngineFinalCost = { [key: string]: number }
promocodes: Array<string>
Array of promocodes for testingcurrentCode: string
Promocode currently being processeddetectState: EngineDetectState
Info collected duringdetect
stagedetectState.userCode
- promocode entered by the user. IfdetectState.userCode === 'UNDEFINED_CODE'
it means that we can't get the value of the code, but we know that it was entereddetectState.isValid
- validity of the code entered by the user.true
if the code is successfully applied andfalse
if the entered code turned out to be erroneous
type EngineDetectState {
userCode: string | 'UNDEFINED_CODE';
isValid: boolean;
}
bestCode: string
Most profitable promocode If none of the codes worked,bestCode === ''
checkout: boolean | null
The flag is null if you are on a page for which we don't have a config yet. In other cases, the flag has a boolean value and indicates whether you are on the checkout page
You can subscribe to those properties' changes via engine.subscribe()
...
const unbinders = engine.subscribe(
{
config: configListener,
checkoutState: checkoutStateListener,
finalCost: finalCostListener,
promocodes: promocodesListener,
progress: progressListener,
currentCode: currentCodeListener,
detectState: detectStateListener,
bestCode: bestCodeListener,
checkout: checkoutListener,
}
);
...and unsubscribe via engine.ubsubscribe()
, passing return value of engine.subscribe()
as an argument:
engine.unsubscribe(unbinders);
Subscribing for properties is optional so you may only choose ones you need and skip the rest:
const unbinders = engine.subscribe(
{
progress: listener1,
currentCode: listener2,
bestCode: listener3,
checkout: listener4,
}
);
listener
- functions look like this:
listener: (value: %property_type%, state: EngineState) => void;
interface EngineState {
checkoutState: EngineCheckoutState;
finalCost: EngineFinalCost;
progress: EngineProgress;
config: EngineConfig;
promocodes: Array<string>;
detectState: EngineDetectState;
bestCode: string;
currentCode: string;
checkout: boolean | null;
}
You can see more in our demo-extension
Changelog
[0.7.0] - 2023-11-16
Changed
- Engine initialization
Added
- Added support for user configs
- Extended error log
- SDK version in server request
- Methods for 3d party coupons
[0.6.11] - 2023-07-10
Added
- Added Edge supports for adblock check
[0.6.10] - 2023-07-06
Update
- Update documentation
- Update @types/chrome package
[0.6.9] - 2023-06-29
Added
- Export 'AdblockAndCookieOutput' type
[0.6.8] - 2023-06-23
Changed
- Now the checkout state is of type
boolean | null
. If we don't support the merchant from the page, we returnnull
in thecheckoutListener
[0.6.7] - 2023-06-21
Fixed
checkAdblockAndCookie
for use with Manifest V3- Error in console
- Update documentation
[0.6.6] - 2023-06-15
Fixed
- Error in console
[0.6.5] - 2023-06-15
Added
- Export
checkAdblockAndCookie
function
[0.6.4] - 2023-05-29
Added
- Export
BootstrapOutput
type
[0.6.3] - 2023-05-26
Fixed
- Optimizing the size of the data requested from the server
[0.6.2] - 2023-03-03
Changed
- Change method name from
sendСodes
tosetCodes
[0.6.1] - 2023-02-27
Added
- README.md file with Changelog
[0.6.0] - 2023-02-16
Added
sendCodes
method
Changed
- Remove
codes
param fromstartEngine
method
[0.5.21] - 2023-01-24
Fixed
- Cache work