From 1417f3a06f127dff122e41680698239be083c09c Mon Sep 17 00:00:00 2001 From: ikaroskun Date: Wed, 7 Aug 2024 11:42:17 +0800 Subject: [PATCH 1/5] feat(photo): :sparkles: add api for publish photo post --- pytiktok/business_account_api.py | 35 +++++++++++++++++++++++++++++ pytiktok/models/business_account.py | 13 +++++++++++ 2 files changed, 48 insertions(+) diff --git a/pytiktok/business_account_api.py b/pytiktok/business_account_api.py index b002549..f59b31c 100644 --- a/pytiktok/business_account_api.py +++ b/pytiktok/business_account_api.py @@ -316,6 +316,41 @@ def create_video( else mds.BusinessVideoPublishResponse.new_from_json_dict(data) ) + def create_photo( + self, + business_id: str, + photo_images: List[str], + post_info: dict, + photo_cover_index: int = 0, + return_json: bool = False, + ) -> Union[mds.BusinessPhotoPublishResponse, dict]: + """ + Publish a photo post to an owned TikTok Account. + :param business_id: Application specific unique identifier for the TikTok account. + :param photo_images: A list of up to 35 publicly accessible HTTP(s) URLs for the photo content to be published. + :param post_info: Information about the photo post. + - privacy_level is Required field. + - Other fields are optional + :param photo_cover_index: The index of the photo to be used as the cover for the post. + O is the first photo. + :param return_json: Type for returned data. If you set True JSON data will be returned. + :return: Photo publish response. + """ + + data = { + "business_id": business_id, + "photo_images": photo_images, + "photo_cover_index": photo_cover_index, + "post_info": post_info, + } + resp = self._request(verb="POST", path="business/photo/publish/", json=data) + data = self.parse_response(resp) + return ( + data + if return_json + else mds.BusinessPhotoPublishResponse.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 ac0b421..817b2c4 100644 --- a/pytiktok/models/business_account.py +++ b/pytiktok/models/business_account.py @@ -178,6 +178,19 @@ class BusinessVideoPublishResponse(BusinessBaseResponse): data: Optional[BusinessVideoPublish] = field(default=None) +@dataclass +class BusinessPhotoPublish(BusinessVideoPublish): + """ + https://business-api.tiktok.com/portal/docs?id=1803630424390658 + """ + ... + + +@dataclass +class BusinessPhotoPublishResponse(BusinessBaseResponse): + data: Optional[BusinessPhotoPublish] = field(default=None) + + @dataclass class BusinessComment(BaseModel): """ From 5cbe08a63fd21218bc5849fe8d92f3a02aac04e2 Mon Sep 17 00:00:00 2001 From: ikaroskun Date: Wed, 7 Aug 2024 12:04:48 +0800 Subject: [PATCH 2/5] feat(comments): :sparkles: add unique_identifier field for comments and replies --- pytiktok/models/business_account.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pytiktok/models/business_account.py b/pytiktok/models/business_account.py index 817b2c4..5387d80 100644 --- a/pytiktok/models/business_account.py +++ b/pytiktok/models/business_account.py @@ -198,7 +198,10 @@ class BusinessComment(BaseModel): """ comment_id: Optional[str] = field(default=None) + unique_identifier: Optional[str] = field(default=None, repr=True) video_id: Optional[str] = field(default=None, repr=False) + # Note: user_id now is To-be-deprecated, will be deprecated in the next API version. + # Please use unique_identifier instead. user_id: Optional[str] = field(default=None, repr=False) create_time: Optional[int] = field(default=None) text: Optional[str] = field(default=None) From e15847cf92335ef1b279b70fa664a370a27b0e02 Mon Sep 17 00:00:00 2001 From: ikaroskun Date: Wed, 7 Aug 2024 16:04:24 +0800 Subject: [PATCH 3/5] fix(model): :bug: modify video publish base model --- pytiktok/models/business_account.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pytiktok/models/business_account.py b/pytiktok/models/business_account.py index 5387d80..769cb2b 100644 --- a/pytiktok/models/business_account.py +++ b/pytiktok/models/business_account.py @@ -165,7 +165,7 @@ class BusinessVideosResponse(BusinessBaseResponse): @dataclass -class BusinessVideoPublish(BusinessBaseResponse): +class BusinessVideoPublish(BaseModel): """ Refer: https://ads.tiktok.com/marketing_api/docs?id=1733584024973313 """ From a6dd34359d67257b45f2af2ba8d423afc7b462f2 Mon Sep 17 00:00:00 2001 From: ikaroskun Date: Wed, 7 Aug 2024 16:07:16 +0800 Subject: [PATCH 4/5] style(model): :art: format code --- pytiktok/models/business_account.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pytiktok/models/business_account.py b/pytiktok/models/business_account.py index 769cb2b..ac4bbe6 100644 --- a/pytiktok/models/business_account.py +++ b/pytiktok/models/business_account.py @@ -183,6 +183,7 @@ class BusinessPhotoPublish(BusinessVideoPublish): """ https://business-api.tiktok.com/portal/docs?id=1803630424390658 """ + ... From 2e1adc42084360be63905d7e8be0f39adc7e5b30 Mon Sep 17 00:00:00 2001 From: ikaroskun Date: Wed, 7 Aug 2024 16:25:00 +0800 Subject: [PATCH 5/5] ci(action): :construction_worker: update ci --- .github/workflows/test.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 4d5cebf..34c1be3 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-20.04 strategy: matrix: - python-version: ['3.6', '3.7', '3.8', '3.9', '3.10'] + python-version: ['3.6', '3.7', '3.8', '3.9', '3.10', "3.11", "3.12"] include: - python-version: '3.10' update-coverage: true @@ -35,7 +35,7 @@ jobs: run: poetry run pytest - name: Upload coverage to Codecov if: ${{ matrix.update-coverage }} - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v4 with: token: ${{ secrets.CODECOV_TOKEN }} files: ./coverage.xml