diff --git a/libraries/nestjs-libraries/src/database/prisma/integrations/integration.service.ts b/libraries/nestjs-libraries/src/database/prisma/integrations/integration.service.ts index d23de149..4f574a37 100644 --- a/libraries/nestjs-libraries/src/database/prisma/integrations/integration.service.ts +++ b/libraries/nestjs-libraries/src/database/prisma/integrations/integration.service.ts @@ -33,7 +33,7 @@ export class IntegrationService { private _autopostsRepository: AutopostRepository, private _integrationManager: IntegrationManager, private _notificationService: NotificationService, - private _workerServiceProducer: BullMqClient + private _workerServiceProducer: BullMqClient, ) {} async changeActiveCron(orgId: string) { @@ -460,15 +460,18 @@ export class IntegrationService { ); } - async processInternalPlug(data: { - post: string; - originalIntegration: string; - integration: string; - plugName: string; - orgId: string; - delay: number; - information: any; - }) { + async processInternalPlug( + data: { + post: string; + originalIntegration: string; + integration: string; + plugName: string; + orgId: string; + delay: number; + information: any; + }, + forceRefresh = false + ): Promise { const originalIntegration = await this._integrationRepository.getIntegrationById( data.orgId, @@ -496,6 +499,63 @@ export class IntegrationService { getIntegration.providerIdentifier ); + if ( + dayjs(getIntegration?.tokenExpiration).isBefore(dayjs()) || + forceRefresh + ) { + const { accessToken, expiresIn, refreshToken, additionalSettings } = + await new Promise((res) => { + getSocialIntegration + .refreshToken(getIntegration.refreshToken!) + .then((r) => res(r)) + .catch(() => + res({ + accessToken: '', + expiresIn: 0, + refreshToken: '', + id: '', + name: '', + username: '', + picture: '', + additionalSettings: undefined, + }) + ); + }); + + if (!accessToken) { + await this.refreshNeeded( + getIntegration.organizationId, + getIntegration.id + ); + + await this.informAboutRefreshError( + getIntegration.organizationId, + getIntegration + ); + return {}; + } + + await this.createOrUpdateIntegration( + additionalSettings, + !!getSocialIntegration.oneTimeToken, + getIntegration.organizationId, + getIntegration.name, + getIntegration.picture!, + 'social', + getIntegration.internalId, + getIntegration.providerIdentifier, + accessToken, + refreshToken, + expiresIn + ); + + getIntegration.token = accessToken; + + if (getSocialIntegration.refreshWait) { + await timer(10000); + } + } + try { // @ts-ignore await getSocialIntegration?.[getAllInternalPlugs.methodName]?.( @@ -505,6 +565,10 @@ export class IntegrationService { data.information ); } catch (err) { + if (err instanceof RefreshToken) { + return this.processInternalPlug(data, true); + } + return; } } diff --git a/libraries/nestjs-libraries/src/integrations/social/linkedin.provider.ts b/libraries/nestjs-libraries/src/integrations/social/linkedin.provider.ts index b49cc81c..e1114391 100644 --- a/libraries/nestjs-libraries/src/integrations/social/linkedin.provider.ts +++ b/libraries/nestjs-libraries/src/integrations/social/linkedin.provider.ts @@ -687,35 +687,31 @@ export class LinkedinProvider extends SocialAbstract implements SocialProvider { information: any, isPersonal = true ) { - try { - await this.fetch(`https://api.linkedin.com/rest/posts`, { - body: JSON.stringify({ - author: - (isPersonal ? 'urn:li:person:' : `urn:li:organization:`) + - `${integration.internalId}`, - commentary: '', - visibility: 'PUBLIC', - distribution: { - feedDistribution: 'MAIN_FEED', - targetEntities: [], - thirdPartyDistributionChannels: [], - }, - lifecycleState: 'PUBLISHED', - isReshareDisabledByAuthor: false, - reshareContext: { - parent: postId, - }, - }), - method: 'POST', - headers: { - 'X-Restli-Protocol-Version': '2.0.0', - 'Content-Type': 'application/json', - 'LinkedIn-Version': '202504', - Authorization: `Bearer ${integration.token}`, + await this.fetch(`https://api.linkedin.com/rest/posts`, { + body: JSON.stringify({ + author: + (isPersonal ? 'urn:li:person:' : `urn:li:organization:`) + + `${integration.internalId}`, + commentary: '', + visibility: 'PUBLIC', + distribution: { + feedDistribution: 'MAIN_FEED', + targetEntities: [], + thirdPartyDistributionChannels: [], }, - }); - } catch (err) { - return; - } + lifecycleState: 'PUBLISHED', + isReshareDisabledByAuthor: false, + reshareContext: { + parent: postId, + }, + }), + method: 'POST', + headers: { + 'X-Restli-Protocol-Version': '2.0.0', + 'Content-Type': 'application/json', + 'LinkedIn-Version': '202504', + Authorization: `Bearer ${integration.token}`, + }, + }); } }