From 0ceaa3d04d195b3d48148e84cd514ce8ae48cc7d Mon Sep 17 00:00:00 2001 From: Nevo David Date: Tue, 10 Feb 2026 10:21:38 +0700 Subject: [PATCH] feat: trial reels --- .../instagram/instagram.collaborators.tsx | 50 +++++++++++++++++++ .../posts/providers-settings/instagram.dto.ts | 7 +++ .../integrations/social/instagram.provider.ts | 20 ++++++-- 3 files changed, 74 insertions(+), 3 deletions(-) diff --git a/apps/frontend/src/components/new-launch/providers/instagram/instagram.collaborators.tsx b/apps/frontend/src/components/new-launch/providers/instagram/instagram.collaborators.tsx index 6ca7b088..7bad425f 100644 --- a/apps/frontend/src/components/new-launch/providers/instagram/instagram.collaborators.tsx +++ b/apps/frontend/src/components/new-launch/providers/instagram/instagram.collaborators.tsx @@ -6,6 +6,7 @@ import { } from '@gitroom/frontend/components/new-launch/providers/high.order.provider'; import { FC } from 'react'; import { Select } from '@gitroom/react/form/select'; +import { Checkbox } from '@gitroom/react/form/checkbox'; import { useSettings } from '@gitroom/frontend/components/launches/helpers/use.values'; import { InstagramDto } from '@gitroom/nestjs-libraries/dtos/posts/providers-settings/instagram.dto'; import { InstagramCollaboratorsTags } from '@gitroom/frontend/components/new-launch/providers/instagram/instagram.tags'; @@ -21,12 +22,24 @@ const postType = [ label: 'Story', }, ]; + +const graduationStrategies = [ + { + value: 'MANUAL', + label: 'Manual', + }, + { + value: 'SS_PERFORMANCE', + label: 'Auto (based on performance)', + }, +]; const InstagramCollaborators: FC<{ values?: any; }> = (props) => { const t = useT(); const { watch, register, formState, control } = useSettings(); const postCurrentType = watch('post_type'); + const isTrialReel = watch('is_trial_reel'); return ( <> + {graduationStrategies.map((item) => ( + + ))} + + )} + + )} ); }; @@ -67,6 +106,17 @@ export default withProvider({ if ((firstPost?.length ?? 0) > 1 && settings?.post_type === 'story') { return 'Stories can only have one media'; } + if (settings?.is_trial_reel) { + if ((firstPost?.length ?? 0) > 1) { + return 'Trial Reels can only have one video'; + } + const hasVideo = firstPost?.some( + (f) => (f?.path?.indexOf?.('mp4') ?? -1) > -1 + ); + if (!hasVideo) { + return 'Trial Reels must be a video'; + } + } const checkVideosLength = await Promise.all( firstPost ?.filter((f) => (f?.path?.indexOf?.('mp4') ?? -1) > -1) diff --git a/libraries/nestjs-libraries/src/dtos/posts/providers-settings/instagram.dto.ts b/libraries/nestjs-libraries/src/dtos/posts/providers-settings/instagram.dto.ts index da9a2481..20b25446 100644 --- a/libraries/nestjs-libraries/src/dtos/posts/providers-settings/instagram.dto.ts +++ b/libraries/nestjs-libraries/src/dtos/posts/providers-settings/instagram.dto.ts @@ -18,6 +18,13 @@ export class InstagramDto { @IsDefined() post_type: 'post' | 'story'; + @IsOptional() + is_trial_reel?: boolean; + + @IsIn(['MANUAL', 'SS_PERFORMANCE']) + @IsOptional() + graduation_strategy?: 'MANUAL' | 'SS_PERFORMANCE'; + @Type(() => Collaborators) @ValidateNested({ each: true }) @IsArray() diff --git a/libraries/nestjs-libraries/src/integrations/social/instagram.provider.ts b/libraries/nestjs-libraries/src/integrations/social/instagram.provider.ts index e0568663..d0f8ab46 100644 --- a/libraries/nestjs-libraries/src/integrations/social/instagram.provider.ts +++ b/libraries/nestjs-libraries/src/integrations/social/instagram.provider.ts @@ -64,6 +64,12 @@ export class InstagramProvider value: 'An unknown error occurred, please try again later', }; } + if (body.indexOf('2207081') > -1) { + return { + type: 'bad-body' as const, + value: 'This account doesn\'t support Trial Reels', + }; + } if (body.indexOf('REVOKED_ACCESS_TOKEN') > -1) { return { @@ -457,6 +463,7 @@ export class InstagramProvider const [firstPost] = postDetails; console.log('in progress', id); const isStory = firstPost.settings.post_type === 'story'; + const isTrialReel = !!firstPost.settings.is_trial_reel; const medias = await Promise.all( firstPost?.media?.map(async (m) => { const caption = @@ -481,7 +488,15 @@ export class InstagramProvider : isStory ? `image_url=${m.path}&media_type=STORIES` : `image_url=${m.path}`; - console.log('in progress1'); + + const trialParams = isTrialReel + ? `&trial_params=${encodeURIComponent( + JSON.stringify({ + graduation_strategy: + firstPost.settings.graduation_strategy || 'MANUAL', + }) + )}` + : ``; const collaborators = firstPost?.settings?.collaborators?.length && !isStory @@ -490,10 +505,9 @@ export class InstagramProvider )}` : ``; - console.log(collaborators); const { id: photoId } = await ( await this.fetch( - `https://${type}/v20.0/${id}/media?${mediaType}${isCarousel}${collaborators}&access_token=${accessToken}${caption}`, + `https://${type}/v20.0/${id}/media?${mediaType}${isCarousel}${collaborators}${trialParams}&access_token=${accessToken}${caption}`, { method: 'POST', }