Skip to content

Commit b49789a

Browse files
committed
Refactor and clean up
1 parent acf1a29 commit b49789a

File tree

4 files changed

+176
-305
lines changed

4 files changed

+176
-305
lines changed

README.md

Lines changed: 68 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -1,125 +1,70 @@
1-
2-
# Threads CLI
3-
4-
This CLI tool allows you to interact with the Threads API to perform various actions like creating posts,
5-
getting profile information, retrieving recent posts, scheduling posts, and managing drafts.
6-
The tool is built using Python and leverages the `typer` library for command-line interface creation and the `rich`
7-
library for pretty-printing tables.
8-
9-
## Installation
10-
11-
1. **Clone the repository:**
12-
```bash
13-
git clone https://github.com/your-repo/threads-cli.git
14-
cd threads-cli
15-
```
16-
17-
2. **Set up a virtual environment:**
18-
```bash
19-
python3 -m venv .venv
20-
source .venv/bin/activate
21-
```
22-
23-
3. **Install the dependencies:**
24-
```bash
25-
pip install -r requirements.txt
26-
```
27-
28-
4. **Set up environment variables:**
29-
Create a `.env` file in the root directory with the following content:
30-
```env
31-
ACCESS_TOKEN=your_access_token
32-
```
1+
# Threads Command-Line Interface (CLI) Tool
2+
The Threads CLI Tool is a powerful and efficient command-line application designed to provide another way to interact
3+
with Threads. Developed using Python and leveraging the `typer` library for a user-friendly interface and the `rich`
4+
library for visual output, this tool can do a range of actions, including creating posts, retrieving
5+
profile information, managing drafts, and more.
6+
7+
## Key Features
8+
- User Profile: Retrieve and display comprehensive user profile information, including the user's last post.
9+
- Recent Posts: Fetch and showcase the most recent posts made by the user.
10+
- Top Liked Posts: Retrieve the top liked posts of all time or within a specific time range.
11+
- Post Creation: Create text posts and image posts.
12+
- Replies: Get the latest replies for a specific media post and send replies to engage with the community.
13+
- Scheduling: Schedule posts to be automatically published at a specified future date and time.
14+
- Drafts: Create, manage, and send drafts, providing flexibility in your content creation workflow.
15+
16+
## Getting Started
17+
To get started with the Threads CLI Tool, follow these steps:
18+
19+
Clone the repository:
20+
```
21+
git clone https://github.com/your-repo/threads-cli.git
22+
cd threads-cli
23+
```
24+
25+
Set up a virtual environment:
26+
```
27+
python3 -m venv .venv
28+
source .venv/bin/activate
29+
```
30+
31+
Install the required dependencies:
32+
```
33+
pip install -r requirements.txt
34+
```
35+
36+
Configure environment variables:
37+
Create a `.env` file in the project's root directory and add the following:
38+
39+
40+
```
41+
ACCESS_TOKEN=your_access_token
42+
```
3343

3444
## Usage
35-
36-
### Commands
37-
If any of these example commands are incorrect, if you do `python main.py --help` you will see the list of commands and their descriptions.
38-
39-
40-
1. **Get Profile Information:**
41-
Retrieve and display user profile information, including the last post made by the user.
42-
```bash
43-
python main.py get-profile
44-
```
45-
46-
2. **Get Recent Posts:**
47-
Retrieve the most recent posts.
48-
```bash
49-
python main.py get-recent-posts --limit 5
50-
```
51-
52-
3. **Get Top Liked Posts:**
53-
Retrieve the top liked posts of all time or within a specific time range.
54-
```bash
55-
python main.py get-top-liked-posts --limit 5 --time-range 2w
56-
```
57-
58-
4. **Create a Text Post:**
59-
Create a post with text.
60-
```bash
61-
python main.py create-text-post "This is a text post."
62-
```
63-
64-
5. **Create an Image Post:**
65-
Create a post with an image.
66-
```bash
67-
python main.py create-image_post "This is an image post." "https://example.com/image.jpg"
68-
```
69-
70-
6. **Get Latest Replies:**
71-
Retrieve the latest replies for a specific media post.
72-
```bash
73-
python main.py get-latest-replies --media-id <media_id> --limit 5
74-
```
75-
76-
7. **Send a Reply:**
77-
Send a reply to a specific media post.
78-
```bash
79-
python main.py send-reply --media-id <media_id> --text "This is a reply."
80-
```
81-
82-
8. **Schedule a Post:**
83-
Schedule a post with text at a specific time.
84-
```bash
85-
python main.py schedule-post --text "This is a scheduled post." --post-time "2024-06-22 23:22:00"
86-
```
87-
88-
9. **Create a Draft:**
89-
Create a draft with text.
90-
```bash
91-
python main.py create-draft "This is a draft."
92-
```
93-
94-
10. **Get Drafts:**
95-
Retrieve all drafts.
96-
```bash
97-
python main.py get-drafts
98-
```
99-
100-
11. **Send a Draft:**
101-
Send a draft with a specific ID and remove it from drafts.
102-
```bash
103-
python main.py send-draft --draft-id 1
104-
```
105-
106-
## Additional Information
107-
108-
### Dependencies
109-
- `typer`
110-
- `requests`
111-
- `rich`
112-
- `python-dotenv`
113-
114-
### Environment Variables
115-
- `ACCESS_TOKEN`: Your Threads API access token.
116-
117-
## Development
118-
119-
Feel free to contribute to this project by creating pull requests. Make sure to follow the standard coding guidelines and thoroughly test your changes.
120-
121-
### Things to do
122-
- [ ] Add tests for the CLI commands.
123-
- [ ] Add support for creating polls.
124-
- [ ] Validate that creating videos/image posts works
125-
45+
The Threads CLI Tool provides a wide range of commands to interact with the Threads API. Here are a few examples:
46+
47+
Retrieve user profile:
48+
```
49+
python main.py get-profile
50+
```
51+
52+
Get recent posts:
53+
```
54+
python main.py get-recent-posts --limit 10
55+
```
56+
57+
Create a text post:
58+
```
59+
python main.py create-text-post "Hello, Threads!"
60+
```
61+
62+
Schedule a post:
63+
```
64+
python main.py schedule-post "Scheduled post" "2024-06-22 09:00:00"
65+
```
66+
67+
For a complete list of available commands and their descriptions, run:
68+
```
69+
python main.py --help
70+
```

