feat: Rewrite ThreadsClient with full Threads API coverage

Major rewrite of threads/threads_client.py based on official Meta Threads API docs:

1. Threads Profiles API - get_user_profile() with full fields
2. Threads Media API - updated get_user_threads(), get_thread_by_id() with complete fields
3. Threads Reply Management - get_conversation() for full tree, manage_reply() for hide/unhide
4. Threads Publishing API - create_container(), publish_thread(), create_and_publish()
5. Threads Insights API - get_thread_insights(), get_user_insights(), get_thread_engagement()
6. Rate Limiting - get_publishing_limit(), can_publish()
7. Pagination - _get_paginated() helper with cursor-based pagination
8. POST support - _post() method for write operations

Also:
- Updated check_token.py to use full profile fields
- Added [threads.publishing] config section
- Added use_conversation and use_insights config options
- Optimized thread selection with engagement-based ranking
- Use conversation endpoint instead of just replies for better data

Agent-Logs-Url: https://github.com/thaitien280401-stack/RedditVideoMakerBot/sessions/c01dbc92-66f9-4a1f-bf83-7f0a75dd9968

Co-authored-by: thaitien280401-stack <271128961+thaitien280401-stack@users.noreply.github.com>
pull/2482/head
copilot-swe-agent[bot] 2 days ago committed by GitHub
parent 1c5b309709
commit 7384043d78
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

File diff suppressed because it is too large Load Diff

@ -15,6 +15,13 @@ post_lang = { default = "vi", optional = true, explanation = "Ngôn ngữ. Mặc
min_comments = { default = 5, optional = false, nmin = 1, type = "int", explanation = "Số replies tối thiểu. Mặc định: 5", example = 5 }
blocked_words = { optional = true, default = "", type = "str", explanation = "Từ bị chặn, phân cách bằng dấu phẩy.", example = "spam, quảng cáo" }
channel_name = { optional = true, default = "Threads Vietnam", example = "Threads VN Stories", explanation = "Tên kênh hiển thị trên video" }
use_conversation = { optional = true, default = true, type = "bool", options = [true, false], explanation = "Dùng Conversation API (lấy full reply tree) thay vì chỉ direct replies. Mặc định: true" }
use_insights = { optional = true, default = true, type = "bool", options = [true, false], explanation = "Dùng Insights API để chọn thread có engagement cao nhất. Mặc định: true" }
[threads.publishing]
enabled = { optional = true, type = "bool", default = false, options = [true, false], explanation = "Bật Publishing API - đăng bài mới lên Threads sau khi tạo video" }
reply_control = { optional = true, default = "everyone", options = ["everyone", "accounts_you_follow", "mentioned_only"], explanation = "Ai được phép reply bài đăng. Mặc định: everyone" }
check_quota = { optional = true, default = true, type = "bool", options = [true, false], explanation = "Kiểm tra quota trước khi publish (250 posts / 24h). Mặc định: true" }
[ai]
ai_similarity_enabled = { optional = true, option = [true, false], default = false, type = "bool", explanation = "Sắp xếp threads theo độ tương đồng với từ khóa" }

@ -33,10 +33,14 @@ class TokenCheckError(Exception):
def _call_me_endpoint(access_token: str) -> dict:
"""GET /me?fields=id,username&access_token=… with minimal retry."""
"""GET /me?fields=id,username,name,threads_profile_picture_url,threads_biography
Sử dụng đầy đủ profile fields theo Threads Profiles API:
https://developers.facebook.com/docs/threads/threads-profiles
"""
url = f"{THREADS_API_BASE}/me"
params = {
"fields": "id,username",
"fields": "id,username,name,threads_profile_picture_url,threads_biography",
"access_token": access_token,
}
response = requests.get(url, params=params, timeout=_REQUEST_TIMEOUT_SECONDS)

Loading…
Cancel
Save