feat: provider

This commit is contained in:
Nevo David 2024-07-03 00:19:04 +07:00
parent 6b603bd87f
commit e21278661e
6 changed files with 250 additions and 47 deletions

View File

@ -382,8 +382,8 @@ export const withProvider = (
</EditorWrapper>,
document.querySelector('#renderEditor')!
)}
{showTab === 2 && (
<div className="mt-[20px]">
{(showTab === 0 || showTab === 2) && (
<div className={clsx("mt-[20px]", showTab !== 2 && 'hidden')}>
<Component />
</div>
)}

View File

@ -8,6 +8,133 @@ import {
linkedinCompanyPreventRemove,
} from '@gitroom/helpers/utils/linkedin.company.prevent.remove';
import { VideoOrImage } from '@gitroom/react/helpers/video.or.image';
import { TikTokDto } from '@gitroom/nestjs-libraries/dtos/posts/providers-settings/tiktok.dto';
import { useSettings } from '@gitroom/frontend/components/launches/helpers/use.values';
import { Select } from '@gitroom/react/form/select';
const privacyLevel = [
{
value: 'PUBLIC_TO_EVERYONE',
label: 'Public to everyone',
},
{
value: 'MUTUAL_FOLLOW_FRIENDS',
label: 'Mutual follow friends',
},
{
value: 'FOLLOWER_OF_CREATOR',
label: 'Follower of creator',
},
{
value: 'SELF_ONLY',
label: 'Self only',
},
];
const yesNo = [
{
value: 'true',
label: 'Yes',
},
{
value: 'false',
label: 'No',
},
];
const TikTokSettings: FC = () => {
const { register, control } = useSettings();
return (
<div className="flex flex-col">
<Select
label="Privacy Level"
{...register('privacy_level', {
value: 'PUBLIC_TO_EVERYONE',
})}
>
<option value="">Select</option>
{privacyLevel.map((item) => (
<option key={item.value} value={item.value}>
{item.label}
</option>
))}
</Select>
<Select
label="Disable Duet"
{...register('disable_duet', {
value: 'false',
setValueAs: (value) => value === 'true',
})}
>
<option value="">Select</option>
{yesNo.map((item) => (
<option key={item.value} value={item.value}>
{item.label}
</option>
))}
</Select>
<Select
label="Disable Stitch"
{...register('disable_stitch', {
value: 'false',
setValueAs: (value) => value === 'true',
})}
>
<option value="">Select</option>
{yesNo.map((item) => (
<option key={item.value} value={item.value}>
{item.label}
</option>
))}
</Select>
<Select
label="Disable Comments"
{...register('disable_comment', {
value: 'false',
setValueAs: (value) => value === 'true',
})}
>
<option value="">Select</option>
{yesNo.map((item) => (
<option key={item.value} value={item.value}>
{item.label}
</option>
))}
</Select>
<Select
label="Is Partnership?"
{...register('brand_content_toggle', {
value: 'false',
setValueAs: (value) => value === 'true',
})}
>
<option value="">Select</option>
{yesNo.map((item) => (
<option key={item.value} value={item.value}>
{item.label}
</option>
))}
</Select>
<Select
label="For my brand?"
{...register('brand_organic_toggle', {
value: 'true',
setValueAs: (value) => value === 'true',
})}
>
<option value="">Select</option>
{yesNo.map((item) => (
<option key={item.value} value={item.value}>
{item.label}
</option>
))}
</Select>
</div>
);
};
const TikTokPreview: FC = (props) => {
const { value: topValue, integration } = useIntegration();
@ -110,4 +237,4 @@ const TikTokPreview: FC = (props) => {
);
};
export default withProvider(null, TikTokPreview);
export default withProvider(TikTokSettings, TikTokPreview, TikTokDto);

View File

@ -11,6 +11,7 @@ import {RedditSettingsDto} from "@gitroom/nestjs-libraries/dtos/posts/providers-
import { YoutubeSettingsDto } from '@gitroom/nestjs-libraries/dtos/posts/providers-settings/youtube.settings.dto';
import { PinterestSettingsDto } from '@gitroom/nestjs-libraries/dtos/posts/providers-settings/pinterest.dto';
import { DribbbleDto } from '@gitroom/nestjs-libraries/dtos/posts/providers-settings/dribbble.dto';
import { TikTokDto } from '@gitroom/nestjs-libraries/dtos/posts/providers-settings/tiktok.dto';
export class EmptySettings {}
export class Integration {
@ -66,6 +67,7 @@ export class Post {
{ value: YoutubeSettingsDto, name: 'youtube' },
{ value: PinterestSettingsDto, name: 'pinterest' },
{ value: DribbbleDto, name: 'dribbble' },
{ value: TikTokDto, name: 'tiktok' },
],
},
})

