OpenAds is a library for displaying ads based on page context or user activity.
npm install @fhylabs/openadsarticle, search, category, tag, home
title + content) |
selectAd() function → returns one winning ad
selectAds(context, ads, options, limit) → returns multiple top ads (multi-ad)
ad-1 → ad-2 → ad-3
`
> Note: Bid + keyword relevance determine the score. Device/geo/hour filters eliminate irrelevant ads before scoring.
---
Campaign & Budget Flow
Every ad in a campaign reduces the campaign budget when displayed.
| Concept / Factor | Description |
| ----------------------------- | ------------------------------------------------------------------ |
| Campaign Budget | Total fund allocated for the campaign (e.g., 100,000) |
| Bid / Ad Price | When an ad is shown, the bid is deducted from the budget |
| Device, Geo, Hour Filters | Ads that do not match are removed, budget is not reduced |
| Ad Priority | Ads with higher bid & higher keyword relevance are displayed first |
| Stop When Budget Runs Out | If remaining budget < ad bid → ad is not displayed |
#### Example Budget
| Ad | Bid | Relevance | Budget Before | Budget After |
| ---- | ----- | --------- | ------------- | ------------ |
| ad-1 | 3,500 | High | 10,000 | 6,500 |
| ad-2 | 2,800 | Medium | 6,500 | 3,700 |
| ad-3 | 3,000 | Low | 3,700 | 700 |
Display Order:
`
ad-1 → ad-2 → ad-3
`
> Notes:
>
> * Ads are displayed only if campaign budget ≥ ad bid
> * Irrelevant ads (by device/geo/hour filters) do not reduce budget
> * Multi-ad campaigns → each ad displayed reduces the budget separately
---
Usage
$3
`
npm i @fhylabs/openads
`
$3
`js
// CommonJS
const { Ad, Context, selectAd, selectAds, renderHtml } = require("@fhylabs/openads");
// ES Modules
import { Ad, Context, selectAd, selectAds, renderHtml } from "@fhylabs/openads"
`
$3
`js
const ads: Ad[] = [
{
id: "ad-1",
title: "Ultra Fast Laptop",
description: "Laptop with high performance",
url: "https://example.com",
image: "https://img.example.com/laptop.jpg",
keywords: ["laptop", "gaming", "developer", "high performance"],
bid: 3500,
device: "desktop", // all | desktop | mobile
countries: ["ID", "EN"], // [] → all countries
hours: [9,10,11,12,13,14,15,16,17], // [] → all hours
category: ["hardware", "programming"] // [] → all categories
}
// other ads ...
]
`
$3
`js
const contexts: { label: string, context: Context, options?: any }[] = [
{
label: "ARTICLE PAGE",
context: {
type: "article",
title: "Learn Node.js Backend",
content: "Node.js backend tutorial for developers. Covers server, hosting, and cloud infrastructure.",
category: "backend"
},
options: { device: "desktop", country: "ID" }
},
{
label: "SEARCH PAGE",
context: {
type: "search",
content: "cloud vps server"
},
options: { device: "all", country: "ID" }
},
{
label: "CATEGORY PAGE",
context: {
type: "category",
content: "backend",
category: "backend"
}
},
{
label: "TAG PAGE",
context: {
type: "tag",
content: "developer"
}
},
{
label: "HOMEPAGE",
context: {
type: "home",
content: "javascript typescript react developer tools"
}
}
]
`
$3
#### Single Ad
`js
for (const { label, context, options } of contexts) {
const ad = selectAd(context, ads, options)
console.log(\n===== ${label} =====)
if (!ad) console.log("No matching ads")
else {
console.log(ID : ${ad.id})
console.log(Title : ${ad.title})
console.log(Device : ${ad.device})
console.log(Category: ${ad.category})
console.log(Bid : ${ad.bid})
console.log("\nHTML OUTPUT:\n")
console.log(renderHtml(ad))
}
}
`
#### Multiple Ads
`js
for (const { label, context, options } of contexts) {
const topAds: Ad[] = selectAds(context, ads, options, 3)
console.log(\n===== ${label} =====)
if (!topAds.length) console.log("No matching ads")
else {
topAds.forEach((ad: Ad, i: number) => {
console.log(\n--- Ad #${i + 1} ---)
console.log(ID : ${ad.id})
console.log(Title : ${ad.title})
console.log(Device : ${ad.device})
console.log(Category: ${ad.category})
console.log(Bid : ${ad.bid})
console.log("\nHTML OUTPUT:")
console.log(renderHtml(ad))
})
}
}
`
#### Campaign Multi Ads
`js
const { context: articleContext, options: articleOptions } = contexts[0]
const topAdsFromCampaign = selectAds(articleContext, campaign.ads, articleOptions, 3)
console.log("\n===== CAMPAIGN: Multi Ads =====")
if (!topAdsFromCampaign.length) console.log("No matching ads")
else {
topAdsFromCampaign.forEach((ad: Ad, i: number) => {
console.log(\n--- Ad #${i + 1} ---)
console.log(ID : ${ad.id})
console.log(Title : ${ad.title})
console.log(Bid : ${ad.bid})
console.log("HTML OUTPUT:")
console.log(renderHtml(ad))
})
}
`
#### Campaign Single Ad
`js
const adFromCampaign = selectAd(articleContext, campaign.ads, articleOptions)
console.log("\n===== CAMPAIGN: Single Ad =====")
if (adFromCampaign) {
console.log(ID : ${adFromCampaign.id})
console.log(Title : ${adFromCampaign.title})
console.log(Bid : ${adFromCampaign.bid})
console.log("HTML OUTPUT:")
console.log(renderHtml(adFromCampaign))
} else {
console.log("No matching ads")
}
``