Open-Source Cold Email & Warmup Platform
Warmbly 是開源的冷郵件平台:溫暖您的收件箱、發送活動、並對每個回覆進行分流。可在我們的雲端運行或自行託管整個系統。
AI 翻譯
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證n8n community node for the AdLib API (ad libraries of Meta, Google, TikTok, LinkedIn, Pinterest, X)
翻譯準備中
取自儲存庫 README
正在載入完整 README。
檢視完整 README ↗An n8n community node for the AdLib API: one API for the public ad libraries of Meta (Facebook, Instagram), Google (incl. YouTube and Google Play), TikTok, LinkedIn, Pinterest, X, Snapchat, Apple, Amazon and Microsoft (Microsoft in beta), with its own ad history. Ads that disappear from a platform's library are still there, with their run time, marked with removed_from_library_at.
Get an API key at adlibapi.com; the free plan includes 5,000 credits a month.
With this package you can:
Not affiliated with Meta, Google, TikTok, LinkedIn, Pinterest, X, Snapchat, Apple, Amazon or Microsoft.
In n8n:
n8n-nodes-adlib and confirm.The AdLib and AdLib Trigger nodes then show up in the nodes panel. See the n8n guide on installing community nodes for manual installation with npm (queue mode, Docker).
Create an AdLib API credential:
X-API-Key header./v1. Default https://api.adlibapi.com; change it if your account uses a different host.When you save the credential, n8n tests it with GET /v1/usage?days=1.
| Resource | Operation | Endpoint |
|---|---|---|
| Advertiser | Resolve by Domain | GET /v1/advertisers/resolve?domain= |
| Advertiser | Get | GET /v1/advertisers/{id} |
| Advertiser | Get Ads (Return All) | GET /v1/advertisers/{id}/ads |
| Advertiser | Get Changes (Return All) | GET /v1/advertisers/{id}/changes?since= |
| Advertiser | Get Stats | GET /v1/advertisers/{id}/stats |
| Advertiser | Get Timeline (Return All) | GET /v1/advertisers/{id}/timeline |
| Advertiser | Report Resolve Match | POST /v1/advertisers/resolve/reports |
| Advertiser | List Resolve Reports | GET /v1/advertisers/resolve/reports |
| Ad | Search (Return All) | GET /v1/search |
| Ad | Get | GET /v1/ads/{id} |
| Ad | Get History | GET /v1/ads/{id}/history |
| Ad | Get Ad Features | GET /v1/ads/{id}/features |
| Ad | Parse Library URL | GET /v1/library-url?url= |
| Domain | Check if Advertising | GET /v1/domains/{domain}/check |
| Domain | Get Company Profile | GET /v1/companies/{domain} |
| Domain | Suggest Domains | GET /v1/domains/suggest?q= |
| Watchlist | Create | POST /v1/watchlists |
| Watchlist | Get | GET /v1/watchlists/{id} |
| Watchlist | List | GET /v1/watchlists |
| Watchlist | Add Advertisers | POST /v1/watchlists/{id}/advertisers |
| Watchlist | Remove Advertiser |
Notes:
<platform>:<id>, for example meta:15087023444 (advertiser) or meta:1234567890 (ad). Advertiser > Resolve by Domain gives you advertiser IDs; each candidate has a confidence score (0 to 1) and a match_reason. Use Options > Minimum Score to drop weak matches and Split Into Items to get one item per advertiser.nike.com or as a full URL; only the host is sent.meta.errors with Raw Pages and are not billed. Source: History searches the archive, including ads that are gone from the platforms; Sort: Days Running puts the longest-running ads (likely winners) first. Political Ads: Only or Exclude filters political and issue ads (only Meta labels them, so Only limits results to Meta). With Source: History, Removed Ads: Only returns ads the platforms' libraries no longer show (taken down, deleted or aged out) that AdLib kept, and Exclude leaves them out.google:. The other Platforms fields (resolve, domain check, company profile, batch, trigger) take the 10 libraries. In search, Options > Placement (Google Search, Shopping, Maps, Play or YouTube) limits a search to where Google ads ran. YouTube with Format: Video gives YouTube video ads.derived.signals (why it likely performs, from public facts: long_running, still_running_90d, scaled, wide_reach, multi_country) and derived.stage (testing, scaling or proven). List results carry meta.platform_totals with Raw Pages: the matching ads per platform, where the platform reports it.The trigger starts the workflow when watched advertisers start, stop, change or remove ads.
On activation it creates an AdLib watchlist whose webhook_url is this node's webhook URL, and stores its ID. On deactivation it deletes the watchlist. Every delivery is checked against the X-AdLib-Signature header (t=<unix>,v1=<hex HMAC-SHA256 of "<t>.<raw body>">) with your webhook secret from GET /v1/webhooks/secret; deliveries with a wrong signature or a timestamp more than 5 minutes off are answered with 401 and do not start the workflow. If you rotate the secret, the trigger fetches the new one on the next delivery.
Each advertiser.changes event is one item:
{
"event": "advertiser.changes",
"watchlist_id": "…",
"advertiser_id": "meta:15087023444",
"crawled_at": "2026-10-26T06:00:00Z",
"summary": { "new": 2, "started": 0, "stopped": 1, "changed": 0, "removed": 0 },
"new": [{ "type": "discovered", "at": "…", "ad_id": "meta:…", "ad": { } }],
"started": [],
"stopped": [{ "type": "stopped", "at": "…", "ad_id": "meta:…", "ad": { } }],
"changed": [],
"removed": []
}
With Options > Split Into Ads, you get one item per ad instead, with change set to new, started, stopped, changed or removed, plus watchlist_id, advertiser_id and crawled_at.
Good to know:
POST /v1/webhooks/test and the test URL: pings start manual test runs only and are ignored in production.Single objects (an advertiser, an ad, a domain check, a watchlist) come out as one item: the API's data object, with meta kept as _meta where the API sends it.
List operations output one item per result (ad, event, watchlist). They have:
next_cursor page by page until the last page or Max Pages (default 10). Page Size sets the results per call.next_cursor you saved.next_cursor and meta, instead of one item per result.Batch > Get outputs one item: the job (status, counts, credits billed) with all fetched items.
The API can also answer in CSV (output=csv). The node does not use that: n8n passes JSON items between nodes, and Return All needs the JSON next_cursor. To get a CSV file, add n8n's Convert to File node after the AdLib node; Domain > Check if Advertising already has a flat columns object for spreadsheets.
The AdLib API bills credits per delivered result, not per call, and reports them in the X-Billing-Credits header. The free plan includes 5,000 credits a month.
| Platform | Credits per delivered ad |
|---|---|
| Meta, TikTok, Pinterest, X, Snapchat, Apple (App Store), Amazon, Microsoft | 1 |
| Google, YouTube, Google Play | 2 |
| 3 |
Return All can deliver many results, so keep Max Pages at a sensible value. Usage > Get shows what you used per day and endpoint.
The API answers errors as {"error": {"code", "message", "request_id", …}}. The node shows that message with a hint, for example:
401: wrong API key or Base URL.402: no credits left.403: the key may not use this endpoint, or history_limit: the ad is older than your plan's archive window (free 90 days, starter 365 days, growth and up unlimited).404: unknown advertiser, ad, watchlist or job ID.429: rate limit. Wait, or turn on Retry On Fail in the node settings.Enable Continue On Fail (or On Error: Continue) if a single bad domain should not stop the workflow.
The AdLib node is marked usableAsTool, so it can be attached to an AI Agent node as a tool, for example to let an agent look up a company's ads or check whether a lead is advertising. On self-hosted n8n, community nodes can only be used as tools when the environment variable N8N_COMMUNITY_PACKAGES_ALLOW_TOOL_USAGE=true is set.
Import any of these via Workflows > Import from File, then pick your own credentials in each node.
templates/competitor-ads-to-slack.json
AdLib Trigger (Watch By: Domain competitor.com, Split Into Ads) → Filter (change is new or started) → Slack (post advertiser, platform, headline and library link to #competitor-ads). Activate the workflow; from the second crawl on, every new ad of the competitor is posted.
templates/domain-enrichment-google-sheets.json
Google Sheets (read rows with a domain column) → AdLib (Domain > Check if Advertising, {{ $json.domain }}) → Edit Fields (advertising yes/no/unknown, platforms with ads, active ad count, checked at) → Google Sheets (append or update, matched on domain). advertising is unknown when no platform could be checked; such checks are free.
npm install
npm run dev # starts n8n with these nodes loaded, rebuilds on change (http://localhost:5678)
npm run lint
npm test # builds, then runs the unit tests in test/
The operations and their fields live in nodes/AdLib/descriptions.ts, the requests in nodes/AdLib/AdLib.node.ts. Signature checking is in nodes/AdLibTrigger/signature.ts. No runtime dependencies.
DELETE /v1/watchlists/{id}/advertisers/{advertiser_id} |
| Watchlist | Update | PATCH /v1/watchlists/{id} |
| Watchlist | Delete | DELETE /v1/watchlists/{id} |
| Batch | Create | POST /v1/batch |
| Batch | Get (Return All) | GET /v1/batch/{job_id} |
| Webhook | List Deliveries (Return All) | GET /v1/webhooks/deliveries |
| Webhook | Get Delivery | GET /v1/webhooks/deliveries/{id} |
| Webhook | Redeliver | POST /v1/webhooks/deliveries/{id}/redeliver |
| Webhook | Send Test | POST /v1/webhooks/test |
| Webhook | Get Secret | GET /v1/webhooks/secret |
| Webhook | Rotate Secret | POST /v1/webhooks/secret/rotate |
| Platform | List | GET /v1/platforms |
| Platform | Get Status | GET /v1/status |
| Usage | Get | GET /v1/usage |
text.hook, offers, urgency, social_proof, guarantee and other tags (each with the exact text it matched), the measured format, media aspect, duration and scene cuts, and on-image text read with OCR. Costs 2 credits by default, plus the ad if it has to be fetched live.kind (ad or advertiser), id and href, the AdLib call that fetches it. Free.columns, a flat object (advertising, platforms_advertising, total_active_ads, latest_ad_at, and <platform>_advertising, <platform>_active_ads, <platform>_advertiser_id) that maps straight onto spreadsheet columns.accounts, with score at least Minimum Score, default 0.75), per-platform totals and combined stats. Agencies, resellers and partners running ads for the domain are listed under related (each account has a role) and left out of the totals unless Include Related Accounts is on. Accounts below the threshold are listed as candidates. It costs one resolve plus one stats call.advertiser_count, interval_hours and email_alerts; the advertisers and their crawl status are in Watchlist > Get. Options > Email Alerts on Create (or Update) mails a digest of each crawl's changes to your account's email. Watchlist > Update changes the name, webhook URL (an empty Webhook URL field removes the webhook) or email alerts.advertiser.changes events; Slack and Discord incoming webhook URLs get a readable message instead.removed events: the platform's library no longer shows the ad (AdLib keeps it).batch.completed event when it is done. Results are kept 30 days.webhook.ping to a URL. Get Secret returns the signing secret (it is stored in the execution data, so prefer the AdLib Trigger, which verifies signatures for you); Rotate Secret replaces it at once, and the AdLib Trigger picks up the new secret on its next delivery.