tiktoker
Version, currently 0.1.0-pre1 version
- 0.1.0-prelatestMay 2, 2021
github.com/lucasintel/tiktoker
Command-line client and API wrapper for TikTok
6 stars
0 dependents
License: MIT
Installation
# Add this to your shard.yml
dependencies:
tiktoker:
github: lucasintel/tiktoker
version: ~> 0.1.0-preThen run:
shards installshard.yml
- Crystal
1.0.0- License
- MIT
- Author
- kandayo <kdy@absolab.xyz>
- Target
tiktokerfrom src/cli.cr
Dependencies
Runtime Dependencies
- crest*github: kandayo/crest, branch: kdy/expose-timeouts
- tallboy*github: epoch/tallboy
- progress*github: kandayo/progress.cr
- retriable*github: Sija/retriable.cr
Development Dependencies
- webmock*github: manastech/webmock.cr, branch: masterdev
README
# TikToker
[](https://crystal-lang.org/)
[](https://github.com/kandayo/tiktoker/releases)
TikToker is a **command-line client for TikTok**. It allows you to search and
browse users from the terminal, and to download videos and its metadata from an
user profile or from a hashtag.
For now, you'll have to spin up a signature server, used to sign requests to
the Tiktok API. See [**TikTok Passport**](https://github.com/kandayo/tiktok-passport).
## Index
- [Features](#features)
- [Disclaimer](#disclaimer)
- [Installation](#installation)
- [Pre-built - Recommended](#pre-built--recommended)
- [From source](#from-source)
- [Flags](#flags)
- [Incremental sync](#incremental-sync)
- [Verbosity](#verbosity)
- [Cronjob mode](#cronjob-mode)
- [Error handling](#error-handling)
- [Commands](#commands)
- [Find user](#find-user)
- [Search user](#search-user)
- [Download user profile](#download-user-profile)
- [Download from batch file](#download-from-batch-file)
- [As a library](#as-a-library)
- [Installation as a shard](#installation-as-a-shard)
- [Configuration](#configuration)
- [Iterators](#iterators)
- [Client](#client)
- [Manually building a request](#manually-building-a-request)
- [Manually signing a request](#manually-signing-a-request)
- [Development](#development)
- [Dockerized environment](#dockerized-environment)
- [Local](#local)
- [Contributing](#contributing)
- [Contributors](#contributors)
- [License](#license)
## Features
- Download public and private profiles.
- Download hashtags.
- **Built with archivists in mind: incremental sync.**
- Automatically resumes previously-interrupted download iterations to prevent rate limiting.
- JSON metadata is stored alongside the video.
- Batch file, cronjob friendly.
## Disclaimer
This lib is in no way affiliated with, authorized, maintained or endorsed by
TikTok or any of its affiliates or subsidiaries.
This is purely an educational proof of concept.
## Installation
### Pre-built - Recommended
Just download the latest release for your platform [here](https://github.com/kandayo/tiktoker/releases).
Then move the binary to your PATH, or just use it right away.
### From source
It only takes a few seconds to compile it yourself. It's not rocket science.
Build dependencies:
- Crystal language, https://crystal-lang.org/install
```bash
$ git clone https://github.com/kandayo/tiktoker
$ cd tiktoker
$ shards build --release --ignore-crystal-version
$ ./bin/tiktoker --help
```
Then move the binary to your PATH, or just use it right away.
## Flags
### Incremental sync
If `--fast-update` (or `-f`) is given, TikToker stops when arriving at the
first already downloaded video. This flag is recommended when you use TikToker
to update your personal archive.
This concept was inspired by Instaloader.
```
$ tiktoker download user charlidamelio --fast-update
Collecting videos from user feed -- username: charlidamelio
+ Charli D’amelio - 000002.mp4 [========================] 11.1 MB | 100%
+ Charli D’amelio - 000001.mp4; exists
✅ Charli D’amelio in sync!
```
### Verbosity
If `--verbose` (or `-V`) is given, TikToker will print debug information for
each operation. You can use it to inspect request/response params, headers and
body.
### Cronjob mode
If `--quiet` (or `-q`) is given, TikTok will not produce any output (except
error messages). The download progress bar is disabled as well. This makes
TikToker suitable as a cron job.
### Error handling
Network errors are gracefully retried following a randomized exponential
backoff technique. This behaviour is customizable.
```
--retry-attempts [attempts; default: 10]
Maximum number of retry attempts until a request is aborted.
--connect-timeout [seconds; default: 5]
Timeout waiting for TikTok server connection to open in seconds.
--write-timeout [seconds; default: 5]
Timeout when waiting for TikTok server to receive data.
--read-timeout [seconds; default: 5]
Timeout when waiting for TikTok server to return data.
```
## Commands
See `tiktoker --help`. For more examples, please refer to the [**documentation**](https://absolab.xyz/tiktoker).
### Find user
*Usage: tiktoker user [username] [--feed]*
```
$ tiktoker user charlidamelio
┌───────────────────────────────────────────────────────────────────────┐
│ charli d’amelio [Verified] │
│ @charlidamelio │
├─────────────────┬─────────────────┬─────────────────┬─────────────────┤
│ 1.21K Following │ 114M Followers │ 9.2B Likes │ 1763 Videos │
└─────────────────┴─────────────────┴─────────────────┴─────────────────┘
┌─────────────────────────────────────────────────────────────────┬───────┬───────┬──────────┐
│ URL │ Views │ Likes │ Comments │
├─────────────────────────────────────────────────────────────────┼───────┼───────┼──────────┤
│ https://www.tiktok.com/@charlidamelio/video/6957450991809662214 │ 8.8M │ 2.5M │ 188K │
│ https://www.tiktok.com/@charlidamelio/video/6957004076668177670 │ 17.3M │ 3.7M │ 457K │
│ https://www.tiktok.com/@charlidamelio/video/6956671135194844422 │ 14.2M │ 2.4M │ 77.0K │
│ https://www.tiktok.com/@charlidamelio/video/6956651282199284997 │ 22.5M │ 4.5M │ 78.1K │
│ https://www.tiktok.com/@charlidamelio/video/6956256557197790469 │ 20.3M │ 3.8M │ 111K │
│ https://www.tiktok.com/@charlidamelio/video/6955937279537990918 │ 18.2M │ 3.1M │ 94.0K │
└─────────────────────────────────────────────────────────────────┴───────┴───────┴──────────┘
[...]
```
You can also get more specific information about an user.
```
SecUID : MS4wLjABAAAA-VASjiXTh7wDDyXvjk10VFhMWUAoxr8bgfO1kAL1-9s
ID : 5831967
Avatar : https://p16-sign-va.tiktokcdn.com/musically-maliva-obj/0a0242e5f906bf9301f859c568b5ecc4~c5_1080x1080.jpeg
Registered at : Saturday, 14 Nov 2015 12:57
Comment settings : Everyone
Duet settings : Everyone
Stitch settings : Everyone
[...]
```
### Search user
*Usage: tiktoker search user [criteria] [--cursor]*
```
$ tiktoker search user charlidamelio
┌───────────────────┬───────────────────────────────┬───────────┬──────────┐
│ Username │ Nickname │ Followers │ Verified │
├───────────────────┼───────────────────────────────┼───────────┼──────────┤
│ charlidamelio │ charli d’amelio │ 113.9M │ true │
│ augustrush │ charli d’amelio’s Adopted Bro │ 1.5M │ true │
│ charlidamelio6650 │ Charli Damelio │ 502.2K │ false │
│ charlidameilo │ charli d’amelio │ 333.2K │ false │
│ cactiboy │ Charli D’amelio │ 208.1K │ false │
│ blidmor │ charlidamelio │ 154.3K │ false │
└───────────────────┴───────────────────────────────┴───────────┴──────────┘
[...]
```
### Download user profile
*Usage: tiktoker download user [username or SecUID] [--fast-update] [--cursor]*
```
$ tiktoker download user charlidamelio
Collecting videos from user feed -- username: charlidamelio
+ Charli D’amelio - 6957004076668177670.mp4 [========================] 11.1 MB | 100%
+ Charli D’amelio - 6956671135194844422.mp4 [========================] 19.2 MB | 100%
+ Charli D’amelio - 6957004076668177670.mp4 [========================] 14.1 MB | 100%
+ Charli D’amelio - 6956671135194844422.mp4 [========================] 23.3 MB | 100%
[...]
```
### Download from batch file
*Usage: tiktoker download batch [file] [--fast-update]*
If `--batch-file <file.txt>` (or `-a`) is given, TikToker will read *file.txt*
expecting @usernames and SecUIDs to download, one identifier per line. Lines
starting with an `#` or empty lines are considered as comments and ignored.
Usernames must be prefixed with an `@`, e.g. `@username`, `@charlidamelio`.
SecUIDs must not be prefixed with an `@`, e.g. `MS4wLjABA[...]`.
```bash
$ cat batch.txt
~> # Comment (ignored)
~> MS4wLjABAAAA-VASjiXTh7wDDyXvjk10VFhMWUAoxr8bgfO1kAL1-9s
~> @charlidamelio # Inline comments are also allowed.
$ tiktoker download batch file.txt
```
## As a library
### Installation as a shard
1. Add the dependency to your `shard.yml`:
```yaml
dependencies:
tiktoker:
github: kandayo/tiktoker
```
2. Run `shards install --ignore-crystal-version`.
### Configuration
```cr
require "tiktoker"
TikToker.config.with do |config|
config.signature_server_url = "http://passport.internal.docker"
config.retry_attempts = 0
end
```
### Iterators
A iterator allows transparently iterating a resource by page.
```cr
iterator = TikToker::ProfileIterator.new(SecUID, cursor)
iterator.next # => Page 1
iterator.next # => Page 2
iterator.next # => Iterator::Stop
```
Most of the time, what you really want is to iterate through the posts without
having to worry about pagination.
```cr
iterator = TikToker::ProfileIterator.new(SecUID, cursor)
iterator.each_post do |post|
post # => TikTok::Post
end
```
### Client
For more examples, please refer to the [**documentation**](https://absolab.xyz/tiktoker).
```cr
TikToker.find_user(username) # => TikTok::UserProfile
TikToker.find_user_secuid(username) # => "MS4wLjABAAAA-VASjiXTh7wDDyXvjk10VFhMWUAoxr8bgfO1kAL1-9s"
TikToker.user_profile_feed(SecUID, cursor) # => TikTok::PostCollection
TikToker.search_user(term, cursor) # => TikTok::SearchResult
```
### Manually building a request
```cr
request = TikToker::RequestBuilder.search_user(term, cursor)
request # => TikToker::Request
request.build # => "https://m.tiktok.com/api/search/user/full?[...]"
```
### Manually signing a request
```cr
TikToker::RequestSigner.sign(request)
```
You can use your own signer backend. Make sure to define a `#call` instance
method and inherit from `RequestSigner::Backend`.
```cr
class CustomSigner < TikToker::RequestSigner::Backend
def initialize(@request : TikToker::Request)
end
def call : TikToker::SignedRequest
# ...
end
end
TikToker::RequestSigner.sign(request, backend: CustomSigner)
```
## Development
### Dockerized environment
Dependencies:
- Docker
- Docker compose
- Dip, https://github.com/bibendi/dip
Provision the project by running `dip provision` and then use `dip crystal`,
`dip spec` or `dip runner` to interact with the dockerized development
environment.
### Local
If you prefer developing on your local machine, make sure you have all
dependencies installed and running.
## Contributing
1. Fork it (<https://github.com/kandayo/tiktoker/fork>)
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create a new Pull Request
## Contributors
- [kandayo](https://github.com/kandayo) - creator and maintainer
## License
The lib is available as open source under the terms of the MIT License.
Documentation
Built from the current release. The first visit to a release nobody has asked for starts its build.
Links
This release
- Version
0.1.0-pre- Tagged
- May 2, 2021
- Commit
e701843026de- Crystal
1.0.0- Indexed
- yes
Dependents
No indexed shard depends on this one yet.
Repository
github.com/lucasintel/tiktoker
Metadata
- Created
- Aug 13, 2026
- Updated
- Aug 13, 2026
- Synced
- Aug 13, 2026
- Versions
- 1