tiennm99 56d71a0e79 refactor(store): drop the Telethon session import
The Go session is already stored, so the one-time conversion from the
Python version's Telethon session is no longer needed. Remove it along
with its tests and the README upgrade section.
2026-10-15 14:38:28 +07:00
2026-10-15 14:22:22 +07:00
2026-10-15 14:22:22 +07:00
2026-10-15 14:22:22 +07:00
2026-10-15 14:22:22 +07:00
2026-10-15 14:22:22 +07:00
2024-03-29 21:41:03 +07:00

export-telegram-group-members

Export Telegram group members with Go and gotd/td. Admin rights give full member visibility. The login session and export history live in Redis, so you can run the tool on any device from just a .env file: no re-login and no copying session or CSV files.

How to use

  1. Clone this repository and install Go:
git clone https://github.com/tiennm99/export-telegram-group-members.git
  1. Create a new Telegram app at https://my.telegram.org and get the api_id and api_hash.
  2. Create a free Redis database (e.g. Upstash) and copy its rediss:// connection URL.
  3. Copy .env.example to .env and fill in REDIS_URL.
  4. Store Telegram config in Redis:
go run ./cmd/configure

configure prompts for api_id, api_hash, phone, and group IDs. You can pass any of them as flags instead: --api-id, --api-hash, --phone, and --groups -1001234567890,-1009876543210. All commands read the stored group IDs from this Redis config.

  1. Crawl the configured groups:
go run ./cmd/crawl

Every group ID stored in the Redis config is crawled. To change the list, run configure again.

To crawl other groups just once, pass their IDs; they replace the configured list for that run only:

go run ./cmd/crawl -1001234567890 -1009876543210

The first crawl asks for the Telegram login code once, then stores the session in Redis. Any later run on any device pointed at the same Redis reuses the Redis config and session and does not prompt again.

Group IDs use the usual marked form: -100<id> for supergroups and channels, -<id> for basic groups. The account must already be a member of each group.

Compare two crawls

Compare membership changes for one group between two saved crawls with git-diff-style terminal output:

go run ./cmd/compare <group_id> <time1> <time2>

If time1 and time2 are omitted, the command compares the latest two crawls for that group:

go run ./cmd/compare <group_id>

If group_id is also omitted, the command uses the first group in the stored configuration:

go run ./cmd/compare

Compare two groups

Fetch two groups live from Telegram and compare their members by Telegram ID:

go run ./cmd/compare-groups <group_id_a> <group_id_b>

Members in both groups are listed unprefixed, members only in the first group with -, and members only in the second group with +. No crawl is saved to Redis; the command uses Redis only for the Telegram config and login session, the same way crawl does.

Export a crawl to CSV

Export one group's saved crawl from Redis:

go run ./cmd/export [group_id] [timecrawl]

When timecrawl is omitted, the latest crawl for the group is exported. When both arguments are omitted, the first group in the stored configuration and its latest crawl are used. An explicit crawl time must use yyyymmddhhmmss format:

go run ./cmd/export -1001234567890 20260724120000

CSV files are written to:

output/<group-id>-<yyyymmddhhmmss>.csv

Each file contains the columns id, username, first_name, and last_name. Formula-like Telegram text is prefixed with an apostrophe for safe spreadsheet opening. On POSIX systems, the output/ directory is created with 0700 permissions and each CSV file is written with 0600 permissions. The output/ directory is ignored by Git.

Build binaries

The code is pure Go, so static binaries build without cgo:

CGO_ENABLED=0 go build -o bin/ ./cmd/...

Configuration

Variable Description
REDIS_URL Redis connection string (rediss://default:<password>@<host>:<port>)

Telegram api_id, api_hash, phone, and group_ids are stored in Redis by configure.

How data is stored

All data lives in Redis under the telegram-export prefix. No key references another, so deleting any key can never corrupt another's state:

telegram-export:config                         -> JSON config:
                                 { api_id, api_hash, phone, group_ids }
telegram-export:session-gotd                   -> gotd session JSON (login)
telegram-export:group:<group_id>:<yyyymmddhhmmss> -> one group's export as JSON:
                                 { group_id, title, time,
                                   members: [{ id, username, first_name, last_name }] }

All groups in one crawl share one timestamp. The login session grants full account access, so restrict Redis access accordingly; deleting telegram-export:session-gotd forces a clean re-login.

Development

go vet ./...
go test ./...

Tests run offline: Redis is faked with miniredis, and Telegram calls are not exercised.

S
Description
Export Telegram group members to CSV using Telethon — admin auth required for full member visibility.
Readme Apache-2.0
514 KiB
0 Stars 1 Watchers 0 Forks
Languages
Go 100%