Browse by type
...
Requires Python 3.10 or above.
pip install -U tg-signer
Or install the performance extras:
pip install "tg-signer[speedup]"
tg-signer also ships with a WebUI. Install it with:
pip install "tg-signer[gui]"

Two prebuilt images are published on GitHub Container Registry:
ghcr.io/amchii/tg-signer:<tag> (CLI) and
ghcr.io/amchii/tg-signer:<tag>-webui (CLI + WebUI).
If you want to build the image yourself, the local build flow is still available. See the Dockerfiles in the docker directory and its README.
Usage: tg-signer [OPTIONS] COMMAND [ARGS]...
Use <subcommand> --help for usage instructions
Subcommand aliases:
run_once -> run-once
send_text -> send-text
Options:
-l, --log-level [debug|info|warn|error]
Log level: `debug`, `info`, `warn`, `error`
[default: info]
--log-file PATH Log file path, can be relative [default: logs/tg-
signer.log]
--log-dir PATH Log directory, can be relative [default: logs]
-p, --proxy TEXT Proxy address, for example:
socks5://127.0.0.1:1080. Overrides the
`TG_PROXY` environment variable [env var:
TG_PROXY]
--session_dir PATH Directory used to store TG sessions, can be
relative [default: .]
-a, --account TEXT Custom account name. The session file will be
named <account>.session [env var: TG_ACCOUNT;
default: my_account]
-w, --workdir PATH tg-signer working directory, used to store
configs and check-in records [default: .signer]
--session-string TEXT Telegram Session String. Overrides the
`TG_SESSION_STRING` environment variable
[env var: TG_SESSION_STRING]
--in-memory Store the session in memory instead of a file
--help Show this message and exit.
Commands:
export Export configuration, defaults to stdout
import Import configuration, defaults to stdin
list List existing configurations
list-members List chat members (groups or channels; channels require
admin permissions)
list-sign-records List the latest N check-in records
list-topics List group topic IDs (`message_thread_id`)
list-schedule-messages Show configured scheduled messages
llm-config Configure the LLM API
login Log in to an account (used to obtain a session)
migrate-sign-records Migrate check-in records from JSON to SQLite (keeps the
original files by default)
logout Log out and delete the session file
monitor Configure and run monitoring
multi-run Run multiple accounts with a shared configuration
reconfig Reconfigure
run Run check-in tasks based on task configuration
run-once Run a check-in task once, even if it has already run
today
schedule-messages Batch configure Telegram's built-in scheduled messages
send-dice Send one DICE message. Make sure the current session has
already "seen" this `chat_id`
send-text Send one text message. Make sure the current session has
already "seen" this `chat_id`
version Show version
webgui Start the WebGUI (requires
`pip install "tg-signer[gui]"`)
Examples:
tg-signer run
tg-signer run my_sign # Run the 'my_sign' task directly, without prompting
tg-signer run-once my_sign # Run the 'my_sign' task once directly
tg-signer list-sign-records linuxdo -n 5 # View the latest 5 check-in records for task linuxdo
tg-signer migrate-sign-records # Migrate check-in records under .signer/signs to SQLite
tg-signer send-text 8671234001 /test # Send '/test' to chat_id '8671234001'
tg-signer send-text @neo /test # Send '/test' to username '@neo'
tg-signer send-text --message-thread-id 1 -- -1003763902761 checkin # Send to a group topic (message_thread_id=1)
tg-signer send-text -- -10006758812 water # For negative numbers, use POSIX style and add '--' before '-'
tg-signer send-text --delete-after 1 8671234001 /test # Send '/test' to chat_id '8671234001' and delete it after 1 second
tg-signer list-members --chat_id -1001680975844 --admin # List channel admins
tg-signer list-topics --chat_id -1003763902761 --limit 50 # List group topics and message_thread_id
tg-signer schedule-messages --crontab '0 0 * * *' --next-times 10 -- -1001680975844 hello # Send a message to '-1001680975844' at 00:00 for the next 10 days
tg-signer schedule-messages --crontab '0 0 * * *' --next-times 3 --message-thread-id 1 -- -1003763902761 hello # Configure scheduled messages for a group topic
tg-signer monitor run # Configure and run personal/group/channel message monitoring and auto reply
tg-signer multi-run -a account_a -a account_b same_task # Run 'account_a' and 'account_b' using the same 'same_task' config
tg-signer webgui --auth-code averycomplexcode # Start the WebGUI
tg-signer does not read the system proxy. Use the TG_PROXY environment
variable or the --proxy argument instead.
For example:
export TG_PROXY=socks5://127.0.0.1:7890
tg-signer login
Follow the prompts to enter your phone number and verification code. The command will print your recent chats, so make sure the chat you want to use for check-ins is included.
Signer chat_id also supports integer IDs and @-prefixed usernames such as
@neo.
For forum-style groups, the login output also prints each topic's
message_thread_id, which can be used directly with --message-thread-id.
Scheduling-related commands such as run and schedule-messages resolve the
time zone in the following order:
TZ environment variableAsia/Shanghai as the final fallbackIf you need schedules to follow a specific time zone, set TZ before starting
the process.
tg-signer list-topics --chat_id -1003763902761
This prints the visible topics in the forum group, including each
message_thread_id, title, and status, which makes topic-based configuration
much easier.
tg-signer send-text 8671234001 hello # Send 'hello' to chat_id '8671234001'
tg-signer send-text @neo hello # Send 'hello' to username '@neo'
tg-signer run
Or specify the task name in advance:
tg-signer run linuxdo
Then follow the prompts to configure it.
Start configuring task <linuxdo>
Check-in 1
1. Chat ID (from recent chats during login or @username): 7661096533
2. Chat name (optional): jerry bot
3. Send to a topic (`message_thread_id`)? (y/N): y
4. message_thread_id: 1
5. Start configuring <actions>. Please configure them in the real check-in order.
1: Send plain text
2: Send a Dice emoji
3: Click a keyboard button based on text
4: Select an option based on an image
5: Reply to a math question
Action 1:
1. Enter the number of the action: 1
2. Enter the text to send: checkin
3. Continue adding actions? (y/N): y
Action 2:
1. Enter the number of the action: 3
2. Enter the keyboard button text to click: Check in
3. Continue adding actions? (y/N): y
Action 3:
1. Enter the number of the action: 4
Image recognition uses the configured LLM. Make sure your model supports image input.
2. Continue adding actions? (y/N): y
Action 4:
1. Enter the number of the action: 5
Math questions are answered by the configured LLM.
2. Continue adding actions? (y/N): y
Action 5:
1. Enter the number of the action: 2
2. Enter the dice emoji to send (for example 🎲, 🎯): 🎲
3. Continue adding actions? (y/N): n
Before running, set `OPENAI_API_KEY` and `OPENAI_BASE_URL` correctly via environment variables.
The default model is "gpt-4o", and can be changed with `OPENAI_MODEL`.
6. Delete the check-in message after N seconds (wait N seconds after sending before deleting; enter '0' for immediate deletion, or press Enter to keep it), N: 10
╔════════════════════════════════════════════════╗
║ Chat ID: 7661096533 ║
║ Name: jerry bot ║
║ Message Thread ID: 1 ║
║ Delete After: 10 ║
╟────────────────────────────────────────────────╢
║ Actions Flow: ║
║ 1. [Send plain text] Text: checkin ║
║ 2. [Click by text] Click: Check in ║
║ 3. [Select by image] ║
║ 4. [Reply to math question] ║
║ 5. [Send Dice emoji] Dice: 🎲 ║
╚════════════════════════════════════════════════╝
Check-in 1 configured successfully
Continue configuring check-ins? (y/N): n
Daily check-in time (time or crontab expression, such as '06:00:00' or '0 6 * * *'):
Random time deviation in seconds (default is 0): 300
tg-signer monitor run my_monitor
Then follow the prompts.
Start configuring task <my_monitor>
Both chat IDs and user IDs support either integer IDs or string usernames. Usernames must start with @, such as @neo.
Configure monitor item 1
1. Chat ID (the ID shown in the recent chats output during login): -4573702599
2. Match rule ('exact', 'contains', 'regex', 'all'): contains
3. Rule value (required): kfc
4. Only match messages from specific user IDs (comma-separated; press Enter to match all): @neo
5. Default text to send: V Me 50
6. Regex used to extract the text to send from the message:
7. Delete the sent message after N seconds (wait N seconds after sending before deleting; enter '0' for immediate deletion, or press Enter to keep it), N:
Continue configuring? (y/N): y
Configure monitor item 2
1. Chat ID (the ID shown in the recent chats output during login): -4573702599
2. Match rule ('exact', 'contains', 'regex'): regex
3. Rule value (required): Participation keyword: 「.*?」
4. Only match messages from specific user IDs (comma-separated; press Enter to match all): 61244351
5. Default text to send:
6. Regex used to extract the text to send from the message: Participation keyword: 「(?P<keyword>(.*?))」\n
7. Text template to send (supports {extracted}/{group1}/named groups; press Enter if not needed): Join {keyword}
8. Delete the sent message after N seconds (wait N seconds after sending before deleting; enter '0' for immediate deletion, or press Enter to keep it), N: 5
Continue configuring? (y/N): y
Configure monitor item 3
1. Chat ID (the ID shown in the recent chats output during login): -4573702599
2. Match rule (exact, contains, regex, all): all
3. Only match messages from specific user IDs (comma-separated; press Enter to match all):
4. Always ignore messages sent by yourself (y/N): y
5. Default text to send (press Enter if not needed):
6. Use AI to reply? (y/N): n
7. Regex used to extract the text to send from the message (press Enter if not needed):
8. Push messages through ServerChan? (y/N): n
9. Forward to external endpoints (UDP, HTTP)? (y/N): y
10. Forward to UDP? (y/N): y
11. Enter the UDP server address and port (for example `127.0.0.1:1234`): 127.0.0.1:9999
12. Forward to HTTP? (y/N): y
13. Enter the HTTP endpoint (for example `http://127.0.0.1:1234`): http://127.0.0.1:8000/tg/user1/messages
Continue configuring? (y/N): n
Both chat_id and user_id support integer IDs and string usernames.
Usernames must start with @, so use @neo instead of neo. Note that a
username may not exist. In the example above, chat_id=-4573702599 means the
rule only applies to that chat.
Matching rules are currently all case-insensitive:
exact means exact match. The message content must equal the configured
value.
contains means substring matching. For example, if contains="kfc",
the message "I like MacDonalds rather than KfC" still matches.
regex means regular expression matching. See
Python regular expressions.
A match is triggered as soon as the pattern is found anywhere in the
message. In the example above, Participation keyword: 「.*?」 can match
a message like:
A new lottery has been created... Participation keyword: 「I want to join」
Please DM the bot first
You can restrict matches to messages from specific users only, for example, group admins instead of any random participant.
You can configure a default outgoing text, meaning the configured text is sent immediately whenever a message matches.
You can extract outgoing text with a regex such as `Participation keyword: 「(?P.*
$ claude mcp add tg-signer \
-- python -m otcore.mcp_server <graph>