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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@ except FopostError as err:
| `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`, `plan_keywords`, `add_keyword`, `update_keyword`, `delete_keyword`, `list_articles`, `request_article`, `get_article`, `update_article`, `regenerate_article`, `publish_article`, `reject_article`, `delete_article` |
| `validate` | `post`, `length`, `media` |
| `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
22 changes: 22 additions & 0 deletions src/fopost/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,17 @@
ValidatePlatformCheck,
ValidatePostResult,
WebhookSubscription,
WhatsappBlockResult,
WhatsappCommerceSettings,
WhatsappEncryptionKeyStatus,
WhatsappFlow,
WhatsappFlowJsonResult,
WhatsappFlowResponse,
WhatsappFlowValidationError,
WhatsappGroup,
WhatsappProfile,
WhatsappSandboxSession,
WhatsappTemplate,
Workspace,
YouTubeCaptionTrack,
YouTubePlaylist,
Expand Down Expand Up @@ -374,6 +385,17 @@
"MetaPersistentMenu",
"MetaPersistentMenuEntry",
"WebhookSubscription",
"WhatsappTemplate",
"WhatsappProfile",
"WhatsappGroup",
"WhatsappBlockResult",
"WhatsappCommerceSettings",
"WhatsappFlow",
"WhatsappFlowValidationError",
"WhatsappFlowJsonResult",
"WhatsappFlowResponse",
"WhatsappEncryptionKeyStatus",
"WhatsappSandboxSession",
"SlackMember",
"SocialAccount",
"AdBusinessCenter",
Expand Down
2 changes: 2 additions & 0 deletions src/fopost/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
PostsResource,
SequencesResource,
ValidateResource,
WhatsappResource,
WorkspacesResource,
)

Expand Down Expand Up @@ -89,6 +90,7 @@ def __init__(
self.activity = ActivityResource(self._http)
self.google_business = GoogleBusinessResource(self._http)
self.blog = BlogResource(self._http)
self.whatsapp = WhatsappResource(self._http)

@property
def base_url(self) -> str:
Expand Down
115 changes: 115 additions & 0 deletions src/fopost/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,17 @@
"BlogSettingsUpdate",
"BlogTargetKind",
"BlogWebsiteTest",
"WhatsappTemplate",
"WhatsappProfile",
"WhatsappGroup",
"WhatsappBlockResult",
"WhatsappCommerceSettings",
"WhatsappFlow",
"WhatsappFlowValidationError",
"WhatsappFlowJsonResult",
"WhatsappFlowResponse",
"WhatsappEncryptionKeyStatus",
"WhatsappSandboxSession",
]

#: Every platform the API can publish to. Model fields stay plain `str`, so a
Expand Down Expand Up @@ -215,6 +226,7 @@
"nostr",
"whop",
"skool",
"whatsapp",
)

Platform = Literal[
Expand Down Expand Up @@ -250,6 +262,7 @@
"nostr",
"whop",
"skool",
"whatsapp",
]

PostStatus = Literal[
Expand Down Expand Up @@ -2480,3 +2493,105 @@ class ArticlePublishedPayload(FopostModel):
word_count: int = 0
published_at: datetime | None = None
published_url: str | None = None


# ─── WhatsApp Business ────────────────────────────────────────────
#
# The platform owns these resources, so nothing here is a cached copy: a
# template's status is whatever the platform assigned it.


class WhatsappTemplate(FopostModel):
id: str
name: str
language: str
category: str
#: The review status the platform assigned: APPROVED, PENDING, REJECTED, …
status: str
rejected_reason: str | None = None
components: list[Any] = []
quality_score: str | None = None


class WhatsappProfile(FopostModel):
about: str | None = None
address: str | None = None
description: str | None = None
email: str | None = None
vertical: str | None = None
websites: list[str] = []
profile_picture_url: str | None = None
display_name: str | None = None
#: The platform's review state for the display name.
display_name_status: str | None = None
username: str | None = None
quality_rating: str | None = None
messaging_limit_tier: str | None = None


class WhatsappGroup(FopostModel):
id: str
subject: str
description: str | None = None
participant_count: int | None = None
invite_link: str | None = None
created_at: datetime | None = None


class WhatsappBlockResult(FopostModel):
blocked: list[str] = []
unblocked: list[str] = []
failed: list[str] = []


class WhatsappCommerceSettings(FopostModel):
cart_enabled: bool | None = None
catalog_visible: bool | None = None
catalog_id: str | None = None


class WhatsappFlowValidationError(FopostModel):
error: str
message: str


class WhatsappFlow(FopostModel):
id: str
name: str
status: str
categories: list[str] = []
validation_errors: list[WhatsappFlowValidationError] = []
endpoint_uri: str | None = None
json_version: str | None = None
preview_url: str | None = None
preview_expires_at: datetime | None = None


class WhatsappFlowJsonResult(FopostModel):
success: bool
validation_errors: list[WhatsappFlowValidationError] = []


class WhatsappFlowResponse(FopostModel):
message_id: str
wa_id: str | None = None
flow_token: str | None = None
answers: dict[str, Any] = {}
responded_at: datetime | None = None


class WhatsappEncryptionKeyStatus(FopostModel):
"""Only whether a key is registered; the key itself never comes back."""

has_key: bool
signature_status: str | None = None


class WhatsappSandboxSession(FopostModel):
id: str
status: str
#: The last four digits only; the number itself is never stored.
phone_number_last4: str
invited_at: datetime
activated_at: datetime | None = None
expires_at: datetime
2 changes: 2 additions & 0 deletions src/fopost/resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from .media import MediaResource
from .posts import PostsResource
from .validate import ValidateResource
from .whatsapp import WhatsappResource
from .workspaces import WorkspacesResource

__all__ = [
Expand All @@ -34,5 +35,6 @@
"MediaResource",
"PostsResource",
"ValidateResource",
"WhatsappResource",
"WorkspacesResource",
]
Loading
Loading