塑造个人品牌,发现细分市场,构建可持续盈利的产品
I share how to build a personal brand, discover niche markets, and create sustainably profitable products. I also share everything about AI.
AI translation
Daily digest of new marketing, advertising and consumer research from 189 curated journals via OpenAlex, with a Claude-written, self-fact-checked pitch dashboard.
MarketingPython · JavaScriptGitHub @Meggers1982OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗Automated pipeline that pulls new articles from a curated list of marketing, advertising and consumer-research journals, uses Claude to write a pitchable digest for two audiences, fact-checks its own output against the abstracts, and publishes every run to a browsable dashboard — https://marketing-research-digest.vercel.app
Built on senior-research-digest: same shape, same scoring idea, same dashboard (the freelance-opps design system by way of AgingWire). What differs is below in Where this differs.
.github/workflows/daily-digest.yml runs scripts/main.py once a day. The cron
asks for 10:07 UTC (5:07am CDT, 4:07am CST); GitHub queues scheduled runs, so expect it hours late
(2.5 to 4.5 hours is typical across these repos, 11.5 the worst seen). Each run:
config/digest_config.json
(a broad day plus 13 topics, by day of year), or the focus input of a
manual run.openalex.py) for everything the 177 indexed journals
published in the last 60 days, narrowed on topic days by a boolean
title-and-abstract query from topics.py.screening.py) down to 40 articles: drops front matter, articles
with no abstract, off-topic articles in the adjacent journals, and anything an
earlier digest already wrote up; ranks the rest by journal rating, recency and
topic relevance, at most three per journal. Every drop is counted.digest_generator.py): Claude picks the newsworthy
studies and returns one record each — headline, the study, why it matters, an
angle for marketers, an angle for general readers, caveats. Journal, date and
DOI are stamped on from OpenAlex, not written by the model.fact_checker.py): a second pass compares every entry
with its abstract and returns a verdict and issues per study.web_coverage.py, Google News via
SerpAPI). Skipped, and labelled as skipped, without SERPAPI_API_KEY.trends.py): continuity with the last run on the same topic,
a cross-study feature pitch with outlets, and a story idea per study, plus a
per-topic memory file in topic_memory/.outputs/ — the digest and fact check as markdown for
people, and a .json run record — then rebuilds docs/data/.marketing-research-digest is connected to this repo and builds every commit
on main; vercel.json serves docs/ with no build step and no token in
the workflow. The bot commits under Meggers1982's GitHub no-reply address
on purpose: on Vercel's Hobby plan a private repo only deploys commits whose
author is on the team, and any other identity gets the deploy BLOCKED.Every Claude call (steps 4, 5 and 7) goes through the Message Batches API
(scripts/llm.py): half price, answered asynchronously, usually within minutes.
The digest and fact-check batches each go in as a single submission. A
submission waits up to 45 minutes, then is canceled and whatever did not finish
runs live at full price, so a slow day costs money, not the digest. The job cap
is 240 minutes to allow for that. Set DIGEST_USE_BATCH_API=0 to send
everything live instead.
python -m pytest tests/ -q runs first in the same workflow. It touches no API.
scripts/resolve_sources.py and stored in config/journals.csv. Fourteen rows
on the list have "unverified" in place of an ISSN and two had theirs mangled by
a spreadsheet; a source ID survives both.outputs/*.json holds exactly
what the model returned; the markdown is rendered from it and nothing parses it.Secrets (Settings → Secrets and variables → Actions):
| Secret | Needed | What happens without it |
|---|---|---|
ANTHROPIC_API_KEY | yes | the run stops before OpenAlex |
SERPAPI_API_KEY | no | coverage is not checked; no study can band as "Lead" |
OPENALEX_API_KEY | no | anonymous limit of 1,000 calls a day; a run uses about 15 |
Run it by hand: Actions → Daily Marketing Research Digest → Run workflow, with an optional topic.
config/digest_config.json for the rotation; scripts/topics.py
for each topic's OpenAlex query and tag terms. A rotation topic must exist in
both — a test checks it.config/journals.csv (it is a copy of
~/Documents/Marketing Research Journals/Marketing Research Journals.csv plus
two OpenAlex columns), then run python scripts/resolve_sources.py. A near-miss
name is recorded as "no match; closest: …" rather than accepted, because two
titles on the list carry hijacked-title warnings.docs/data/hidden.json ({"ids": [...]}) and
rebuild with python scripts/build_dashboard_data.py. Nothing is deleted.python scripts/build_dashboard_data.py. No API calls.var(--accent) from a base a rule, so
OpenAlex IDs in the prose and DOIs in the citation table stay readable in dark
mode. They used to fall back to browser blue (#0000EE). A test pins it.On this Mac, use python3.11 (the repo needs 3.10+; the python.org 3.11 has no CA
bundle, so live OpenAlex calls need
SSL_CERT_FILE=$(python3.11 -c "import certifi; print(certifi.where())")).