Skip to content

Commit 9a9e078

Browse files
authored
feat(bluesky): add Bluesky adapter with 9 commands (#215)
Bluesky (9 commands, public AT Protocol API, no auth needed): - profile: user profile info (followers, following, posts) - user: recent posts from a user with engagement stats - trending: trending topics on Bluesky - search: search users - feeds: popular feed generators - followers: list user's followers - following: list accounts a user follows - thread: post thread with replies - starter-packs: user's starter packs All commands use the public Bluesky API, no browser or login required.
1 parent 55d0473 commit 9a9e078

File tree

10 files changed

+336
-0
lines changed

10 files changed

+336
-0
lines changed

docs/adapters/browser/bluesky.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Bluesky
2+
3+
**Mode**: 🌐 Public · **Domain**: `bsky.app`
4+
5+
## Commands
6+
7+
| Command | Description |
8+
|---------|-------------|
9+
| `opencli bluesky profile` | User profile info |
10+
| `opencli bluesky user` | Recent posts from a user |
11+
| `opencli bluesky trending` | Trending topics |
12+
| `opencli bluesky search` | Search users |
13+
| `opencli bluesky feeds` | Popular feed generators |
14+
| `opencli bluesky followers` | User's followers |
15+
| `opencli bluesky following` | Accounts a user follows |
16+
| `opencli bluesky thread` | Post thread with replies |
17+
| `opencli bluesky starter-packs` | User's starter packs |
18+
19+
## Usage Examples
20+
21+
```bash
22+
# User profile
23+
opencli bluesky profile --handle bsky.app
24+
25+
# Recent posts
26+
opencli bluesky user --handle bsky.app --limit 10
27+
28+
# Trending topics
29+
opencli bluesky trending --limit 10
30+
31+
# Search users
32+
opencli bluesky search --query "AI" --limit 10
33+
34+
# Popular feeds
35+
opencli bluesky feeds --limit 10
36+
37+
# Followers / following
38+
opencli bluesky followers --handle bsky.app --limit 10
39+
opencli bluesky following --handle bsky.app
40+
41+
# Post thread with replies
42+
opencli bluesky thread --uri "at://did:.../app.bsky.feed.post/..."
43+
44+
# Starter packs
45+
opencli bluesky starter-packs --handle bsky.app
46+
47+
# JSON output
48+
opencli bluesky profile --handle bsky.app -f json
49+
```
50+
51+
## Prerequisites
52+
53+
None — all commands use the public Bluesky AT Protocol API, no browser or login required.

src/clis/bluesky/feeds.yaml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
site: bluesky
2+
name: feeds
3+
description: Popular Bluesky feed generators
4+
domain: public.api.bsky.app
5+
strategy: public
6+
browser: false
7+
8+
args:
9+
limit:
10+
type: int
11+
default: 20
12+
description: Number of feeds
13+
14+
pipeline:
15+
- fetch:
16+
url: https://public.api.bsky.app/xrpc/app.bsky.unspecced.getPopularFeedGenerators?limit=${{ args.limit }}
17+
18+
- select: feeds
19+
20+
- map:
21+
rank: ${{ index + 1 }}
22+
name: ${{ item.displayName }}
23+
likes: ${{ item.likeCount }}
24+
creator: ${{ item.creator.handle }}
25+
description: ${{ item.description }}
26+
27+
- limit: ${{ args.limit }}
28+
29+
columns: [rank, name, likes, creator, description]

src/clis/bluesky/followers.yaml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
site: bluesky
2+
name: followers
3+
description: List followers of a Bluesky user
4+
domain: public.api.bsky.app
5+
strategy: public
6+
browser: false
7+
8+
args:
9+
handle:
10+
type: str
11+
required: true
12+
positional: true
13+
description: "Bluesky handle"
14+
limit:
15+
type: int
16+
default: 20
17+
description: Number of followers
18+
19+
pipeline:
20+
- fetch:
21+
url: https://public.api.bsky.app/xrpc/app.bsky.graph.getFollowers?actor=${{ args.handle }}&limit=${{ args.limit }}
22+
23+
- select: followers
24+
25+
- map:
26+
rank: ${{ index + 1 }}
27+
handle: ${{ item.handle }}
28+
name: ${{ item.displayName }}
29+
description: ${{ item.description }}
30+
31+
- limit: ${{ args.limit }}
32+
33+
columns: [rank, handle, name, description]

src/clis/bluesky/following.yaml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
site: bluesky
2+
name: following
3+
description: List accounts a Bluesky user is following
4+
domain: public.api.bsky.app
5+
strategy: public
6+
browser: false
7+
8+
args:
9+
handle:
10+
type: str
11+
required: true
12+
positional: true
13+
description: "Bluesky handle"
14+
limit:
15+
type: int
16+
default: 20
17+
description: Number of accounts
18+
19+
pipeline:
20+
- fetch:
21+
url: https://public.api.bsky.app/xrpc/app.bsky.graph.getFollows?actor=${{ args.handle }}&limit=${{ args.limit }}
22+
23+
- select: follows
24+
25+
- map:
26+
rank: ${{ index + 1 }}
27+
handle: ${{ item.handle }}
28+
name: ${{ item.displayName }}
29+
description: ${{ item.description }}
30+
31+
- limit: ${{ args.limit }}
32+
33+
columns: [rank, handle, name, description]

src/clis/bluesky/profile.yaml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
site: bluesky
2+
name: profile
3+
description: Get Bluesky user profile info
4+
domain: public.api.bsky.app
5+
strategy: public
6+
browser: false
7+
8+
args:
9+
handle:
10+
type: str
11+
required: true
12+
positional: true
13+
description: "Bluesky handle (e.g. bsky.app, jay.bsky.team)"
14+
15+
pipeline:
16+
- fetch:
17+
url: https://public.api.bsky.app/xrpc/app.bsky.actor.getProfile?actor=${{ args.handle }}
18+
19+
- map:
20+
handle: ${{ item.handle }}
21+
name: ${{ item.displayName }}
22+
followers: ${{ item.followersCount }}
23+
following: ${{ item.followsCount }}
24+
posts: ${{ item.postsCount }}
25+
description: ${{ item.description }}
26+
27+
columns: [handle, name, followers, following, posts, description]

src/clis/bluesky/search.yaml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
site: bluesky
2+
name: search
3+
description: Search Bluesky users
4+
domain: public.api.bsky.app
5+
strategy: public
6+
browser: false
7+
8+
args:
9+
query:
10+
type: str
11+
required: true
12+
positional: true
13+
description: Search query
14+
limit:
15+
type: int
16+
default: 10
17+
description: Number of results
18+
19+
pipeline:
20+
- fetch:
21+
url: https://public.api.bsky.app/xrpc/app.bsky.actor.searchActors?q=${{ args.query }}&limit=${{ args.limit }}
22+
23+
- select: actors
24+
25+
- map:
26+
rank: ${{ index + 1 }}
27+
handle: ${{ item.handle }}
28+
name: ${{ item.displayName }}
29+
followers: ${{ item.followersCount }}
30+
description: ${{ item.description }}
31+
32+
- limit: ${{ args.limit }}
33+
34+
columns: [rank, handle, name, followers, description]
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
site: bluesky
2+
name: starter-packs
3+
description: Get starter packs created by a Bluesky user
4+
domain: public.api.bsky.app
5+
strategy: public
6+
browser: false
7+
8+
args:
9+
handle:
10+
type: str
11+
required: true
12+
positional: true
13+
description: "Bluesky handle"
14+
limit:
15+
type: int
16+
default: 10
17+
description: Number of starter packs
18+
19+
pipeline:
20+
- fetch:
21+
url: https://public.api.bsky.app/xrpc/app.bsky.graph.getActorStarterPacks?actor=${{ args.handle }}&limit=${{ args.limit }}
22+
23+
- select: starterPacks
24+
25+
- map:
26+
rank: ${{ index + 1 }}
27+
name: ${{ item.record.name }}
28+
description: ${{ item.record.description }}
29+
members: ${{ item.listItemCount }}
30+
joins: ${{ item.joinedAllTimeCount }}
31+
32+
- limit: ${{ args.limit }}
33+
34+
columns: [rank, name, description, members, joins]

src/clis/bluesky/thread.yaml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
site: bluesky
2+
name: thread
3+
description: Get a Bluesky post thread with replies
4+
domain: public.api.bsky.app
5+
strategy: public
6+
browser: false
7+
8+
args:
9+
uri:
10+
type: str
11+
required: true
12+
positional: true
13+
description: "Post AT URI (at://did:.../app.bsky.feed.post/...) or bsky.app URL"
14+
limit:
15+
type: int
16+
default: 20
17+
description: Number of replies
18+
19+
pipeline:
20+
- fetch:
21+
url: https://public.api.bsky.app/xrpc/app.bsky.feed.getPostThread?uri=${{ args.uri }}&depth=2
22+
23+
- select: thread
24+
25+
- map:
26+
author: ${{ item.post.author.handle }}
27+
text: ${{ item.post.record.text }}
28+
likes: ${{ item.post.likeCount }}
29+
reposts: ${{ item.post.repostCount }}
30+
replies_count: ${{ item.post.replyCount }}
31+
32+
columns: [author, text, likes, reposts, replies_count]

src/clis/bluesky/trending.yaml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
site: bluesky
2+
name: trending
3+
description: Trending topics on Bluesky
4+
domain: public.api.bsky.app
5+
strategy: public
6+
browser: false
7+
8+
args:
9+
limit:
10+
type: int
11+
default: 20
12+
description: Number of topics
13+
14+
pipeline:
15+
- fetch:
16+
url: https://public.api.bsky.app/xrpc/app.bsky.unspecced.getTrendingTopics
17+
18+
- select: topics
19+
20+
- map:
21+
rank: ${{ index + 1 }}
22+
topic: ${{ item.topic }}
23+
link: ${{ item.link }}
24+
25+
- limit: ${{ args.limit }}
26+
27+
columns: [rank, topic, link]

src/clis/bluesky/user.yaml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
site: bluesky
2+
name: user
3+
description: Get recent posts from a Bluesky user
4+
domain: public.api.bsky.app
5+
strategy: public
6+
browser: false
7+
8+
args:
9+
handle:
10+
type: str
11+
required: true
12+
positional: true
13+
description: "Bluesky handle (e.g. bsky.app)"
14+
limit:
15+
type: int
16+
default: 20
17+
description: Number of posts
18+
19+
pipeline:
20+
- fetch:
21+
url: https://public.api.bsky.app/xrpc/app.bsky.feed.getAuthorFeed?actor=${{ args.handle }}&limit=${{ args.limit }}
22+
23+
- select: feed
24+
25+
- map:
26+
rank: ${{ index + 1 }}
27+
text: ${{ item.post.record.text }}
28+
likes: ${{ item.post.likeCount }}
29+
reposts: ${{ item.post.repostCount }}
30+
replies: ${{ item.post.replyCount }}
31+
32+
- limit: ${{ args.limit }}
33+
34+
columns: [rank, text, likes, reposts, replies]

0 commit comments

Comments
 (0)