import { PrismaRepository } from '@gitroom/nestjs-libraries/database/prisma/prisma.service'; import { Injectable } from '@nestjs/common'; import dayjs from 'dayjs'; import * as console from 'node:console'; import { Integration } from '@prisma/client'; import { makeId } from '@gitroom/nestjs-libraries/services/make.is'; import { simpleUpload } from '@gitroom/nestjs-libraries/upload/r2.uploader'; import axios from 'axios'; @Injectable() export class IntegrationRepository { constructor( private _integration: PrismaRepository<'integration'>, private _posts: PrismaRepository<'post'> ) {} async updateIntegration(id: string, params: Partial) { if (params.picture && params.picture.indexOf(process.env.CLOUDFLARE_BUCKET_URL!) === -1) { const picture = await axios.get(params.picture, { responseType: 'arraybuffer' }); params.picture = await simpleUpload(picture.data, `${makeId(10)}.png`, 'image/png'); } return this._integration.model.integration.update({ where: { id, }, data: { ...params, }, }); } disconnectChannel(org: string, id: string) { return this._integration.model.integration.update({ where: { id, organizationId: org, }, data: { refreshNeeded: true, }, }); } createOrUpdateIntegration( org: string, name: string, picture: string, type: 'article' | 'social', internalId: string, provider: string, token: string, refreshToken = '', expiresIn = 999999999, username?: string, isBetweenSteps = false, refresh?: string ) { return this._integration.model.integration.upsert({ where: { organizationId_internalId: { internalId, organizationId: org, }, }, create: { type: type as any, name, providerIdentifier: provider, token, profile: username, picture, inBetweenSteps: isBetweenSteps, refreshToken, ...(expiresIn ? { tokenExpiration: new Date(Date.now() + expiresIn * 1000) } : {}), internalId, organizationId: org, refreshNeeded: false, }, update: { type: type as any, ...(!refresh ? { inBetweenSteps: isBetweenSteps, } : {}), name, picture, profile: username, providerIdentifier: provider, token, refreshToken, ...(expiresIn ? { tokenExpiration: new Date(Date.now() + expiresIn * 1000) } : {}), internalId, organizationId: org, deletedAt: null, refreshNeeded: false, }, }); } needsToBeRefreshed() { return this._integration.model.integration.findMany({ where: { tokenExpiration: { lte: dayjs().add(1, 'day').toDate(), }, inBetweenSteps: false, deletedAt: null, refreshNeeded: false, }, }); } refreshNeeded(org: string, id: string) { return this._integration.model.integration.update({ where: { id, organizationId: org, }, data: { refreshNeeded: true, }, }); } getIntegrationById(org: string, id: string) { return this._integration.model.integration.findFirst({ where: { organizationId: org, id, }, }); } async getIntegrationForOrder( id: string, order: string, user: string, org: string ) { const integration = await this._posts.model.post.findFirst({ where: { integrationId: id, submittedForOrder: { id: order, messageGroup: { OR: [ { sellerId: user }, { buyerId: user }, { buyerOrganizationId: org }, ], }, }, }, select: { integration: { select: { id: true, name: true, picture: true, inBetweenSteps: true, providerIdentifier: true, }, }, }, }); return integration?.integration; } getIntegrationsList(org: string) { return this._integration.model.integration.findMany({ where: { organizationId: org, deletedAt: null, }, }); } async disableChannel(org: string, id: string) { await this._integration.model.integration.update({ where: { id, organizationId: org, }, data: { disabled: true, }, }); } async enableChannel(org: string, id: string) { await this._integration.model.integration.update({ where: { id, organizationId: org, }, data: { disabled: false, }, }); } getPostsForChannel(org: string, id: string) { return this._posts.model.post.groupBy({ by: ['group'], where: { organizationId: org, integrationId: id, deletedAt: null }, }); } deleteChannel(org: string, id: string) { return this._integration.model.integration.update({ where: { id, organizationId: org, }, data: { deletedAt: new Date(), }, }); } async checkForDeletedOnceAndUpdate(org: string, page: string) { return this._integration.model.integration.updateMany({ where: { organizationId: org, internalId: page, deletedAt: { not: null, }, }, data: { internalId: makeId(10), }, }); } async disableIntegrations(org: string, totalChannels: number) { const getChannels = await this._integration.model.integration.findMany({ where: { organizationId: org, disabled: false, deletedAt: null, }, take: totalChannels, select: { id: true, }, }); for (const channel of getChannels) { await this._integration.model.integration.update({ where: { id: channel.id, }, data: { disabled: true, }, }); } } }