View File

@ -4,6 +4,7 @@ import { HashnodeSettingsDto } from '@gitroom/nestjs-libraries/dtos/posts/provid
import { RedditSettingsDto } from '@gitroom/nestjs-libraries/dtos/posts/providers-settings/reddit.dto';
import { PinterestSettingsDto } from '@gitroom/nestjs-libraries/dtos/posts/providers-settings/pinterest.dto';
import { YoutubeSettingsDto } from '@gitroom/nestjs-libraries/dtos/posts/providers-settings/youtube.settings.dto';
import { TikTokDto } from '@gitroom/nestjs-libraries/dtos/posts/providers-settings/tiktok.dto';
export type AllProvidersSettings =
| DevToSettingsDto
@ -11,4 +12,5 @@ export type AllProvidersSettings =
| HashnodeSettingsDto
| RedditSettingsDto
| YoutubeSettingsDto
| PinterestSettingsDto;
| PinterestSettingsDto
| TikTokDto;

View File

@ -0,0 +1,22 @@
import { IsBoolean, IsIn, IsString } from 'class-validator';
export class TikTokDto {
@IsIn(['PUBLIC_TO_EVERYONE', 'MUTUAL_FOLLOW_FRIENDS', 'FOLLOWER_OF_CREATOR', 'SELF_ONLY'])
@IsString()
privacy_level: 'PUBLIC_TO_EVERYONE' | 'MUTUAL_FOLLOW_FRIENDS' | 'FOLLOWER_OF_CREATOR' | 'SELF_ONLY';
@IsBoolean()
disable_duet: boolean;
@IsBoolean()
disable_stitch: boolean;
@IsBoolean()
disable_comment: boolean;
@IsBoolean()
brand_content_toggle: boolean;
@IsBoolean()
brand_organic_toggle: boolean;
}

View File

