feat: fix tiktok for photos

This commit is contained in:
Nevo David 2025-07-11 12:25:30 +07:00
parent 894cb33c97
commit b8e3f53b23
4 changed files with 102 additions and 12 deletions

View File

@ -19,6 +19,8 @@ import { useCustomProviderFunction } from '@gitroom/frontend/components/launches
import { Checkbox } from '@gitroom/react/form/checkbox';
import clsx from 'clsx';
import { useT } from '@gitroom/react/translation/get.transation.service.client';
import { useIntegration } from '@gitroom/frontend/components/launches/helpers/use.integration';
import { Input } from '@gitroom/react/form/input';
const CheckTikTokValidity: FC<{
picture: string;
@ -85,9 +87,14 @@ const CheckTikTokValidity: FC<{
const TikTokSettings: FC<{
values?: any;
}> = (props) => {
const { watch, register, formState, control } = useSettings();
const { watch, register } = useSettings();
const { value } = useIntegration();
const t = useT();
const isTitle = useMemo(() => {
return value?.[0].image.some((p) => p.path.indexOf('mp4') === -1);
}, [value]);
const disclose = watch('disclose');
const brand_organic_toggle = watch('brand_organic_toggle');
const brand_content_toggle = watch('brand_content_toggle');
@ -142,6 +149,9 @@ const TikTokSettings: FC<{
return (
<div className="flex flex-col">
<CheckTikTokValidity picture={props?.values?.[0]?.image?.[0]?.path} />
{isTitle && (
<Input label="Title" {...register('title')} maxLength={90} />
)}
<Select
label={t('label_who_can_see_this_video', 'Who can see this video?')}
hideErrors={true}

View File

@ -1,6 +1,10 @@
import { IsBoolean, IsDefined, IsIn, IsString } from 'class-validator';
import { IsBoolean, ValidateIf, IsIn, IsString, MaxLength } from 'class-validator';
export class TikTokDto {
@ValidateIf(p => p.title)
@MaxLength(90)
title: string;
@IsIn([
'PUBLIC_TO_EVERYONE',
'MUTUAL_FOLLOW_FRIENDS',
@ -32,10 +36,6 @@ export class TikTokDto {
@IsBoolean()
brand_organic_toggle: boolean;
// @IsIn(['true'])
// @IsDefined()
// isValidVideo: boolean;
@IsIn(['DIRECT_POST', 'UPLOAD'])
@IsString()
content_posting_method: 'DIRECT_POST' | 'UPLOAD';

View File

@ -66,6 +66,13 @@ export class FacebookProvider extends SocialAbstract implements SocialProvider {
};
}
if (body.indexOf('1404006') > -1) {
return {
type: 'bad-body' as const,
value: "We couldn't post your comment, A security check in facebook required to proceed.",
};
}
if (body.indexOf('1404102') > -1) {
return {
type: 'bad-body' as const,

View File

@ -63,7 +63,63 @@ export class TiktokProvider extends SocialAbstract implements SocialProvider {
};
}
// Spam/Policy errors
if (body.indexOf('file_format_check_failed') > -1) {
return {
type: 'bad-body' as const,
value: 'File format is invalid, please check video specifications',
};
}
if (body.indexOf('duration_check_failed') > -1) {
return {
type: 'bad-body' as const,
value: 'Video duration is invalid, please check video specifications',
};
}
if (body.indexOf('frame_rate_check_failed') > -1) {
return {
type: 'bad-body' as const,
value: 'Video frame rate is invalid, please check video specifications',
};
}
if (body.indexOf('video_pull_failed') > -1) {
return {
type: 'bad-body' as const,
value: 'Failed to pull video from URL, please check the URL',
};
}
if (body.indexOf('photo_pull_failed') > -1) {
return {
type: 'bad-body' as const,
value: 'Failed to pull photo from URL, please check the URL',
};
}
if (body.indexOf('spam_risk_user_banned_from_posting') > -1) {
return {
type: 'bad-body' as const,
value:
'Account banned from posting, please check TikTok account status',
};
}
if (body.indexOf('spam_risk_text') > -1) {
return {
type: 'bad-body' as const,
value: 'TikTok detected potential spam in the post text',
};
}
if (body.indexOf('spam_risk') > -1) {
return {
type: 'bad-body' as const,
value: 'TikTok detected potential spam',
};
}
if (body.indexOf('spam_risk_too_many_posts') > -1) {
return {
type: 'bad-body' as const,
@ -125,14 +181,21 @@ export class TiktokProvider extends SocialAbstract implements SocialProvider {
}
// Server errors
if (body.indexOf('internal_error') > -1) {
if (body.indexOf('internal') > -1) {
return {
type: 'bad-body' as const,
value: 'TikTok server error, please try again later',
value: 'There is a problem with TikTok servers, please try again later',
};
}
// Generic TikTok API errors
if (body.indexOf('picture_size_check_failed') > -1) {
return {
type: 'bad-body' as const,
value: 'Picture size is invalid',
};
}
if (body.indexOf('TikTok API error') > -1) {
return {
type: 'bad-body' as const,
@ -358,8 +421,9 @@ export class TiktokProvider extends SocialAbstract implements SocialProvider {
postDetails: PostDetails<TikTokDto>[],
integration: Integration
): Promise<PostResponse[]> {
const [firstPost, ...comments] = postDetails;
const [firstPost] = postDetails;
const isPhoto = (firstPost?.media?.[0]?.path?.indexOf('mp4') || -1) === -1;
const {
data: { publish_id },
} = await (
@ -379,8 +443,17 @@ export class TiktokProvider extends SocialAbstract implements SocialProvider {
'DIRECT_POST') === 'DIRECT_POST'
? {
post_info: {
title: firstPost.message,
privacy_level: firstPost.settings.privacy_level || 'PUBLIC_TO_EVERYONE',
...((firstPost?.settings?.title && isPhoto) ||
(firstPost.message && !isPhoto)
? {
title: isPhoto
? firstPost.settings.title
: firstPost.message,
}
: {}),
...(isPhoto ? { description: firstPost.message } : {}),
privacy_level:
firstPost.settings.privacy_level || 'PUBLIC_TO_EVERYONE',
disable_duet: !firstPost.settings.duet || false,
disable_comment: !firstPost.settings.comment || false,
disable_stitch: !firstPost.settings.stitch || false,