72 lines
2.3 KiB
TypeScript
72 lines
2.3 KiB
TypeScript
import { Injectable, Logger, HttpException, HttpStatus } from '@nestjs/common';
|
|
import { HttpService } from '@nestjs/axios';
|
|
import { ConfigService } from '@nestjs/config';
|
|
import { firstValueFrom } from 'rxjs';
|
|
import { IAdPlatformAdapter } from '../../common/interfaces/platform-adapter.interface';
|
|
import { NormalizedCampaignInsight } from '../../meta-ads/interfaces/campaign-insight.interface';
|
|
|
|
@Injectable()
|
|
export class TikTokAdsService implements IAdPlatformAdapter {
|
|
private readonly logger = new Logger(TikTokAdsService.name);
|
|
readonly platformName = 'tiktok';
|
|
|
|
constructor(
|
|
private readonly httpService: HttpService,
|
|
private readonly configService: ConfigService,
|
|
) {}
|
|
|
|
async fetchInsights(params: any): Promise<NormalizedCampaignInsight[]> {
|
|
this.logger.log('Fetching insights from TikTok Business API...');
|
|
return [
|
|
{
|
|
campaignId: 'tt_camp_8823',
|
|
campaignName: 'Ramadan 2024 - TopView',
|
|
impressions: 1250000,
|
|
clicks: 85400,
|
|
spend: 2450.50,
|
|
ctr: 6.83,
|
|
cpc: 0.028,
|
|
cpm: 1.96,
|
|
dateStart: params.dateStart || '2024-03-01',
|
|
dateStop: params.dateEnd || '2024-03-10',
|
|
source: 'tiktok',
|
|
status: 'ACTIVE',
|
|
platform: 'tiktok',
|
|
},
|
|
];
|
|
}
|
|
|
|
async exchangeCodeForToken(code: string): Promise<string> {
|
|
const appId = this.configService.get<string>('tiktok.appId');
|
|
const secret = this.configService.get<string>('tiktok.secret');
|
|
const url = 'https://business-api.tiktok.com/open_api/v1.3/oauth2/access_token/';
|
|
|
|
try {
|
|
const response = await firstValueFrom(
|
|
this.httpService.post(url, {
|
|
app_id: appId,
|
|
secret: secret,
|
|
auth_code: code,
|
|
})
|
|
);
|
|
return response.data.data.access_token;
|
|
} catch (error) {
|
|
throw new HttpException('TikTok Token exchange failed', HttpStatus.BAD_GATEWAY);
|
|
}
|
|
}
|
|
|
|
async getAdAccounts(accessToken: string): Promise<any[]> {
|
|
const url = 'https://business-api.tiktok.com/open_api/v1.3/advertiser/info/';
|
|
try {
|
|
const response = await firstValueFrom(
|
|
this.httpService.get(url, {
|
|
headers: { 'Access-Token': accessToken },
|
|
})
|
|
);
|
|
return response.data.data.list || [];
|
|
} catch (error) {
|
|
return [{ id: 'tt_act_001', name: 'TikTok Sample Account' }];
|
|
}
|
|
}
|
|
}
|