Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -313,14 +313,14 @@ except FopostError as err:
| Namespace | Methods |
| ------------ | -------------------------------------------------------------------------------------- |
| `posts` | `list`, `iter`, `iter_pages`, `get`, `create`, `update`, `delete`, `publish`, `cancel`, `retry`, `preflight`, `deliveries` |
| `accounts` | `list`, `get`, `health`, `update`, `move`, `create_telegram_connect_code`, `get_telegram_connect_status`, `get_telegram_bot_commands`, `set_telegram_bot_commands`, `delete_telegram_bot_commands`, `list_slack_channels`, `list_slack_members`, `get_slack_identity`, `update_slack_identity`, `get_ice_breakers`, `set_ice_breakers`, `delete_ice_breakers`, `get_persistent_menu`, `set_persistent_menu`, `delete_persistent_menu`, `get_greeting`, `set_greeting`, `delete_greeting`, `get_webhook_subscription`, `resubscribe_webhook`, `list_discord_channels`, `switch_discord_channel`, `get_discord_identity`, `update_discord_identity`, `list_discord_pins`, `delete_discord_message`, `pin_discord_message`, `unpin_discord_message`, `crosspost_discord_message`, `create_discord_thread`, `send_discord_dm`, `list_discord_events`, `get_discord_event`, `create_discord_event`, `update_discord_event`, `delete_discord_event`, `list_discord_members`, `get_discord_member`, `list_discord_roles`, `create_discord_role`, `update_discord_role`, `delete_discord_role`, `add_discord_member_role`, `remove_discord_member_role`, `platform_metrics` |
| `accounts` | `list`, `get`, `health`, `update`, `move`, `create_telegram_connect_code`, `get_telegram_connect_status`, `get_telegram_bot_commands`, `set_telegram_bot_commands`, `delete_telegram_bot_commands`, `list_slack_channels`, `list_slack_members`, `get_slack_identity`, `update_slack_identity`, `list_reddit_subreddits`, `list_reddit_subreddit_rules`, `list_reddit_flairs`, `set_reddit_default_subreddit`, `get_ice_breakers`, `set_ice_breakers`, `delete_ice_breakers`, `get_persistent_menu`, `set_persistent_menu`, `delete_persistent_menu`, `get_greeting`, `set_greeting`, `delete_greeting`, `get_webhook_subscription`, `resubscribe_webhook`, `list_discord_channels`, `switch_discord_channel`, `get_discord_identity`, `update_discord_identity`, `list_discord_pins`, `delete_discord_message`, `pin_discord_message`, `unpin_discord_message`, `crosspost_discord_message`, `create_discord_thread`, `send_discord_dm`, `list_discord_events`, `get_discord_event`, `create_discord_event`, `update_discord_event`, `delete_discord_event`, `list_discord_members`, `get_discord_member`, `list_discord_roles`, `create_discord_role`, `update_discord_role`, `delete_discord_role`, `add_discord_member_role`, `remove_discord_member_role`, `platform_metrics` |
| `account_groups` | `list`, `create`, `get`, `update`, `delete`, `set_members` |
| `workspaces` | `list`, `get` |
| `labels` | `list` |
| `media` | `limits`, `presign`, `complete`, `upload_direct` |
| `ai` | `credits`, `generate_caption`, `rewrite`, `repurpose_url` |
| `inbox` | `list`, `threads`, `conversations`, `unread_count`, `accounts`, `platforms`, `mark_thread_read`, `refresh`, `update`, `edit_comment`, `reply`, `hide`, `unhide`, `delete`, `like`, `unlike`, `pin`, `unpin`, `react`, `start_conversation`, `set_typing`, `handover`, `list_approvals`, `approve_reply`, `reject_reply` |
| `inbox` | `list`, `threads`, `conversations`, `unread_count`, `accounts`, `platforms`, `mark_thread_read`, `refresh`, `update`, `edit_comment`, `reply`, `hide`, `unhide`, `delete`, `like`, `unlike`, `pin`, `unpin`, `react`, `start_conversation`, `set_typing`, `list_approvals`, `approve_reply`, `reject_reply` |
| `inbox` | `list`, `threads`, `conversations`, `unread_count`, `accounts`, `platforms`, `mark_thread_read`, `refresh`, `update`, `edit_comment`, `reply`, `hide`, `unhide`, `delete`, `like`, `unlike`, `vote`, `pin`, `unpin`, `react`, `start_conversation`, `set_typing`, `handover`, `list_approvals`, `approve_reply`, `reject_reply` |
| `inbox` | `list`, `threads`, `conversations`, `unread_count`, `accounts`, `platforms`, `mark_thread_read`, `refresh`, `update`, `edit_comment`, `reply`, `hide`, `unhide`, `delete`, `like`, `unlike`, `vote`, `pin`, `unpin`, `react`, `start_conversation`, `set_typing`, `list_approvals`, `approve_reply`, `reject_reply` |
| `contacts` | `list`, `get`, `create`, `update`, `delete`, `conversations`, `import_csv`, `list_fields`, `create_field`, `update_field`, `delete_field`, `conversation_analytics` |
| `broadcasts` | `list`, `get`, `create`, `update`, `delete`, `send`, `cancel`, `recipients` |
| `sequences` | `list`, `get`, `create`, `update`, `delete`, `enroll`, `unenroll`, `enrollments` |
Expand All @@ -329,7 +329,7 @@ except FopostError as err:
| `ads` | `list`, `external`, `boostable`, `connections`, `sources`, `providers`, `authorize`, `delete_connection`, `boost`, `create`, `refresh`, `set_status`, `delete`, `audiences`, `create_audience`, `search_targeting`, `lead_forms`, `create_lead_form`, `leads`, `account_tree`, `create_campaign`, `get_campaign`, `update_campaign`, `delete_campaign`, `duplicate_campaign`, `create_ad_set`, `get_ad_set`, `update_ad_set`, `delete_ad_set`, `duplicate_ad_set`, `create_network_ad`, `get_network_ad`, `update_network_ad`, `delete_network_ad`, `duplicate_network_ad`, `bulk_set_status`, `creatives`, `create_creative`, `get_creative`, `delete_creative`, `get_audience`, `update_audience`, `delete_audience`, `add_audience_users`, `add_audience_companies`, `estimate_reach`, `insights`, `ad_insights`, `get_lead_form`, `archive_lead_form`, `leads_feed`, `lead_pages`, `subscribe_lead_page`, `unsubscribe_lead_page`, `bid_pricing`, `supply_forecast`, `conversion_rules`, `create_conversion_rule`, `get_conversion_rule`, `update_conversion_rule`, `delete_conversion_rule`, `attach_conversion_rule`, `detach_conversion_rule`, `conversion_metrics`, `send_conversion_events` |
| `google_business` | `get_location`, `update_location`, `get_attributes`, `update_attributes`, `get_menus`, `replace_menus`, `get_services`, `replace_services`, `list_media`, `add_media`, `delete_media`, `list_place_actions`, `create_place_action`, `update_place_action`, `delete_place_action`, `get_verification_options`, `start_verification`, `complete_verification`, `get_performance`, `get_search_keywords`, `assign` |
| `blog` | `get_settings`, `update_settings`, `rotate_website_secret`, `test_website`, `list_keywords`, `suggest_seeds`, `plan_keywords`, `add_keyword`, `update_keyword`, `delete_keyword`, `list_articles`, `request_article`, `get_article`, `update_article`, `regenerate_article`, `submit_article`, `publish_article`, `reject_article`, `delete_article` |
| `validate` | `post`, `length`, `media` |
| `validate` | `post`, `length`, `media`, `subreddit` |
| `whatsapp` | `get_profile`, `update_profile`, `request_display_name`, `set_username`, `list_templates`, `list_template_library`, `get_template`, `create_template`, `import_template`, `update_template`, `delete_template`, `list_groups`, `create_group`, `get_group`, `update_group`, `delete_group`, `get_group_invite_link`, `reset_group_invite_link`, `remove_group_participants`, `list_blocked`, `block_users`, `unblock_users`, `get_commerce_settings`, `update_commerce_settings`, `link_catalog`, `list_flows`, `get_flow`, `create_flow`, `update_flow`, `delete_flow`, `upload_flow_json`, `publish_flow`, `deprecate_flow`, `list_flow_responses`, `get_encryption_key_status`, `set_encryption_key`, `get_account_events`, `list_sandbox_sessions`, `create_sandbox_session` |
| `analytics` | `decay`, `frequency`, `timeline`, `changes`, `collect_post`, `native_posts` |
| `activity` | `list` |
Expand Down
14 changes: 14 additions & 0 deletions src/fopost/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,12 @@
PostTimeline,
PresignedUpload,
ReachEstimate,
RedditDefaultSubreddit,
RedditFlair,
RedditFlairs,
RedditSubreddit,
RedditSubredditRule,
RedditSubredditRules,
RepurposeResult,
RewriteResult,
RewriteVariant,
Expand All @@ -203,6 +209,7 @@
SlackMember,
SocialAccount,
SparkPost,
SubredditCheck,
SupplyForecast,
TargetingOption,
TelegramBotCommand,
Expand Down Expand Up @@ -353,6 +360,12 @@
"UploadLimitTier",
"UploadLimits",
"ReachEstimate",
"RedditDefaultSubreddit",
"RedditFlair",
"RedditFlairs",
"RedditSubreddit",
"RedditSubredditRule",
"RedditSubredditRules",
"RepurposeResult",
"RewriteResult",
"RewriteVariant",
Expand Down Expand Up @@ -406,6 +419,7 @@
"AdCommentsPage",
"AdIdentity",
"SparkPost",
"SubredditCheck",
"TargetingOption",
"TelegramBotCommand",
"TelegramBotCommands",
Expand Down
64 changes: 64 additions & 0 deletions src/fopost/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@
"UploadLimitTier",
"UploadLimits",
"ReachEstimate",
"RedditDefaultSubreddit",
"RedditFlair",
"RedditFlairs",
"RedditSubreddit",
"RedditSubredditRule",
"RedditSubredditRules",
"RepurposeResult",
"RewriteResult",
"RewriteVariant",
Expand All @@ -116,6 +122,7 @@
"SlackIdentity",
"SlackMember",
"SocialAccount",
"SubredditCheck",
"TargetingOption",
"TelegramBotCommand",
"TelegramBotCommands",
Expand Down Expand Up @@ -424,6 +431,7 @@ class SocialAccount(FopostModel):
health_status: str | None = None
last_health_check: datetime | None = None
platform_name: str | None = None
reconnect_required: bool | None = None


