Model or dataset
ViggoZ/producthunt-daily-hot avatar
ViggoZ/producthunt-daily-hot

producthunt-daily-hot: a daily Product Hunt list, translated and committed by a cron job

自动生成每日Product Hunt热门产品中文榜单,基于GitHub Actions自动提交Markdown文件

1,008 stars138 forksPythonMIT

At a glance

What is it?
producthunt-daily-hot is a small Python tool that fetches the previous day's Product Hunt top 30, uses GPT-4 to translate each description and generate a short Chinese keyword, writes a Markdown file into the data directory, and commits it through a GitHub Actions workflow that runs every morning. It is MIT licensed and the last push was on 2026-10-15.
Who is it for?
The tool fits a Chinese-language publication that wants a daily Product Hunt roundup without a person writing it, and it fits a reader who wants to see the workflow of a scheduled content pipeline end to end. It does not fit a project that needs the data to be a faithful record rather than a translation, because every description passes through a language model.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A scheduled job that writes a file and commits it

The producthunt-daily-hot repository is an automated tool based on GitHub Actions that generates a daily ranking of popular Product Hunt products as a Markdown file and commits it back to the repository automatically. The stated purpose is to help users quickly see the daily Product Hunt hot list and get more detailed information about each product.

The mechanism is worth stating plainly, because it is a common shape and a clean one. A scheduled workflow runs, a script fetches yesterday's products, the model translates and summarises them, a Markdown file is written into the `data/` directory, and the workflow commits it. The output is versioned in git, which means the archive of every day's list is a git history rather than a database.

The file naming is deterministic, `PH-daily-YYYY-MM-DD.md`, so the archive is browsable by date without any index. The published list is shown daily on decohack.com under the producthunt category, and the homepage of the project points at that same page, with search and browsing by month of past issues.

The updates happen on a schedule, with the list refreshed every day at 4pm, and the underlying workflow runs at 07:01 UTC, which is 15:01 Beijing time. It can also be triggered manually.

The top-level layout shows how small this is. There is a `data/` directory for the generated files, a `scripts/` directory for the Python, `requirements.txt`, the two readmes in English and Chinese, a `preview.gif`, and a `.github/` directory holding the workflow. There is also a stray file named `=1.0.0` at the root, which is the sort of artefact a mistyped shell redirect leaves behind, and it is a small reminder that this is a personal project rather than a packaged one.

The pipeline is fetch, translate, summarise, write, commit

The feature list describes the stages, and each one is a separate concern that could fail separately.

Automatic data fetching gets the previous day's Product Hunt top 30 products. Keyword generation produces concise, easy to understand Chinese keywords so a reader can grasp what a product does before reading the description. High quality translation uses OpenAI's GPT-4 model to translate the product descriptions. Markdown file generation produces a file containing the product data, the keywords and the translated descriptions, ready to publish on a website or another platform. Daily automation handles the generate-and-commit step through GitHub Actions. A configurable workflow supports both manual triggering and scheduled generation. And the scripts are easy to extend or modify to include extra product details or change the file format.

The order matters. The keyword generation comes before the translation in the list, which suggests the pipeline works in the order a reader consumes the page: a title and a keyword, then the description. That is a small thing, but a generated list where the keyword is derived from the English description rather than from the Chinese one tends to read better, because the keyword is the part that has to fit in a table cell.

The dependencies confirm the shape. `requests` and `urllib3` for the Product Hunt API, `beautifulsoup4` for parsing, `openai` for the model calls, `pytz` for time zone handling, which matters for a job that has to decide which day is yesterday, and `python-dotenv` for loading secrets from a local environment file during development.

The `openai` and `beautifulsoup4` pair is worth noticing. If the Product Hunt data were fetched from the API as structured JSON, the HTML parser would not be needed, so the scraper is presumably reading the website. That is a reasonable choice for a small project and it is also a fragile one, since a website markup change breaks the fetcher without any API version to negotiate.

Three secrets, and the token that pushes the result

The setup section lists what you need, and the shape of it is instructive about how this kind of pipeline is actually operated.

The prerequisites are Python 3.x, a GitHub account and repository, an OpenAI API key, and a Product Hunt developer token obtained from the Product Hunt developer settings page.

Then there are four GitHub Secrets. `OPENAI_API_KEY` is the OpenAI key. `PRODUCTHUNT_DEVELOPER_TOKEN` is the Product Hunt token. `PAT` is the personal access token used to push the changes back to the repository. And `DISPATCH_TOKEN` is optional and, when set, notifies a downstream repository such as a website to update itself; without it that step is skipped.

The optional dispatch token is the interesting one, because it solves a real problem. The natural implementation is that the daily list is committed to one repository and the website pulls it, but then the website's build has to run on a schedule and detect the change, which means either polling or a webhook. The dispatch token is a repository dispatch event, a push that asks another repository to rebuild, and it makes the website update immediately after the list is committed rather than whenever its own cron happens to run.

The Product Hunt token comes from the developer settings page, where you create a new application in the OAuth applications section to obtain it. That is the standard path for a personal integration rather than a published one.