api.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import requests
2+
from utils import convert_to_locale
3+
4+
BASE_URL = "https://graph.threads.net/v1.0"
5+
6+
def get_user_id(headers):
7+
response = requests.get(f"{BASE_URL}/me?fields=id", headers=headers)
8+
response.raise_for_status()
9+
return response.json()['id']
10+
11+
def get_user_profile(user_id, headers):
12+
profile_fields = "id,username,threads_profile_picture_url,threads_biography"
13+
response = requests.get(f"{BASE_URL}/{user_id}?fields={profile_fields}", headers=headers)
14+
response.raise_for_status()
15+
return response.json()
16+
17+
def get_user_posts(user_id, headers, limit=5):
18+
post_fields = "id,media_product_type,media_type,media_url,permalink,owner,username,text,timestamp,shortcode,thumbnail_url,children,is_quote_post"
19+
response = requests.get(f"{BASE_URL}/{user_id}/threads?fields={post_fields}&limit={limit}", headers=headers)
20+
response.raise_for_status()
21+
return response.json().get('data', [])
22+
23+
def get_post_insights(post_id, headers):
24+
metrics = "views,likes,replies,reposts,quotes"
25+
response = requests.get(f"{BASE_URL}/{post_id}/insights?metric={metrics}", headers=headers)
26+
if response.status_code == 500:
27+
return {}
28+
response.raise_for_status()
29+
insights = response.json().get('data', [])
30+
return {insight['name']: insight['values'][0]['value'] for insight in insights}
31+
32+
def fetch_all_posts(user_id, headers):
33+
all_posts = []
34+
fields = "id,media_product_type,media_type,media_url,permalink,owner,username,text,timestamp,shortcode,thumbnail_url,children,is_quote_post"
35+
next_url = f"{BASE_URL}/{user_id}/threads?fields={fields}"
36+
while next_url:
37+
response = requests.get(next_url, headers=headers)
38+
response.raise_for_status()
39+
data = response.json()
40+
all_posts.extend(data.get('data', []))
41+
next_url = data.get('paging', {}).get('next')
42+
return all_posts
43+
44+
def create_post(user_id, headers, payload):
45+
response = requests.post(f"{BASE_URL}/{user_id}/threads", headers=headers, json=payload)
46+
response.raise_for_status()
47+
container_id = response.json()['id']
48+
49+
publish_payload = {
50+
"creation_id": container_id
51+
}
52+
publish_response = requests.post(f"{BASE_URL}/{user_id}/threads_publish", headers=headers, json=publish_payload)
53+
publish_response.raise_for_status()
54+
return publish_response.json()
55+
56+
def get_post_replies(media_id, headers, limit=5):
57+
fields = "id,text,username,permalink,timestamp,media_product_type,media_type,shortcode,has_replies,root_post,replied_to,is_reply,hide_status"
58+
response = requests.get(f"{BASE_URL}/{media_id}/replies?fields={fields}&limit={limit}&reverse=true", headers=headers)
59+
response.raise_for_status()
60+
return response.json().get('data', [])
61+
62+
def get_post_replies_count(post_id, headers):
63+
response = requests.get(f"{BASE_URL}/{post_id}/replies", headers=headers)
64+
response.raise_for_status()
65+
replies = response.json().get('data', [])
66+
return len(replies)

0 commit comments

Comments
 (0)