class AccountRename(FopostModel):
Expand Down Expand Up @@ -814,6 +822,60 @@ class AccountPlatformMetrics(FopostModel):
post: PlatformMetricsBlock


class RedditSubreddit(FopostModel):
"""A subreddit the account is in, or its own profile page."""

name: str
title: str | None = None
subscribers: int | None = None
over18: bool = False
can_post: bool = True
flair_enabled: bool = False
icon_url: str | None = None
is_default: bool = False


class RedditSubredditRule(FopostModel):
name: str
description: str | None = None
applies_to: str | None = None


class RedditSubredditRules(FopostModel):
subreddit: str
rules: list[RedditSubredditRule] = []


class RedditFlair(FopostModel):
"""``editable`` means the label may be replaced with your own text."""

id: str
text: str = ""
editable: bool = False


class RedditFlairs(FopostModel):
subreddit: str
flairs: list[RedditFlair] = []


class RedditDefaultSubreddit(FopostModel):
"""``None`` means the account's own profile page."""

subreddit: str | None = None


class SubredditCheck(FopostModel):
"""``ok`` is true when the subreddit exists and takes a post from this account."""

subreddit: str
exists: bool = False
can_post: bool = False
over_18: bool = False
flair_enabled: bool = False
ok: bool = False


class Workspace(FopostModel):
id: str
name: str
Expand Down Expand Up @@ -1156,10 +1218,12 @@ class InboxItem(FopostModel):
can_hide: bool | None = None
can_delete: bool | None = None
liked: bool | None = None
vote: str | None = None
pinned: bool | None = None
reaction: str | None = None
edited_at: datetime | None = None
can_like: bool | None = None
can_vote: bool | None = None
can_pin: bool | None = None
can_edit: bool | None = None
can_react: bool | None = None
Expand Down
41 changes: 41 additions & 0 deletions src/fopost/resources/accounts.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import builtins
from collections.abc import Mapping, Sequence
from typing import Any
from urllib.parse import quote

