Library / SDK
Womsxd/MihoyoBBSTools avatar
Womsxd/MihoyoBBSTools

MihoyoBBSTools: a scheduled check-in for the miHoYo community

Womsxd/AutoMihoyoBBS,米游社相关脚本

1,378 stars225 forksPythonMIT

At a glance

What is it?
A Python project that signs in to the miHoYo community site for a set of games and collects the daily community currency, with configuration held in YAML files and six ways to run it, from a local Python process to Docker, Kubernetes, serverless functions and a panel scheduler.
Who is it for?
MihoyoBBSTools fits a player of one of the supported games who wants the daily check-in handled without remembering to do it, and who is comfortable managing a cookie and a token for their own account.
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 115 days 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 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the project does

MihoyoBBSTools is a Python 3 project for assisted check-in on the miHoYo community site, and its purpose is narrow and concrete.

The first function is automatically collecting the community currency, which is what the site awards for a daily sign-in. The second is the coverage: for the Chinese server it supports check-in for Honkai Impact 2nd, Honkai Impact 3rd, Tears of Themis, Genshin Impact, Honkai Star Rail and Zenless Zone Zero, and for the international server it supports Honkai Impact 3rd, Tears of Themis, Genshin Impact, Honkai Star Rail and Zenless Zone Zero.

So this is not a game tool in any sense. It does not touch the game, it does not modify a client and it does not read any local state. It signs in to a website, as a person would, and collects what the site gives for signing in.

The implementation is a set of small modules at the root of the repository, and the names describe the pieces: `main.py` and `main_multi.py` for the single and multi-user entry points, `index.py` for the cloud function handler, `account.py` for the account model, `login.py` for the session, `mihoyobbs.py` for the community site, `gamecheckin.py` and `hoyo_checkin.py` for the per-game sign-in, `cloudgames.py`, `os_cloudgames.py` and `competition.py` and `web_activity.py` for the other activities the site offers, `captcha.py` for the case where the site asks for one, `config.py` and `setting.py` for configuration, `request.py` for HTTP, `tools.py`, `push.py` for notifications, `loghelper.py`, `error.py`, `server.py` for the command panel, `ql_main.py` for the panel scheduler, and `template.yml` alongside them.

The project is MIT licensed, the primary language is Python, the default branch is `master`, and the last push was on 2026-06-30. There are no GitHub releases.

The credentials, and how the site changed underneath them

The authentication story is the part of this project that tells you most about it, and the documentation is unusually candid about the fragility.

The flow is that the user signs in to the community site in a private browsing window, opens the developer tools, uses the network filter to find the request named `getUserGameUnreadCount`, and copies the contents of the `Cookie` header from that request. The reason for the private window is to avoid copying a cookie that is already polluted with other state, and the reason for the `getUserGameUnreadCount` filter is that the operator changed which cookies the site exposes, so a cookie obtained the obvious way comes out missing pieces, and the extra filtering step is what puts it back together.

The international version has a shorter path, because the site sets the token in a way the browser console can read directly, and the documentation instructs the user to copy from the `ltoken` onwards.

The second credential is a stoken, and the documentation points at a companion login project for obtaining it, with an alternative route through a third-party cookie service, with a request to turn the BBS module off in that configuration.

So the whole security model of this project is that a person pastes their own session credentials into a YAML file that the script then replays. That is the design, and it is a reasonable one for a personal script, and it is also why the configuration file is the sensitive artefact in the repository and why the multi-user mode exists at all: each user has their own file, and the script scans the directory and runs them in name order.

Configuration is a directory of YAML files

The configuration model is the simplest thing about the project and the reason the multi-user mode is easy.

The setup instructions say to copy the `config.yaml.example` from the `config` folder and rename it to `config.yaml`. The multi-user feature works by reading different configuration files, and the script scans the `config` directory for files with the `yaml` extension and runs them in name order, so a user can create any number of files with custom names.

Each file holds the credentials and the switches. The `cookie` and `stoken` values go into the `account` section, and the features that are switched on are controlled by `enable` values, one per feature, with the note that the BBS module can be turned off when the third-party cookie route is used. The multi-user mode is a separate entry point, `main_multi.py`, and it has an `autorun` argument for the case where the script has to run on its own.

The three deployment targets each read the same configuration format, which is what makes the project portable between them. The environment variable `CRON_SIGNIN` in the container sets the schedule, and the compose file sets it to 30 9, which is nine in the morning. The Kubernetes path expects a copy of the example file in the `kube` directory, and the panel path expects a specific prefix on the file names for the multi-user case, which the environment variable `AutoMihoyoBBS_config_prefix` provides when it is not configured by hand.

Six ways to run the same script

The documentation covers a surprising number of environments, and the reason is that this tool is meant to run unattended on hardware that is not a workstation.

Locally, it is `python main.py` for one account, `python main_multi.py` for several, and `python main_multi.py autorun` when it should run by itself. There is also a command panel mode, `python3 server.py`, with a screen session for running it in the background, and a small set of console commands: stop, mulit, single, reload, a mode switch, a cookie add, a task interval and an enable toggle.

In Docker, the compose file is the whole configuration:

yaml
version: "3"

services:
  mihoyo-bbs:
    image: womsxd/mihoyo-bbs
    restart: always
    environment:
      - CRON_SIGNIN=30 9 * * *
      - MULTI=TRUE
    volumes:
      - ./config:/var/app/config
    logging:
      driver: "json-file"
      options:
        max-size: "1m"

