Skip to content

Commit 4391ccf

Browse files
authored
feat(tiktok): add TikTok adapter with 15 commands (#202)
* feat(tiktok): add TikTok adapter with 15 commands TikTok (15 commands, browser mode): Read commands: - profile: user profile info via rehydration script parsing - search: search videos via internal search API - explore: trending videos from explore page (DOM scraping) - user: recent videos from a user page (DOM scraping) - following: list accounts you follow - friends: friend suggestions - live: browse live streams with viewer counts - notifications: activity notifications Write commands (verified with real interactions): - like/unlike: like or unlike a video by URL - save/unsave: add or remove video from Favorites - follow/unfollow: follow or unfollow a user - comment: comment on a video All write operations verified with live TikTok interactions. * docs: add missing adapter documentation for doc-coverage CI
1 parent ce484c2 commit 4391ccf

File tree

20 files changed

+877
-0
lines changed

20 files changed

+877
-0
lines changed

docs/adapters/browser/facebook.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Facebook
2+
3+
**Mode**: 🔐 Browser · **Domain**: `facebook.com`
4+
5+
## Commands
6+
7+
| Command | Description |
8+
|---------|-------------|
9+
| `opencli facebook profile` | Get user/page profile info |
10+
| `opencli facebook notifications` | Get recent notifications |
11+
| `opencli facebook feed` | Get news feed posts |
12+
| `opencli facebook search` | Search people, pages, posts |
13+
| `opencli facebook friends` | Friend suggestions |
14+
| `opencli facebook groups` | List your joined groups |
15+
| `opencli facebook memories` | On This Day memories |
16+
| `opencli facebook events` | Browse event categories |
17+
| `opencli facebook add-friend` | Send a friend request |
18+
| `opencli facebook join-group` | Join a group |
19+
20+
## Usage Examples
21+
22+
```bash
23+
# View a profile
24+
opencli facebook profile --username zuck
25+
26+
# Get notifications
27+
opencli facebook notifications --limit 10
28+
29+
# News feed
30+
opencli facebook feed --limit 5
31+
32+
# Search
33+
opencli facebook search --query "OpenAI" --limit 5
34+
35+
# List your groups
36+
opencli facebook groups
37+
38+
# Send friend request
39+
opencli facebook add-friend --username someone
40+
41+
# Join a group
42+
opencli facebook join-group --group 123456789
43+
44+
# JSON output
45+
opencli facebook profile --username zuck -f json
46+
```
47+
48+
## Prerequisites
49+
50+
- Chrome running and **logged into** facebook.com
51+
- [Browser Bridge extension](/guide/browser-bridge) installed

docs/adapters/browser/instagram.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Instagram
2+
3+
**Mode**: 🔐 Browser · **Domain**: `instagram.com`
4+
5+
## Commands
6+
7+
| Command | Description |
8+
|---------|-------------|
9+
| `opencli instagram profile` | Get user profile info |
10+
| `opencli instagram search` | Search users |
11+
| `opencli instagram user` | Get recent posts from a user |
12+
| `opencli instagram explore` | Discover trending posts |
13+
| `opencli instagram followers` | List user's followers |
14+
| `opencli instagram following` | List user's following |
15+
| `opencli instagram saved` | Get your saved posts |
16+
| `opencli instagram like` | Like a post |
17+
| `opencli instagram unlike` | Unlike a post |
18+
| `opencli instagram comment` | Comment on a post |
19+
| `opencli instagram save` | Bookmark a post |
20+
| `opencli instagram unsave` | Remove bookmark |
21+
| `opencli instagram follow` | Follow a user |
22+
| `opencli instagram unfollow` | Unfollow a user |
23+
24+
## Usage Examples
25+
26+
```bash
27+
# View a user's profile
28+
opencli instagram profile --username nasa
29+
30+
# Search users
31+
opencli instagram search --query nasa --limit 5
32+
33+
# View a user's recent posts
34+
opencli instagram user --username nasa --limit 10
35+
36+
# Like a user's most recent post
37+
opencli instagram like --username nasa --index 1
38+
39+
# Comment on a post
40+
opencli instagram comment --username nasa --text "Amazing!" --index 1
41+
42+
# Follow/unfollow
43+
opencli instagram follow --username nasa
44+
opencli instagram unfollow --username nasa
45+
46+
# JSON output
47+
opencli instagram profile --username nasa -f json
48+
```
49+
50+
## Prerequisites
51+
52+
- Chrome running and **logged into** instagram.com
53+
- [Browser Bridge extension](/guide/browser-bridge) installed

docs/adapters/browser/lobsters.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Lobsters
2+
3+
**Mode**: 🌐 Public · **Domain**: `lobste.rs`
4+
5+
## Commands
6+
7+
| Command | Description |
8+
|---------|-------------|
9+
| `opencli lobsters hot` | Hottest stories |
10+
| `opencli lobsters newest` | Latest stories |
11+
| `opencli lobsters active` | Most active discussions |
12+
| `opencli lobsters tag` | Stories by tag |
13+
14+
## Usage Examples
15+
16+
```bash
17+
# Quick start
18+
opencli lobsters hot --limit 10
19+
20+
# Filter by tag
21+
opencli lobsters tag --tag rust --limit 5
22+
23+
# JSON output
24+
opencli lobsters hot -f json
25+
26+
# Verbose mode
27+
opencli lobsters hot -v
28+
```
29+
30+
## Prerequisites
31+
32+
None — all commands use the public JSON API, no browser or login required.

docs/adapters/browser/medium.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Medium
2+
3+
**Mode**: 🌐 Public · **Domain**: `medium.com`
4+
5+
## Commands
6+
7+
| Command | Description |
8+
|---------|-------------|
9+
| `opencli medium publication` | Get recent articles from a publication |
10+
| `opencli medium tag` | Get top articles for a tag |
11+
| `opencli medium user` | Get recent articles by a user |
12+
13+
## Usage Examples
14+
15+
```bash
16+
# Get articles from a publication
17+
opencli medium publication --name towards-data-science
18+
19+
# Get top articles for a tag
20+
opencli medium tag --name programming
21+
22+
# Get articles by a user
23+
opencli medium user --name @username
24+
25+
# JSON output
26+
opencli medium tag --name ai -f json
27+
```
28+
29+
## Prerequisites
30+
31+
None — all commands use public endpoints, no browser or login required.

docs/adapters/browser/tiktok.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# TikTok
2+
3+
**Mode**: 🔐 Browser · **Domain**: `tiktok.com`
4+
5+
## Commands
6+
7+
| Command | Description |
8+
|---------|-------------|
9+
| `opencli tiktok profile` | Get user profile info |
10+
| `opencli tiktok search` | Search videos |
11+
| `opencli tiktok explore` | Trending videos from explore page |
12+
| `opencli tiktok user` | Get recent videos from a user |
13+
| `opencli tiktok following` | List accounts you follow |
14+
| `opencli tiktok friends` | Friend suggestions |
15+
| `opencli tiktok live` | Browse live streams |
16+
| `opencli tiktok notifications` | Get notifications |
17+
| `opencli tiktok like` | Like a video |
18+
| `opencli tiktok unlike` | Unlike a video |
19+
| `opencli tiktok save` | Add to Favorites |
20+
| `opencli tiktok unsave` | Remove from Favorites |
21+
| `opencli tiktok follow` | Follow a user |
22+
| `opencli tiktok unfollow` | Unfollow a user |
23+
| `opencli tiktok comment` | Comment on a video |
24+
25+
## Usage Examples
26+
27+
```bash
28+
# View a user's profile
29+
opencli tiktok profile --username tiktok
30+
31+
# Search videos
32+
opencli tiktok search --query "cooking" --limit 10
33+
34+
# Trending explore videos
35+
opencli tiktok explore --limit 20
36+
37+
# Browse live streams
38+
opencli tiktok live --limit 10
39+
40+
# List who you follow
41+
opencli tiktok following
42+
43+
# Friend suggestions
44+
opencli tiktok friends --limit 10
45+
46+
# Like/unlike a video
47+
opencli tiktok like --url "https://www.tiktok.com/@user/video/123"
48+
opencli tiktok unlike --url "https://www.tiktok.com/@user/video/123"
49+
50+
# Save/unsave (Favorites)
51+
opencli tiktok save --url "https://www.tiktok.com/@user/video/123"
52+
opencli tiktok unsave --url "https://www.tiktok.com/@user/video/123"
53+
54+
# Follow/unfollow
55+
opencli tiktok follow --username nasa
56+
opencli tiktok unfollow --username nasa
57+
58+
# Comment on a video
59+
opencli tiktok comment --url "https://www.tiktok.com/@user/video/123" --text "Great!"
60+
61+
# JSON output
62+
opencli tiktok profile --username tiktok -f json
63+
```
64+
65+
## Prerequisites
66+
67+
- Chrome running and **logged into** tiktok.com
68+
- [Browser Bridge extension](/guide/browser-bridge) installed

src/clis/tiktok/comment.yaml

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
site: tiktok
2+
name: comment
3+
description: Comment on a TikTok video
4+
domain: www.tiktok.com
5+
6+
args:
7+
url:
8+
type: str
9+
required: true
10+
positional: true
11+
description: TikTok video URL
12+
text:
13+
type: str
14+
required: true
15+
description: Comment text
16+
17+
pipeline:
18+
- navigate:
19+
url: ${{ args.url }}
20+
settleMs: 6000
21+
22+
- evaluate: |
23+
(async () => {
24+
const url = ${{ args.url | json }};
25+
const commentText = ${{ args.text | json }};
26+
27+
// Click comment icon to expand comment section
28+
const commentIcon = document.querySelector('[data-e2e="comment-icon"]');
29+
if (commentIcon) {
30+
const cBtn = commentIcon.closest('button') || commentIcon.closest('[role="button"]') || commentIcon;
31+
cBtn.click();
32+
await new Promise(r => setTimeout(r, 3000));
33+
}
34+
35+
// Find comment input
36+
const input = document.querySelector('[data-e2e="comment-input"] [contenteditable="true"]') ||
37+
document.querySelector('[contenteditable="true"]');
38+
if (!input) throw new Error('Comment input not found - make sure you are logged in');
39+
40+
input.focus();
41+
document.execCommand('insertText', false, commentText);
42+
await new Promise(r => setTimeout(r, 1000));
43+
44+
// Click post button
45+
const btns = Array.from(document.querySelectorAll('[data-e2e="comment-post"], button'));
46+
const postBtn = btns.find(function(b) {
47+
var t = b.textContent.trim();
48+
return t === 'Post' || t === '发布' || t === '发送';
49+
});
50+
if (postBtn) {
51+
postBtn.click();
52+
await new Promise(r => setTimeout(r, 2000));
53+
}
54+
55+
return [{ status: 'Commented', url: url, text: commentText }];
56+
})()
57+
58+
columns: [status, url, text]

src/clis/tiktok/explore.yaml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
site: tiktok
2+
name: explore
3+
description: Get trending TikTok videos from explore page
4+
domain: www.tiktok.com
5+
6+
args:
7+
limit:
8+
type: int
9+
default: 20
10+
description: Number of videos
11+
12+
pipeline:
13+
- navigate:
14+
url: https://www.tiktok.com/explore
15+
settleMs: 5000
16+
17+
- evaluate: |
18+
(() => {
19+
const limit = ${{ args.limit }};
20+
const links = Array.from(document.querySelectorAll('a[href*="/video/"]'));
21+
const seen = new Set();
22+
const results = [];
23+
for (const a of links) {
24+
const href = a.href;
25+
if (seen.has(href)) continue;
26+
seen.add(href);
27+
const match = href.match(/@([^/]+)\/video\/(\d+)/);
28+
results.push({
29+
rank: results.length + 1,
30+
author: match ? match[1] : '',
31+
views: a.textContent.trim() || '-',
32+
url: href,
33+
});
34+
if (results.length >= limit) break;
35+
}
36+
return results;
37+
})()
38+
39+
columns: [rank, author, views, url]

src/clis/tiktok/follow.yaml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
site: tiktok
2+
name: follow
3+
description: Follow a TikTok user
4+
domain: www.tiktok.com
5+
6+
args:
7+
username:
8+
type: str
9+
required: true
10+
positional: true
11+
description: TikTok username (without @)
12+
13+
pipeline:
14+
- navigate:
15+
url: https://www.tiktok.com/@${{ args.username }}
16+
settleMs: 6000
17+
18+
- evaluate: |
19+
(async () => {
20+
const username = ${{ args.username | json }};
21+
const buttons = Array.from(document.querySelectorAll('button, [role="button"]'));
22+
const followBtn = buttons.find(function(b) {
23+
var text = b.textContent.trim();
24+
return text === 'Follow' || text === '关注';
25+
});
26+
if (!followBtn) {
27+
var isFollowing = buttons.some(function(b) {
28+
var t = b.textContent.trim();
29+
return t === 'Following' || t === '已关注' || t === 'Friends' || t === '互关';
30+
});
31+
if (isFollowing) return [{ status: 'Already following', username: username }];
32+
return [{ status: 'Follow button not found', username: username }];
33+
}
34+
followBtn.click();
35+
await new Promise(r => setTimeout(r, 2000));
36+
return [{ status: 'Followed', username: username }];
37+
})()
38+
39+
columns: [status, username]

0 commit comments

Comments
 (0)