The `PAT` deserves a note. A personal access token with write access to the repository is what lets the workflow commit the generated file, and it is the credential most likely to be over-scoped if someone grants repository-wide write access rather than the narrowest scope that works. Since the workflow also has an OpenAI key, the blast radius of a compromise in either is the repository.

Running it locally, and where the content actually comes from

The install is the standard Python two-step, and then the workflow is what does the work.

bash
git clone https://github.com/ViggoZ/producthunt-daily-hot.git
cd producthunt-daily-hot
bash
pip install -r requirements.txt

The workflow is defined in `.github/workflows/generate_markdown.yml`, and it runs automatically every day at 07:01 UTC, which is 15:01 Beijing time, and can also be triggered manually. Once it is set up, the GitHub Action automatically generates and commits a Markdown file containing the day's popular Product Hunt products, and the files are stored in the `data/` directory.

The two customisation points are named, and they are the right two. You can modify `scripts/product_hunt_list_to_md.py` to customise the generated file format or add extra content, and if you need it, you can adjust the schedule in `.github/workflows/generate_markdown.yml`.

That split between the script and the workflow is a sensible design for a project like this. The workflow is the scheduling and the committing, which is plumbing that rarely needs changing, and the script is the content generation, which is where the interesting adjustments happen. It also means the script can be run by hand during development with the same secrets loaded from a `.env` file, which is what `python-dotenv` is in the dependency list for.

One thing the documentation does not describe is how the day boundary is handled when the job runs. A job at 07:01 UTC fetching the previous day's products has to decide which day means yesterday, and in a Chinese and Western timezone mix the answer shifts. `pytz` being a dependency suggests the author thought about it, and the file name carries a date, so the archive is self-describing either way.

Where producthunt-daily-hot is the wrong approach

The first case is anything that needs the data to be a faithful record. Every product description in the output has been through a language model, which means the file is a translation and a summary, not the source. A downstream consumer that wants the original English description, the tag list, the upvote count at a point in time or the maker's own wording gets none of it from this output. The Product Hunt API would give all of that.

The second case is a project where a language model call per product is not acceptable. Thirty products a day is thirty translation requests a day, and every one of them costs money and takes time. A site with a larger volume, or one covering more than one source, multiplies that. And the failure mode is quiet: if the OpenAI key is exhausted or the model returns something malformed, the pipeline does not fail loudly, it produces a file that is subtly wrong.

The third is a workflow that needs the output somewhere other than a git commit. The tool's model is that the artefact is a Markdown file in a repository, which is excellent for a static site and for an auditable archive, and wrong for anything that wants a database, an API or a feed. The `DISPATCH_TOKEN` hook is the escape hatch for a second repository, but it is a rebuild trigger rather than a data interface.

The fourth case is scraping as a strategy. If the data comes from the website rather than the API, the fetcher breaks when the site changes, and the failure looks like an empty list rather than an error. For a project that has to run unattended for years, that is a poor foundation, and the Product Hunt developer token that the setup requires is the same token that would give a stable API path.

One last observation on the scale of the thing. The project is a script, a workflow file and a data directory, and the readme says the scripts are easy to extend or modify, which is an accurate description of a project of this size. That is a strength if you want to adapt it, and it is also why there is no framework, no abstraction layer and no plugin system: the point is that you can read the whole thing and change it.

Editorial conclusion

The tool fits a Chinese-language publication that wants a daily Product Hunt roundup without a person writing it, and it fits a reader who wants to see the workflow of a scheduled content pipeline end to end. It does not fit a project that needs the data to be a faithful record rather than a translation, because every description passes through a language model. Before you point it at your own repository, read the generated Markdown rather than trusting the output, and note that the pipeline needs three secrets, an OpenAI key, a Product Hunt developer token and a personal access token with write access to the repository.

Frequently asked questions

What does the producthunt-daily-hot project do?

It is a GitHub Actions based tool that fetches the previous day's Product Hunt top 30, generates short Chinese keywords and GPT-4 translations of the descriptions, writes a Markdown file into the `data/` directory, and commits it to the repository automatically.

Which secrets does the producthunt-daily-hot workflow need?

Four: `OPENAI_API_KEY` for the model calls, `PRODUCTHUNT_DEVELOPER_TOKEN` for the Product Hunt API, `PAT` as the personal access token used to push the changes, and the optional `DISPATCH_TOKEN` which notifies a downstream repository such as a website to update after a commit.

How do I change the schedule or the output format?

The schedule lives in `.github/workflows/generate_markdown.yml` and can be adjusted there, and the output format is produced by `scripts/product_hunt_list_to_md.py`, which you can modify to customise the generated file or add extra product details. The workflow runs daily at 07:01 UTC, which is 15:01 Beijing time, and can also be triggered manually.

Where are the generated producthunt-daily-hot files stored and what are they named?

In the `data/` directory, with each file named `PH-daily-YYYY-MM-DD.md`. The published list is shown daily on decohack.com under the producthunt category, with search and browsing by month of past issues.

Official sources

  1. Issues
  2. License: MIT
  3. Project website
  4. README
  5. ViggoZ/producthunt-daily-hot on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/viggoz-producthunt-daily-hot.svg)](https://hysenlabs.com/projects/viggoz-producthunt-daily-hot)

Was this useful?