diff --git a/CHANGELOG.md b/CHANGELOG.md index 5781082..ebb1b3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ All notable changes to this project will be documented in this file. +## [0.1.10](https://github.com/sns-sdks/python-tiktok/v0.1.10) (2024-12-16) + +### Features + +- Add api for get account post privacy setting +- Add api for get post publish status +- fix fields type in get data. + ## [0.1.9](https://github.com/sns-sdks/python-tiktok/v0.1.9) (2024-08-07) ### Features @@ -35,7 +43,7 @@ All notable changes to this project will be documented in this file. ### Fix -- fix sometimes the `requests` module raise the `JSONDecodeError not found`. +- fix sometimes the `requests` module raise the `JSONDecodeError not found`. ## [0.1.4](https://github.com/sns-sdks/python-tiktok/v0.1.4) (2022-08-23) diff --git a/pytiktok/business_account_api.py b/pytiktok/business_account_api.py index 94c827e..68b34b0 100644 --- a/pytiktok/business_account_api.py +++ b/pytiktok/business_account_api.py @@ -2,6 +2,7 @@ Core API impl. """ +import json from typing import Optional, List, Union import requests @@ -40,6 +41,12 @@ def __init__( # Must be the same as the TikTok account holder redirect URL set in the app. self.oauth_redirect_uri = oauth_redirect_uri + @staticmethod + def _format_fields(fields): + if isinstance(fields, str): + return fields + return json.dumps(fields) + def generate_access_token( self, code: str, redirect_uri: Optional[str] = None, return_json: bool = False ) -> Union[mds.BusinessAccessToken, dict]: @@ -235,7 +242,7 @@ def get_account_data( if end_date is not None: params["end_date"] = end_date if fields is not None: - params["fields"] = fields + params["fields"] = self._format_fields(fields) resp = self._request(path="business/get/", params=params) data = self.parse_response(resp) @@ -268,7 +275,7 @@ def get_account_videos( params = {"business_id": business_id} if fields is not None: - params["fields"] = fields + params["fields"] = self._format_fields(fields) if filters is not None: params["filters"] = filters if cursor is not None: @@ -284,6 +291,26 @@ def get_account_videos( data if return_json else mds.BusinessVideosResponse.new_from_json_dict(data) ) + def get_account_post_privacy( + self, + business_id: str, + return_json: bool = False, + ) -> Union[mds.BusinessAccountPrivacySettingResponse, dict]: + """ + Get the post privacy settings of a TikTok account. + :param business_id: Application specific unique identifier for the TikTok account. + :param return_json: Type for returned data. If you set True JSON data will be returned. + :return: Account's post privacy setting + """ + params = {"business_id": business_id} + resp = self._request(path="business/video/settings/", params=params) + data = self.parse_response(resp) + return ( + data + if return_json + else mds.BusinessAccountPrivacySettingResponse.new_from_json_dict(data) + ) + def create_video( self, business_id: str, @@ -351,6 +378,28 @@ def create_photo( else mds.BusinessPhotoPublishResponse.new_from_json_dict(data) ) + def get_publish_status( + self, + business_id: str, + publish_id: str, + return_json: bool = False, + ) -> Union[mds.BusinessPublishStatusResponse, dict]: + """ + Get the publishing status of a TikTok video post or photo post. + :param business_id: Application specific unique identifier for the TikTok account. + :param publish_id: Unique identifier for a post publishing task. Value of the `share_id`. + :param return_json: Type for returned data. If you set True JSON data will be returned. + :return: publish status + """ + params = {"business_id": business_id, "publish_id": publish_id} + resp = self._request(path="business/publish/status/", params=params) + data = self.parse_response(resp) + return ( + data + if return_json + else mds.BusinessPublishStatusResponse.new_from_json_dict(data) + ) + def get_video_comments( self, business_id: str, diff --git a/pytiktok/models/business_account.py b/pytiktok/models/business_account.py index 54daf87..6d1285b 100644 --- a/pytiktok/models/business_account.py +++ b/pytiktok/models/business_account.py @@ -111,6 +111,20 @@ class BusinessAccountResponse(BusinessBaseResponse): data: Optional[BusinessAccount] = field(default=None) +@dataclass +class BusinessAccountPrivacySetting(BaseModel): + privacy_level_options: Optional[List[str]] = field(default=None) + comment_disabled: Optional[bool] = field(default=None) + duet_disabled: Optional[bool] = field(default=None) + stitch_disabled: Optional[bool] = field(default=None) + max_video_post_duration_sec: Optional[int] = field(default=None) + + +@dataclass +class BusinessAccountPrivacySettingResponse(BusinessBaseResponse): + data: Optional[BusinessAccountPrivacySetting] = field(default=None) + + @dataclass class BusinessVideoImpressionSource(BaseModel): impression_source: Optional[str] = field(default=None) @@ -192,6 +206,18 @@ class BusinessPhotoPublishResponse(BusinessBaseResponse): data: Optional[BusinessPhotoPublish] = field(default=None) +@dataclass +class BusinessPublishStatus(BaseModel): + status: Optional[str] = field(default=None) + post_ids: Optional[List[str]] = field(default=None) + reason: Optional[str] = field(default=None) + + +@dataclass +class BusinessPublishStatusResponse(BusinessBaseResponse): + data: Optional[BusinessPublishStatus] = field(default=None) + + @dataclass class BusinessComment(BaseModel): """