from .._http import unwrap
from ..models import (
Expand All @@ -31,6 +32,10 @@
MetaPersistentMenu,
MetaPersistentMenuEntry,
PinterestBoard,
RedditDefaultSubreddit,
RedditFlairs,
RedditSubreddit,
RedditSubredditRules,
SlackChannel,
SlackIdentity,
SlackMember,
Expand Down Expand Up @@ -154,6 +159,42 @@ def delete_telegram_bot_commands(self, account_id: str) -> TelegramBotCommands:
unwrap(self._http.delete(f"/accounts/{account_id}/telegram/commands"))
)

def list_reddit_subreddits(self, account_id: str) -> builtins.list[RedditSubreddit]:
"""Subreddits the account is in, busiest first, plus its own profile page."""
return parse_list(
RedditSubreddit, unwrap(self._http.get(f"/accounts/{account_id}/reddit/subreddits"))
)

def list_reddit_subreddit_rules(self, account_id: str, subreddit: str) -> RedditSubredditRules:
"""The rules a subreddit publishes, in its own order."""
return RedditSubredditRules.model_validate(
unwrap(
self._http.get(
f"/accounts/{account_id}/reddit/subreddits/{quote(subreddit, safe='')}/rules"
)
)
)

def list_reddit_flairs(self, account_id: str, subreddit: str) -> RedditFlairs:
"""Post flairs one subreddit offers; a flair id is valid only there."""
return RedditFlairs.model_validate(
unwrap(
self._http.get(f"/accounts/{account_id}/reddit/flairs", {"subreddit": subreddit})
)
)

