aicash-embed
v0.1.0
Published
Drop a single revenue-shared sponsored line into any chat bot, web UI, or custom CLI and get paid for it (aicash publisher SDK, Model B).
Maintainers
Readme
aicash-embed
Drop a single revenue-shared sponsored line into any chat bot, web UI, or custom CLI — and get paid for the impressions and clicks it generates.
This is the publisher SDK for the aicash text-ad network (Model B: publisher payee). You authenticate once with a publisher key; every impression/click accrues to your aicash account, no matter which end-user saw it. End-users are never asked to log in.
Install
npm install aicash-embedGet a publisher key from the aicash dashboard and put it in your env as AICASH_PUBLISHER_KEY.
Sandbox → live
You get two kinds of key. Both attribute to the same publisher and behave identically in code — the only difference is what they serve:
| Key | Serves | Earns | Use for |
|---|---|---|---|
| pk_test_… | test ads | nothing (events are recorded but never counted) | building & verifying your integration |
| pk_live_… | real ads | revenue share | production |
Build against pk_test_ first: you'll see the full flow — ad text, the
Sponsored line, impression + click tracking — without generating billable
traffic or affecting your account quality. When it works, swap the env var to
your pk_live_ key. No code change.
Usage (core)
import { createAdClient } from "aicash-embed";
const ads = createAdClient({
publisherKey: process.env.AICASH_PUBLISHER_KEY!,
host: "my-bot",
});
const ad = await ads.getAd({
endUserId: "end-user-id", // hashed locally → never sent raw
sessionId: "channel-id",
});
if (ad) {
// renderLine adds the mandatory "Sponsored" disclosure and fires the
// impression automatically.
await send(ads.renderLine(ad));
}Telegram adapter
aicash-embed/telegram is a thin wrapper that reads from.id/chat.id off a
Telegram message for you and renders Telegram-ready lines. It's library-agnostic
(grammY, Telegraf, node-telegram-bot-api, or the raw Bot API).
import { createTelegramAds } from "aicash-embed/telegram";
const ads = createTelegramAds({ publisherKey: process.env.AICASH_PUBLISHER_KEY! });
// host defaults to "telegram-bot"
bot.on("message", async (msg) => {
await bot.sendMessage(msg.chat.id, `You said: ${msg.text}`);
const ad = await ads.sponsoredLine(msg, { render: { format: "html" } });
if (ad) {
await bot.sendMessage(msg.chat.id, ad.text, {
parse_mode: ad.parseMode, // "HTML" | undefined
disable_web_page_preview: true,
});
}
});sponsoredLine(msg) returns { text, parseMode } (or null when there's no ad),
so you can hand it straight to sendMessage. Telegram permits a labelled
sponsored line in your bot's own messages. See a full runnable bot in
examples/telegram-bot.mjs.
Telegram adapter API: createTelegramAds(opts) → { getAd, adForMessage,
renderLine, sponsoredLine, fireImpression }.
ads.renderLine(ad) →
Sponsored · Fastest Postgres hosting — Neon: https://api.aicash.fun/c/ab12…Markdown platforms:
ads.renderLine(ad, { format: "markdown" });
// Sponsored · [Fastest Postgres hosting — Neon](https://api.aicash.fun/c/ab12…)Design guarantees
| Guarantee | What it means |
|---|---|
| Never throws | getAd() returns null on any error/timeout/no-fill. A failed ad request can't break your bot. |
| Disclosure is mandatory | renderLine() always prefixes Sponsored ·. There is no option to hide it. |
| Privacy by default | endUserId is hashed on your machine into an opaque surfaceKey before it leaves; the raw id is never sent. Message context is only shared when you pass consentContext: true. |
Contextual ads (opt-in)
By default the SDK serves run-of-network ads — no conversation content leaves your machine. To get more relevant ads, opt in per call:
const ad = await ads.getAd({
context: recentMessages, // [{ role, content }, …]
consentContext: true, // you confirm the end-user consented
endUserId: String(msg.from.id),
});⚠️ Some platforms forbid sending their user data to ad networks (e.g. Discord). Keep
consentContextfalse there — the SDK never sends context unless you opt in.
Disclosure & policy
Non-negotiable, and mostly handled for you:
- Every ad must be labelled.
renderLine/sponsoredLinealways prefixSponsored ·. Don't strip it — it keeps you compliant with FTC and platform ad-disclosure rules. - Don't send a platform's user data to the ad network where its rules forbid
it. Notably Discord: keep
consentContextfalse so no message content leaves your machine (the SDK's default). - Never advertise where the platform bans it. Slack prohibits ads in its app/channels outright — don't ship there.
- One line, under your own message. Keep it to a single sponsored line appended to your bot's own reply.
Going live checklist
- Integrate with your
pk_test_key; confirm theSponsoredline renders and clicks open the tracked link. - Decide contextual vs run-of-network (
consentContext). If your platform forbids sharing user data, leave it off. - Swap
AICASH_PUBLISHER_KEYto yourpk_live_key. - Watch your valid-rate in the dashboard — very low valid-rate or bot-like traffic is auto-suspended.
API
createAdClient(options)→AdClientpublisherKey(required),host(required)proxyUrl?,surfaceSalt?,timeoutMs?(4000),disclosureLabel?("Sponsored"),autoImpressionOnRender?(true)
client.getAd(opts?)→Promise<EmbedAd | null>client.renderLine(ad, opts?)→string(format: "plain" | "markdown",noImpression?)client.fireImpression(ad)→Promise<void>(manual, deduped)
License
MIT
