Download apps/backend/src/api/routes/integrations.controller.ts from Leon4gr45/postio: direct link, hf CLI and curl.
- Browser
- Download file 14 kB
-
https://huggingface.co/spaces/Leon4gr45/postio/resolve/main/apps/backend/src/api/routes/integrations.controller.ts
- Command line
-
hf download hf://spaces/Leon4gr45/postio/apps/backend/src/api/routes/integrations.controller.ts
-
curl -L -o integrations.controller.ts https://huggingface.co/spaces/Leon4gr45/postio/resolve/main/apps/backend/src/api/routes/integrations.controller.ts
14 kB
| import { | |
| Body, | |
| Controller, | |
| Delete, | |
| Get, | |
| Param, | |
| Post, | |
| Put, | |
| Query, | |
| } from '@nestjs/common'; | |
| import { ioRedis } from '@gitroom/nestjs-libraries/redis/redis.service'; | |
| import { IntegrationManager } from '@gitroom/nestjs-libraries/integrations/integration.manager'; | |
| import { IntegrationService } from '@gitroom/nestjs-libraries/database/prisma/integrations/integration.service'; | |
| import { GetOrgFromRequest } from '@gitroom/nestjs-libraries/user/org.from.request'; | |
| import { Organization, User } from '@prisma/client'; | |
| import { IntegrationFunctionDto } from '@gitroom/nestjs-libraries/dtos/integrations/integration.function.dto'; | |
| import { CheckPolicies } from '@gitroom/backend/services/auth/permissions/permissions.ability'; | |
| import { pricing } from '@gitroom/nestjs-libraries/database/prisma/subscriptions/pricing'; | |
| import { ApiTags } from '@nestjs/swagger'; | |
| import { GetUserFromRequest } from '@gitroom/nestjs-libraries/user/user.from.request'; | |
| import { PostsService } from '@gitroom/nestjs-libraries/database/prisma/posts/posts.service'; | |
| import { IntegrationTimeDto } from '@gitroom/nestjs-libraries/dtos/integrations/integration.time.dto'; | |
| import { PlugDto } from '@gitroom/nestjs-libraries/dtos/plugs/plug.dto'; | |
| import { RefreshToken } from '@gitroom/nestjs-libraries/integrations/social.abstract'; | |
| import { timer } from '@gitroom/helpers/utils/timer'; | |
| import { TelegramProvider } from '@gitroom/nestjs-libraries/integrations/social/telegram.provider'; | |
| import { MoltbookProvider } from '@gitroom/nestjs-libraries/integrations/social/moltbook.provider'; | |
| import { | |
| AuthorizationActions, | |
| Sections, | |
| } from '@gitroom/backend/services/auth/permissions/permission.exception.class'; | |
| import { uniqBy } from 'lodash'; | |
| import { RefreshIntegrationService } from '@gitroom/nestjs-libraries/integrations/refresh.integration.service'; | |
| ('Integrations') | |
| ('/integrations') | |
| export class IntegrationsController { | |
| constructor( | |
| private _integrationManager: IntegrationManager, | |
| private _integrationService: IntegrationService, | |
| private _postService: PostsService, | |
| private _refreshIntegrationService: RefreshIntegrationService | |
| ) {} | |
| ('/provider/:id/connect') | |
| ([AuthorizationActions.Create, Sections.CHANNEL]) | |
| async saveProviderPage( | |
| () org: Organization, | |
| ('id') id: string, | |
| () body: any | |
| ) { | |
| return this._integrationService.saveProviderPage(org.id, id, body); | |
| } | |
| ('/:identifier/internal-plugs') | |
| getInternalPlugs(('identifier') identifier: string) { | |
| return this._integrationManager.getInternalPlugs(identifier); | |
| } | |
| ('/customers') | |
| getCustomers(() org: Organization) { | |
| return this._integrationService.customers(org.id); | |
| } | |
| ('/:id/group') | |
| async updateIntegrationGroup( | |
| () org: Organization, | |
| ('id') id: string, | |
| () body: { group: string } | |
| ) { | |
| return this._integrationService.updateIntegrationGroup( | |
| org.id, | |
| id, | |
| body.group | |
| ); | |
| } | |
| ('/:id/customer-name') | |
| async updateOnCustomerName( | |
| () org: Organization, | |
| ('id') id: string, | |
| () body: { name: string } | |
| ) { | |
| return this._integrationService.updateOnCustomerName(org.id, id, body.name); | |
| } | |
| ('/list') | |
| async getIntegrationList(() org: Organization) { | |
| return { | |
| integrations: await Promise.all( | |
| ( | |
| await this._integrationService.getIntegrationsList(org.id) | |
| ).map(async (p) => { | |
| const findIntegration = this._integrationManager.getSocialIntegration( | |
| p.providerIdentifier | |
| ); | |
| return { | |
| name: p.name, | |
| id: p.id, | |
| internalId: p.internalId, | |
| disabled: p.disabled, | |
| editor: findIntegration.editor, | |
| stripLinks: !!findIntegration?.stripLinks?.(), | |
| picture: p.picture || '/no-picture.jpg', | |
| identifier: p.providerIdentifier, | |
| inBetweenSteps: p.inBetweenSteps, | |
| refreshNeeded: p.refreshNeeded, | |
| isCustomFields: !!findIntegration.customFields, | |
| ...(findIntegration.customFields | |
| ? { customFields: await findIntegration.customFields() } | |
| : {}), | |
| display: p.profile, | |
| type: p.type, | |
| time: JSON.parse(p.postingTimes), | |
| changeProfilePicture: !!findIntegration?.changeProfilePicture, | |
| changeNickName: !!findIntegration?.changeNickname, | |
| customer: p.customer, | |
| additionalSettings: p.additionalSettings || '[]', | |
| }; | |
| }) | |
| ), | |
| }; | |
| } | |
| ('/:id/settings') | |
| async updateProviderSettings( | |
| () org: Organization, | |
| ('id') id: string, | |
| ('additionalSettings') body: string | |
| ) { | |
| if (typeof body !== 'string') { | |
| throw new Error('Invalid body'); | |
| } | |
| await this._integrationService.updateProviderSettings(org.id, id, body); | |
| } | |
| ('/:id/nickname') | |
| async setNickname( | |
| () org: Organization, | |
| ('id') id: string, | |
| () body: { name: string; picture: string } | |
| ) { | |
| const integration = await this._integrationService.getIntegrationById( | |
| org.id, | |
| id | |
| ); | |
| if (!integration) { | |
| throw new Error('Invalid integration'); | |
| } | |
| const manager = this._integrationManager.getSocialIntegration( | |
| integration.providerIdentifier | |
| ); | |
| if (!manager.changeProfilePicture && !manager.changeNickname) { | |
| throw new Error('Invalid integration'); | |
| } | |
| const { url } = manager.changeProfilePicture | |
| ? await manager.changeProfilePicture( | |
| integration.internalId, | |
| integration.token, | |
| body.picture | |
| ) | |
| : { url: '' }; | |
| const { name } = manager.changeNickname | |
| ? await manager.changeNickname( | |
| integration.internalId, | |
| integration.token, | |
| body.name | |
| ) | |
| : { name: '' }; | |
| return this._integrationService.updateNameAndUrl(id, name, url); | |
| } | |
| ('/:id') | |
| getSingleIntegration( | |
| ('id') id: string, | |
| ('order') order: string, | |
| () user: User, | |
| () org: Organization | |
| ) { | |
| return this._integrationService.getIntegrationForOrder( | |
| id, | |
| order, | |
| user.id, | |
| org.id | |
| ); | |
| } | |
| ('/social/:integration') | |
| ([AuthorizationActions.Create, Sections.CHANNEL]) | |
| async getIntegrationUrl( | |
| ('integration') integration: string, | |
| ('refresh') refresh: string, | |
| ('externalUrl') externalUrl: string, | |
| ('redirectUrl') redirectUrl: string, | |
| ('onboarding') onboarding: string, | |
| () org: Organization | |
| ) { | |
| if ( | |
| !this._integrationManager | |
| .getAllowedSocialsIntegrations() | |
| .includes(integration) | |
| ) { | |
| throw new Error('Integration not allowed'); | |
| } | |
| const integrationProvider = | |
| this._integrationManager.getSocialIntegration(integration); | |
| if (integrationProvider.externalUrl && !externalUrl) { | |
| throw new Error('Missing external url'); | |
| } | |
| try { | |
| const getExternalUrl = integrationProvider.externalUrl | |
| ? { | |
| ...(await integrationProvider.externalUrl(externalUrl)), | |
| instanceUrl: externalUrl, | |
| } | |
| : undefined; | |
| const { codeVerifier, state, url } = | |
| await integrationProvider.generateAuthUrl(getExternalUrl); | |
| if (refresh) { | |
| await ioRedis.set(`refresh:${state}`, refresh, 'EX', 3600); | |
| } | |
| if (onboarding === 'true') { | |
| await ioRedis.set(`onboarding:${state}`, 'true', 'EX', 3600); | |
| } | |
| if (redirectUrl) { | |
| await ioRedis.set(`redirect:${state}`, redirectUrl, 'EX', 3600); | |
| } | |
| await ioRedis.set(`organization:${state}`, org.id, 'EX', 3600); | |
| await ioRedis.set(`login:${state}`, codeVerifier, 'EX', 3600); | |
| await ioRedis.set( | |
| `external:${state}`, | |
| JSON.stringify(getExternalUrl), | |
| 'EX', | |
| 3600 | |
| ); | |
| return { url }; | |
| } catch (err) { | |
| return { err: true }; | |
| } | |
| } | |
| ('/:id/time') | |
| async setTime( | |
| () org: Organization, | |
| ('id') id: string, | |
| () body: IntegrationTimeDto | |
| ) { | |
| return this._integrationService.setTimes(org.id, id, body); | |
| } | |
| ('/mentions') | |
| async mentions( | |
| () org: Organization, | |
| () body: IntegrationFunctionDto | |
| ) { | |
| const getIntegration = await this._integrationService.getIntegrationById( | |
| org.id, | |
| body.id | |
| ); | |
| if (!getIntegration) { | |
| throw new Error('Invalid integration'); | |
| } | |
| let newList: any[] | { none: true } = []; | |
| try { | |
| newList = (await this.functionIntegration(org, body)) || []; | |
| } catch (err) { | |
| console.log(err); | |
| } | |
| if (!Array.isArray(newList) && newList?.none) { | |
| return newList; | |
| } | |
| const list = await this._integrationService.getMentions( | |
| getIntegration.providerIdentifier, | |
| body?.data?.query | |
| ); | |
| if (Array.isArray(newList) && newList.length) { | |
| await this._integrationService.insertMentions( | |
| getIntegration.providerIdentifier, | |
| newList | |
| .map((p: any) => ({ | |
| name: p.label || '', | |
| username: p.id || '', | |
| image: p.image || '', | |
| doNotCache: p.doNotCache || false, | |
| })) | |
| .filter((f: any) => f.name && !f.doNotCache) | |
| ); | |
| } | |
| return uniqBy( | |
| [ | |
| ...list.map((p) => ({ | |
| id: p.username, | |
| image: p.image, | |
| label: p.name, | |
| })), | |
| ...(newList as any[]), | |
| ], | |
| (p) => p.id | |
| ).filter((f) => f.label && f.id); | |
| } | |
| ('/function') | |
| async functionIntegration( | |
| () org: Organization, | |
| () body: IntegrationFunctionDto | |
| ): Promise<any> { | |
| const getIntegration = await this._integrationService.getIntegrationById( | |
| org.id, | |
| body.id | |
| ); | |
| if (!getIntegration) { | |
| throw new Error('Invalid integration'); | |
| } | |
| const integrationProvider = this._integrationManager.getSocialIntegration( | |
| getIntegration.providerIdentifier | |
| ); | |
| if (!integrationProvider) { | |
| throw new Error('Invalid provider'); | |
| } | |
| // @ts-ignore | |
| if (integrationProvider[body.name]) { | |
| try { | |
| // @ts-ignore | |
| const load = await integrationProvider[body.name]( | |
| getIntegration.token, | |
| body.data, | |
| getIntegration.internalId, | |
| getIntegration | |
| ); | |
| return load; | |
| } catch (err) { | |
| if (err instanceof RefreshToken) { | |
| const data = await this._refreshIntegrationService.refresh( | |
| getIntegration | |
| ); | |
| if (!data) { | |
| return; | |
| } | |
| const { accessToken } = data; | |
| if (accessToken) { | |
| if (integrationProvider.refreshWait) { | |
| await timer(10000); | |
| } | |
| return this.functionIntegration(org, body); | |
| } | |
| return false; | |
| } | |
| return false; | |
| } | |
| } | |
| throw new Error('Function not found'); | |
| } | |
| ('/disable') | |
| disableChannel( | |
| () org: Organization, | |
| ('id') id: string | |
| ) { | |
| return this._integrationService.disableChannel(org.id, id); | |
| } | |
| ('/enable') | |
| enableChannel( | |
| () org: Organization, | |
| ('id') id: string | |
| ) { | |
| return this._integrationService.enableChannel( | |
| org.id, | |
| // @ts-ignore | |
| org?.subscription?.totalChannels || pricing.FREE.channel, | |
| id | |
| ); | |
| } | |
| ('/') | |
| async deleteChannel( | |
| () org: Organization, | |
| ('id') id: string | |
| ) { | |
| const isTherePosts = await this._integrationService.getPostsForChannel( | |
| org.id, | |
| id | |
| ); | |
| if (isTherePosts.length) { | |
| for (const post of isTherePosts) { | |
| this._postService.deletePost(org.id, post.group).catch((err) => {}); | |
| } | |
| } | |
| return this._integrationService.deleteChannel(org.id, id); | |
| } | |
| ('/plug/list') | |
| async getPlugList() { | |
| return { plugs: this._integrationManager.getAllPlugs() }; | |
| } | |
| ('/:id/plugs') | |
| async getPlugsByIntegrationId( | |
| ('id') id: string, | |
| () org: Organization | |
| ) { | |
| return this._integrationService.getPlugsByIntegrationId(org.id, id); | |
| } | |
| ('/:id/plugs') | |
| async postPlugsByIntegrationId( | |
| ('id') id: string, | |
| () org: Organization, | |
| () body: PlugDto | |
| ) { | |
| return this._integrationService.createOrUpdatePlug(org.id, id, body); | |
| } | |
| ('/plugs/:id/activate') | |
| async changePlugActivation( | |
| ('id') id: string, | |
| () org: Organization, | |
| ('status') status: boolean | |
| ) { | |
| return this._integrationService.changePlugActivation(org.id, id, status); | |
| } | |
| ('/telegram/updates') | |
| async getUpdates(() query: { word: string; id?: number }) { | |
| return new TelegramProvider().getBotId(query); | |
| } | |
| ('/moltbook/register') | |
| async moltbookRegister(() body: { name: string; description: string }) { | |
| try { | |
| const provider = new MoltbookProvider(); | |
| const result = await provider.registerAgent(body.name, body.description); | |
| return { | |
| apiKey: result.api_key, | |
| claimUrl: result.claim_url, | |
| verificationCode: result.verification_code, | |
| }; | |
| } catch (err: any) { | |
| return { error: err.message || 'Registration failed' }; | |
| } | |
| } | |
| ('/moltbook/status') | |
| async moltbookStatus(('apiKey') apiKey: string) { | |
| try { | |
| const provider = new MoltbookProvider(); | |
| const result = await provider.checkAgentStatus(apiKey); | |
| return { claimed: result?.status === 'claimed' }; | |
| } catch (err) { | |
| return { claimed: false }; | |
| } | |
| } | |
| } | |