def set_reddit_default_subreddit(
self, account_id: str, subreddit: str | None
) -> RedditDefaultSubreddit:
"""Where posts go when a post names none; ``None`` falls back to the profile page."""
return RedditDefaultSubreddit.model_validate(
unwrap(
self._http.put(
f"/accounts/{account_id}/reddit/default-subreddit", {"subreddit": subreddit}
)
)
)

def list_slack_channels(self, account_id: str) -> builtins.list[SlackChannel]:
"""Channels the Slack app can post to in the connected workspace."""
return parse_list(
Expand Down
10 changes: 10 additions & 0 deletions src/fopost/resources/inbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,16 @@ def like(self, item_id: str) -> InboxItem:
def unlike(self, item_id: str) -> InboxItem:
return InboxItem.model_validate(unwrap(self._http.post(f"/inbox/{item_id}/unlike")))

def vote(self, item_id: str, direction: str) -> InboxItem:
"""Vote up or down where the network ranks by votes, where ``can_vote`` is true.

``direction`` is ``"up"``, ``"down"``, or ``"none"`` to take an earlier vote
back. An upvote is the same call a like makes, so ``liked`` moves with it.
"""
return InboxItem.model_validate(
unwrap(self._http.post(f"/inbox/{item_id}/vote", {"direction": direction}))
)

def pin(self, item_id: str) -> InboxItem:
"""Pin our own comment, where ``can_pin`` is true."""
return InboxItem.model_validate(unwrap(self._http.post(f"/inbox/{item_id}/pin")))
Expand Down
16 changes: 15 additions & 1 deletion src/fopost/resources/validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@
from typing import Any

from .._http import unwrap
from ..models import ValidateLengthResult, ValidateMediaResult, ValidatePostResult
from ..models import (
SubredditCheck,
ValidateLengthResult,
ValidateMediaResult,
ValidatePostResult,
)
from ._base import Resource

__all__ = ["ValidateResource"]
Expand Down Expand Up @@ -46,3 +51,12 @@ def media(self, *, url: str) -> ValidateMediaResult:
return ValidateMediaResult.model_validate(
unwrap(self._http.post("/validate/media", {"url": url}))
)

def subreddit(self, *, account_id: str, name: str) -> SubredditCheck:
"""Whether a subreddit exists and takes a post from this Reddit account.

The check runs with the account's own token, so ``account_id`` is required.
"""
return SubredditCheck.model_validate(
unwrap(self._http.get("/validate/subreddit", {"account_id": account_id, "name": name}))
)
Loading
Loading