Skip to main content

NativeAds SDK for Telegram bots — inject ads into LLM replies (aiogram / python-telegram-bot / raw).

Project description

nativeads (Python)

Python SDK for NativeAds — monetize your Telegram bot by injecting ads into LLM replies. Works with aiogram 3.x, python-telegram-bot v20+, or raw bot code.

pip install nativeads              # core (httpx only)
pip install nativeads[aiogram]     # + aiogram 3.x
pip install nativeads[ptb]         # + python-telegram-bot v20+

Quick start (inject)

from nativeads import NativeAds

ads = NativeAds(api_key="sk_live_xxx", platform_id="plt_xxx")

# inside an async message handler, after generating the LLM answer:
result = await ads.inject(
    user_id=message.from_user.id,
    message=llm_answer,
    language_code=message.from_user.language_code,
    is_premium=message.from_user.is_premium,
    keyboard=my_keyboard,        # optional — aiogram / PTB / raw dict
    # ad_button_position="top",  # default "bottom"
)
# link_preview_options hides the ad link's preview card (clean native footnote).
await message.answer(
    result.message,
    reply_markup=result.keyboard,
    link_preview_options=result.link_preview_options,
)

result.link_preview_options is {"is_disabled": True} by default, so the ad reads as a native footnote, not a banner. It's None when no ad was injected — always safe to pass. Want the rich preview card? Build the client with link_preview=True. On older aiogram/PTB without link_preview_options, use disable_web_page_preview=True instead.

aiogram middleware (DI)

from nativeads import NativeAds
from nativeads.middleware import NativeAdsMiddleware

mw = NativeAdsMiddleware(api_key="sk_live_xxx", platform_id="plt_xxx")
dp.message.middleware(mw)
dp.shutdown.register(mw.aclose)

async def handler(message: Message, nativeads: NativeAds):
    result = await nativeads.inject(user_id=message.from_user.id, message=answer)
    await message.answer(
        result.message,
        reply_markup=result.keyboard,
        link_preview_options=result.link_preview_options,
    )

Privacy-friendly mode (fetch)

res = await ads.fetch(user_id=uid, language_code="ru")
if res.has_ad:
    text = f"{llm_answer}\n\n{res.ad.ad_text}"
    # render res.ad.button_text / res.ad.button_url yourself

Contextual targeting (user_message) — v0.3.0+

Optional. With inject() the topic is already inferred from your bot's reply, so you don't have to pass anything extra. Passing the user's message improves it: short user questions are classified inline, so even the very first impression gets targeted. With fetch() (no reply is sent) user_message is the only context source.

result = await ads.inject(user_id=uid, message=llm_answer, user_message=user_text)
res = await ads.fetch(user_id=uid, user_message=user_text)

Truncated to 4000 chars client-side, processed in memory, never stored raw.

Guarantees

  • Never raises. On any error (timeout, network, 5xx) inject()/fetch() return your original message and keyboard unchanged. Default timeout 3s.
  • Your buttons are preserved — the ad button is a separate row (top/bottom), respecting Telegram's 4096-char and 13-row limits.
  • Click tracking is automaticbutton_url is a tracking redirect.

API

  • NativeAds(api_key, platform_id=None, *, base_url=..., timeout=3.0, platform="telegram", show_every=1, skip_first=0, link_preview=False)
    • show_every — ad on every Nth message (5 = optimal, 0 = off); N>1 keeps the first message ad-free.
    • skip_first — never show an ad on a user's first N messages.
    • link_preview — show Telegram's preview card for the ad link (False keeps it a clean footnote).
    • Frequency is client-side (in-memory per-user counter); skipped turns return your message without a server call.
    • NativeAdsMiddleware(...) accepts the same show_every / skip_first / link_preview.
  • await ads.inject(*, user_id, message, language_code=None, is_premium=None, keyboard=None, ad_button_position="bottom", parse_mode=None) -> InjectResult
  • await ads.fetch(*, user_id, language_code=None, is_premium=None, parse_mode=None) -> FetchResult
  • await ads.aclose()

InjectResult(message, has_ad, impression_id, ad, keyboard, link_preview_options) · FetchResult(has_ad, impression_id, ad) · Ad(ad_text, button_text, button_url, ad_text_formatted)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nativeads-0.3.1.tar.gz (12.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nativeads-0.3.1-py3-none-any.whl (8.1 kB view details)

Uploaded Python 3

File details

Details for the file nativeads-0.3.1.tar.gz.

File metadata

  • Download URL: nativeads-0.3.1.tar.gz
  • Upload date:
  • Size: 12.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.6

File hashes

Hashes for nativeads-0.3.1.tar.gz
Algorithm Hash digest
SHA256 daa6196fafaae5da486446f1cf97e43bf0cb148151dc4b2f90ac7141047a2045
MD5 7200d1f04853561b79b399b9410144ff
BLAKE2b-256 eecd70cc642d4923e7332cba4588069b7e813c8989f2d436580a79899ff97a5d

See more details on using hashes here.

File details

Details for the file nativeads-0.3.1-py3-none-any.whl.

File metadata

  • Download URL: nativeads-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 8.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.6

File hashes

Hashes for nativeads-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 f85f48a7aeb193cffebeaa7046e36014c2bc5f665c294cd791aa201a1aa1206f
MD5 9d3ab17d3db84212459f9913db5500e2
BLAKE2b-256 a33cef6b5fbbf9cfdc1675247a441faf2c437ffb6df93a5f3f31844d89ce4694

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page