@ -4,7 +4,6 @@ import {
PostResponse,
SocialProvider,
} from '@gitroom/nestjs-libraries/integrations/social/social.integrations.interface';
import { makeId } from '@gitroom/nestjs-libraries/services/make.is';
import dayjs from 'dayjs';
import { SocialAbstract } from '@gitroom/nestjs-libraries/integrations/social.abstract';
@ -13,57 +12,71 @@ export class TiktokProvider extends SocialAbstract implements SocialProvider {
name = 'Tiktok';
isBetweenSteps = false;
async refreshToken(refresh_token: string): Promise<AuthTokenDetails> {
async refreshToken(refreshToken: string): Promise<AuthTokenDetails> {
const value = {
client_key: process.env.TIKTOK_CLIENT_ID!,
client_secret: process.env.TIKTOK_CLIENT_SECRET!,
grant_type: 'authorization_code',
refresh_token: refreshToken,
};
const { access_token, refresh_token } = await (
await this.fetch('https://open.tiktokapis.com/v2/oauth/token/', {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
method: 'POST',
body: new URLSearchParams(value).toString(),
})
).json();
const {
data: {
user: { avatar_url, display_name, open_id },
},
} = await (
await fetch(
'https://open.tiktokapis.com/v2/user/info/?fields=open_id,avatar_url,display_name',
{
method: 'GET',
headers: {
Authorization: `Bearer ${access_token}`,
},
}
)
).json();
return {
refreshToken: '',
expiresIn: 0,
accessToken: '',
id: '',
name: '',
picture: '',
username: '',
refreshToken: refresh_token,
expiresIn: dayjs().add(23, 'hours').unix() - dayjs().unix(),
accessToken: access_token,
id: open_id.replace(/-/g, ''),
name: display_name,
picture: avatar_url,
username: display_name.toLowerCase(),
};
}
async generateAuthUrl(refresh?: string) {
const state = makeId(6);
console.log(
'https://www.tiktok.com/v2/auth/authorize' +
`?client_key=${process.env.TIKTOK_CLIENT_ID}` +
`&redirect_uri=${encodeURIComponent(
`${
process.env.NODE_ENV === 'development' || !process.env.NODE_ENV
? 'https://redirectmeto.com/'
: ''
}${process.env.FRONTEND_URL}/integrations/social/tiktok${
refresh ? `?refresh=${refresh}` : ''
}`
)}` +
`&state=${state}` +
`&response_type=code` +
`&scope=${encodeURIComponent(
'user.info.basic,video.publish,video.upload'
)}`
);
const state = Math.random().toString(36).substring(2);
return {
url:
'https://www.tiktok.com/v2/auth/authorize' +
'https://www.tiktok.com/v2/auth/authorize/' +
`?client_key=${process.env.TIKTOK_CLIENT_ID}` +
`&redirect_uri=${encodeURIComponent(
`${
process.env.NODE_ENV === 'development' || !process.env.NODE_ENV
? 'https://redirectmeto.com/'
: ''
}${process.env.FRONTEND_URL}/integrations/social/tiktok${
refresh ? `?refresh=${refresh}` : ''
}`
? `https://integration.git.sn/integrations/social/tiktok`
: `${process.env.FRONTEND_URL}/integrations/social/tiktok`
}${refresh ? `?refresh=${refresh}` : ''}`
)}` +
`&state=${state}` +
`&response_type=code` +
`&scope=${encodeURIComponent(
'user.info.basic,video.publish,video.upload'
)}`,
codeVerifier: makeId(10),
codeVerifier: state,
state,
};
}
@ -73,15 +86,52 @@ export class TiktokProvider extends SocialAbstract implements SocialProvider {
codeVerifier: string;
refresh?: string;
}) {
console.log(params);
const value = {
client_key: process.env.TIKTOK_CLIENT_ID!,
client_secret: process.env.TIKTOK_CLIENT_SECRET!,
code: params.code,
grant_type: 'authorization_code',
code_verifier: params.codeVerifier,
redirect_uri:
process.env.NODE_ENV === 'development' || !process.env.NODE_ENV
? `https://integration.git.sn/integrations/social/tiktok`
: `${process.env.FRONTEND_URL}/integrations/social/tiktok`,
};
const { access_token, refresh_token } = await (
await this.fetch('https://open.tiktokapis.com/v2/oauth/token/', {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
method: 'POST',
body: new URLSearchParams(value).toString(),
})
).json();
const {
data: {
user: { avatar_url, display_name, open_id },
},
} = await (
await fetch(
'https://open.tiktokapis.com/v2/user/info/?fields=open_id,avatar_url,display_name',
{
method: 'GET',
headers: {
Authorization: `Bearer ${access_token}`,
},
}
)
).json();
return {
id: '',
name: '',
accessToken: '',
refreshToken: '',
expiresIn: dayjs().add(59, 'days').unix() - dayjs().unix(),
picture: '',
username: '',
id: open_id.replace(/-/g, ''),
name: display_name,
accessToken: access_token,
refreshToken: refresh_token,
expiresIn: dayjs().add(23, 'hours').unix() - dayjs().unix(),
picture: avatar_url,
username: display_name.toLowerCase(),
};
}