The configuration directory is mounted, so edits on the host are visible in the container immediately, and the image runs the Python entry point through a small `docker.py`. The Dockerfile is based on `python:3-alpine`, sets the timezone to Asia/Shanghai, and the default schedule is again nine in the morning. There are also Dockerfiles for arm32v7 and arm64v8, which is the usual sign that the tool is deployed on small single board computers as well as on servers.

On Kubernetes, the steps are a ConfigMap from the configuration file and an apply of the deployment, and then the logs are read from the pod the deployment created.

The two cloud function routes, on Tencent Cloud and on Alibaba Cloud, install the requirements into the function directory, run the script once locally to create the state, upload the folder, set the handler to `index.main_handler` or `index.main_handler_mulit`, raise the timeout to 300 seconds, and configure a scheduled trigger. The documentation notes that cloud functions now cost money on both providers.

And the panel route, for the Qinglong scheduler, subscribes to the repository as a public repository with a crontab rule and a whitelist of modules, or pulls it with a command, and then the environment variables point the tool at the configuration directory, the multi-user switch and the prefix, with the project's own push implementation used when the user prefers it.

The project asks not to be publicised, and explains why

Three instructions at the top of the README are unusual enough to be worth reading as a design decision.

The first asks not to publicise the project widely. The second asks people not to post about it on Bilibili. The third asks not to abuse the project.

The warning that follows explains the practical reason, and it is a good one. For developers who fork the project or use it, do not abuse GitHub Actions, because GitHub will count the Actions usage of your branch against the upstream repository, which may lead to GitHub disabling that upstream repository. In other words, a popular fork running a scheduled workflow on the upstream's source would spend the maintainer's Actions quota, and the maintainer is asking people not to do it.

That is a small and very human piece of infrastructure engineering, and it also tells you something about the deployment story. The most natural way to run this script on a schedule is a GitHub Action, and the most natural way to run it that way is to fork the repository, so the request not to do that is a request about a real pattern rather than a formality.

It also explains the breadth of the deployment documentation. If the intended runners are a personal machine, a home server, a small board, a Kubernetes cluster and a serverless function, then the supported paths are the supported paths, and the tool has to work in all of them.

Where this tool is the wrong one

The limits are structural, and they come from the fact that the tool is a script against a private endpoint of a game operator.

The first is that the target can change without notice, and the documentation says so. The operator modified which cookies the site exposes, which broke the obvious way of obtaining one, and the workaround is a specific filtering step in the developer tools. A script that depends on an undocumented request shape, a particular cookie and a token has a maintenance relationship with the service, and the person carrying it is whoever runs the script.

The second is that failure is quiet. The script's output is a sign-in result, and a sign-in that stops working because a cookie expired looks much like a sign-in that was already done. There is a `captcha.py` in the module list, which tells you the site does sometimes present a verification step, and a project that has to handle that has a dependency on a challenge it cannot solve. A tool that reports nothing when it stops working is a poor thing to put on a schedule and forget.

The third is the licence of the account you are using. The project is for your own account, and the multi-user mode exists for people with several accounts, which is the case the mode was built for.

The alternative, for somebody who does not want to manage credentials, is to sign in manually once a day, which is the whole value the script provides. The difference in approach is that this project automates a private endpoint that a commercial operator can change, and the alternative automates nothing and therefore breaks on nothing, and for a task worth thirty seconds a day the manual route is often the one that survives.

Editorial conclusion

MihoyoBBSTools fits a player of one of the supported games who wants the daily check-in handled without remembering to do it, and who is comfortable managing a cookie and a token for their own account. It is the wrong tool for a team that needs a supported integration, because the whole thing is a set of calls to a private community endpoint that the operator can change, and it is the wrong choice for a deployment that has to be reliable in a way a personal script is not, since a silent failure looks exactly like a successful run. Before deploying it, pin the version of the tool and the version of the community endpoint together, because the README notes that the operator changed which cookies the site exposes, and read the note about forks and GitHub Actions quota before you fork it and run it in a workflow.

Frequently asked questions

What does MihoyoBBSTools automate?

It performs the daily check-in on the miHoYo community site to collect the community currency, supporting the Chinese and international servers for Honkai Impact 2nd, Honkai Impact 3rd, Tears of Themis, Genshin Impact, Honkai Star Rail and Zenless Zone Zero.

How does MihoyoBBSTools authenticate?

With a cookie and an stoken that you obtain yourself. The cookie is copied out of the browser developer tools by filtering the network log for the getUserGameUnreadCount request, and the stoken comes from a companion login project, with a documented alternative through a third-party cookie service that requires the BBS module to be turned off.

How do I run MihoyoBBSTools on a schedule?

Locally with `python main.py` or `python main_multi.py autorun`, in Docker with `docker-compose up -d`, where the compose file sets the CRON_SIGNIN schedule and a daily 9:30 default, on Kubernetes with a ConfigMap and the deployment manifest, or as a cloud function with a scheduled trigger.

Why does the MihoyoBBSTools README ask users not to publicise it?

Because a fork that runs GitHub Actions on the upstream repository has its usage counted against the upstream owner, which may lead to GitHub disabling that repository. The maintainers also ask not to post about the project elsewhere and not to abuse it.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. Womsxd/MihoyoBBSTools 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/womsxd-mihoyobbstools.svg)](https://hysenlabs.com/projects/womsxd-mihoyobbstools)

Was this useful?