From 4b4bf425349a2005addf8ebf26abcbfe0072743e Mon Sep 17 00:00:00 2001 From: Artem Savchenko Date: Tue, 7 Oct 2025 07:27:08 +0700 Subject: [PATCH 1/5] Support telegram reconnect Signed-off-by: Artem Savchenko --- packages/integration-client/src/client.ts | 45 ++++ packages/integration-client/src/types.ts | 10 + packages/integration-client/src/utils.ts | 15 ++ packages/theme/styles/_colors.scss | 8 + plugins/setting-assets/lang/cs.json | 1 + plugins/setting-assets/lang/de.json | 1 + plugins/setting-assets/lang/en.json | 1 + plugins/setting-assets/lang/es.json | 1 + plugins/setting-assets/lang/fr.json | 1 + plugins/setting-assets/lang/it.json | 1 + plugins/setting-assets/lang/ja.json | 1 + plugins/setting-assets/lang/pt.json | 1 + plugins/setting-assets/lang/ru.json | 1 + plugins/setting-assets/lang/tr.json | 1 + plugins/setting-assets/lang/zh.json | 1 + .../integrations/IntegrationCard.svelte | 38 +-- .../integrations/IntegrationLabel.svelte | 47 +++- plugins/setting-resources/src/utils.ts | 15 +- plugins/setting/src/index.ts | 1 + plugins/telegram-resources/package.json | 1 + plugins/telegram-resources/src/api.ts | 2 +- .../src/components/Connect.svelte | 57 +++-- .../src/components/IntegrationState.svelte | 22 +- .../src/components/Reconnect.svelte | 223 +----------------- 24 files changed, 232 insertions(+), 263 deletions(-) diff --git a/packages/integration-client/src/client.ts b/packages/integration-client/src/client.ts index 4645c5039f6..4d4d6bdf288 100644 --- a/packages/integration-client/src/client.ts +++ b/packages/integration-client/src/client.ts @@ -337,4 +337,49 @@ export class IntegrationClientImpl implements IntegrationClient { await this.client.addIntegrationSecret(data) } } + + async removeSecrets (integration: Integration): Promise { + const secrets = await this.client.listIntegrationsSecrets({ + socialId: integration.socialId, + kind: integration.kind, + workspaceUuid: integration.workspaceUuid + }) + for (const secret of secrets) { + await this.client.deleteIntegrationSecret(secret) + } + } + + async setIntegrationEnabled (integrationKey: IntegrationKey, enabled: boolean): Promise { + try { + const integration = await this.client.getIntegration(integrationKey) + if (integration == null) { + throw new Error(`Integration not found: ${JSON.stringify(integrationKey)}`) + } + + const data = { + ...integration.data, + disabled: !enabled + } + + await this.client.updateIntegration({ + ...integration, + disabled: !enabled + }) + + const eventData: IntegrationEventData = { + integration: { ...integration, data }, + timestamp: Date.now() + } + this.emit(enabled ? 'integration:enabled' : 'integration:disabled', eventData) + } catch (error) { + const errorData: IntegrationErrorData = { + operation: 'setIntegrationEnabled', + error: error instanceof Error ? error.message : String(error), + integrationKey, + timestamp: Date.now() + } + this.emit('integration:error', errorData) + throw error + } + } } diff --git a/packages/integration-client/src/types.ts b/packages/integration-client/src/types.ts index aaf1c3761fd..45e02f17647 100644 --- a/packages/integration-client/src/types.ts +++ b/packages/integration-client/src/types.ts @@ -72,6 +72,16 @@ export interface IntegrationClient { * Set or update integration secret */ setSecret: (data: IntegrationSecret) => Promise + + /** + * Remove all integration secrets + */ + removeSecrets: (integration: Integration) => Promise + + /** + * Disable or enable an integration + */ + setIntegrationEnabled: (integrationKey: IntegrationKey, enabled: boolean) => Promise } export interface IntegrationEventData { diff --git a/packages/integration-client/src/utils.ts b/packages/integration-client/src/utils.ts index 62f93d9c932..a08d2b13b9a 100644 --- a/packages/integration-client/src/utils.ts +++ b/packages/integration-client/src/utils.ts @@ -14,6 +14,7 @@ // import { Integration } from '@hcengineering/account-client' +import platform, { PlatformError } from '@hcengineering/platform' import { IntegrationEventData } from './types' export function isWorkspaceIntegration (integration: Integration): boolean { @@ -34,3 +35,17 @@ export function isSameIntegrationEvent (event: IntegrationEventData, integration export function getIntegrationConfig (integration: Integration): Record | undefined { return integration?.data?.config } + +export function isDisabled (integration: Integration): boolean { + return integration?.data?.disabled === true +} + +export function isUnauthorizedError (error: any): boolean { + if (error instanceof PlatformError && error.status.code === platform.status.Unauthorized) { + return true + } + if (error?.status === 401 || error?.status?.code === 401) { + return true + } + return false +} diff --git a/packages/theme/styles/_colors.scss b/packages/theme/styles/_colors.scss index b44a16306da..de226a53a8a 100644 --- a/packages/theme/styles/_colors.scss +++ b/packages/theme/styles/_colors.scss @@ -403,6 +403,10 @@ --theme-label-blue-bg-color: rgba(59, 130, 246, .08); --theme-label-blue-border-color: rgba(59, 130, 246, .2); + --theme-label-orange-color: rgba(249, 115, 22, .8); + --theme-label-orange-bg-color: rgba(249, 115, 22, .08); + --theme-label-orange-border-color: rgba(249, 115, 22, .2); + --theme-label-gray-color: rgba(255, 255, 255, .6); --theme-label-gray-bg-color: rgba(255, 255, 255, .02); --theme-label-gray-border-color: rgba(255, 255, 255, .09); @@ -718,6 +722,10 @@ --theme-label-blue-bg-color: rgba(59, 130, 246, .08); --theme-label-blue-border-color: rgba(59, 130, 246, .15); + --theme-label-orange-color: rgba(194, 65, 12, 0.9); + --theme-label-orange-bg-color: rgba(249, 115, 22, .08); + --theme-label-orange-border-color: rgba(249, 115, 22, .15); + --theme-label-gray-color: rgba(0, 0, 0, .6); --theme-label-gray-bg-color: rgba(0, 0, 0, .02); --theme-label-gray-border-color: rgba(0, 0, 0, .09); diff --git a/plugins/setting-assets/lang/cs.json b/plugins/setting-assets/lang/cs.json index 006026a9a81..43f8618c7dc 100644 --- a/plugins/setting-assets/lang/cs.json +++ b/plugins/setting-assets/lang/cs.json @@ -191,6 +191,7 @@ "ServiceIsUnavailable": "Služba není k dispozici", "Integrated": "Integrované", "Connected": "Připojené", + "Disconnected": "Odpojené", "Available": "Dostupné", "NotConnectedIntegration": "Účet {account} není integrován s pracovním prostorem", "IntegrationIsUnstable": "Integrační služba má problémy. Některé funkce nemusí fungovat správně.", diff --git a/plugins/setting-assets/lang/de.json b/plugins/setting-assets/lang/de.json index 22712912b0e..2a41cbcb148 100644 --- a/plugins/setting-assets/lang/de.json +++ b/plugins/setting-assets/lang/de.json @@ -193,6 +193,7 @@ "ServiceIsUnavailable": "Dienst ist nicht verfügbar", "Integrated": "Integriert", "Connected": "Verbunden", + "Disconnected": "Getrennt", "Available": "Verfügbar", "NotConnectedIntegration": "Das Konto {account} ist nicht mit dem Arbeitsbereich integriert", "IntegrationIsUnstable": "Der Integrationsdienst hat Probleme. Einige Funktionen funktionieren möglicherweise nicht richtig.", diff --git a/plugins/setting-assets/lang/en.json b/plugins/setting-assets/lang/en.json index 42d5d81be98..2aab6077414 100644 --- a/plugins/setting-assets/lang/en.json +++ b/plugins/setting-assets/lang/en.json @@ -193,6 +193,7 @@ "ServiceIsUnavailable": "Service is unavailable", "Integrated": "Integrated", "Connected": "Connected", + "Disconnected": "Disconnected", "Available": "Available", "NotConnectedIntegration": "The account {account} is not integrated with the workspace", "IntegrationIsUnstable": "Integration service is experiencing issues. Some features may not work properly.", diff --git a/plugins/setting-assets/lang/es.json b/plugins/setting-assets/lang/es.json index 7dcf0014e63..e0e20d0a3f6 100644 --- a/plugins/setting-assets/lang/es.json +++ b/plugins/setting-assets/lang/es.json @@ -184,6 +184,7 @@ "ServiceIsUnavailable": "El servicio no está disponible", "Integrated": "Integrado", "Connected": "Conectado", + "Disconnected": "Desconectado", "Available": "Disponible", "NotConnectedIntegration": "La cuenta {account} no está integrada con el espacio de trabajo", "IntegrationIsUnstable": "El servicio de integración está experimentando problemas. Es posible que algunas funciones no funcionen correctamente.", diff --git a/plugins/setting-assets/lang/fr.json b/plugins/setting-assets/lang/fr.json index 1ad81df5da4..4c6d4262d38 100644 --- a/plugins/setting-assets/lang/fr.json +++ b/plugins/setting-assets/lang/fr.json @@ -193,6 +193,7 @@ "ServiceIsUnavailable": "Le service n'est pas disponible", "Integrated": "Intégré", "Connected": "Connecté", + "Disconnected": "Déconnecté", "Available": "Disponible", "NotConnectedIntegration": "Le compte {account} n'est pas intégré au workspace", "IntegrationIsUnstable": "Le service d'intégration rencontre des problèmes. Certaines fonctionnalités peuvent ne pas fonctionner correctement.", diff --git a/plugins/setting-assets/lang/it.json b/plugins/setting-assets/lang/it.json index c8a6dd2048e..443521c7e10 100644 --- a/plugins/setting-assets/lang/it.json +++ b/plugins/setting-assets/lang/it.json @@ -193,6 +193,7 @@ "ServiceIsUnavailable": "Il servizio non è disponibile", "Integrated": "Integrato", "Connected": "Connesso", + "Disconnected": "Disconnesso", "Available": "Disponibile", "NotConnectedIntegration": "L'account {account} non è integrato con il workspace", "IntegrationIsUnstable": "L'integrazione è instabile. Alcune funzionalità potrebbero non funzionare correttamente.", diff --git a/plugins/setting-assets/lang/ja.json b/plugins/setting-assets/lang/ja.json index bd985a94d1d..3066a7f0641 100644 --- a/plugins/setting-assets/lang/ja.json +++ b/plugins/setting-assets/lang/ja.json @@ -193,6 +193,7 @@ "ServiceIsUnavailable": "サービスは利用できません", "Integrated": "統合済み", "Connected": "接続済み", + "Disconnected": "切断済み", "Available": "利用可能", "NotConnectedIntegration": "アカウント {account} はワークスペースに統合されていません", "IntegrationIsUnstable": "統合サービスに問題が発生しています。一部の機能が正しく動作しない可能性があります。", diff --git a/plugins/setting-assets/lang/pt.json b/plugins/setting-assets/lang/pt.json index ee572f5e4f2..8a035c42553 100644 --- a/plugins/setting-assets/lang/pt.json +++ b/plugins/setting-assets/lang/pt.json @@ -184,6 +184,7 @@ "ServiceIsUnavailable": "Serviço indisponível", "Integrated": "Integrado", "Connected": "Conectado", + "Disconnected": "Desconectado", "Available": "Disponível", "NotConnectedIntegration": "A conta {account} não está integrada com o espaço de trabalho", "IntegrationIsUnstable": "O serviço de integração está enfrentando problemas. Algumas funcionalidades podem não funcionar corretamente." diff --git a/plugins/setting-assets/lang/ru.json b/plugins/setting-assets/lang/ru.json index 9be6eba8a7c..63c1a5d8607 100644 --- a/plugins/setting-assets/lang/ru.json +++ b/plugins/setting-assets/lang/ru.json @@ -196,6 +196,7 @@ "ServiceIsUnavailable": "Сервис недоступен", "Integrated": "Интегрировано", "Connected": "Подключено", + "Disconnected": "Отключено", "Available": "Доступно", "NotConnectedIntegration": "Учетная запись {account} не интегрирована с рабочим пространством", "IntegrationIsUnstable": "Сервис интеграции испытывает проблемы. Некоторые функции могут работать некорректно." diff --git a/plugins/setting-assets/lang/tr.json b/plugins/setting-assets/lang/tr.json index 151eac57749..56b726bdb2c 100644 --- a/plugins/setting-assets/lang/tr.json +++ b/plugins/setting-assets/lang/tr.json @@ -193,6 +193,7 @@ "ServiceIsUnavailable": "Servis kullanılamıyor", "Integrated": "Entegre", "Connected": "Bağlandı", + "Disconnected": "Bağlantı Kesildi", "Available": "Kullanılabilir", "NotConnectedIntegration": "{account} hesabı çalışma alanıyla entegre değil", "IntegrationIsUnstable": "Entegrasyon servisi sorunlar yaşıyor. Bazı özellikler düzgün çalışmayabilir.", diff --git a/plugins/setting-assets/lang/zh.json b/plugins/setting-assets/lang/zh.json index e38267b81c9..a1af841d2f8 100644 --- a/plugins/setting-assets/lang/zh.json +++ b/plugins/setting-assets/lang/zh.json @@ -193,6 +193,7 @@ "ServiceIsUnavailable": "服务不可用", "Integrated": "已集成", "Connected": "已连接", + "Disconnected": "已断开", "Available": "可用", "NotConnectedIntegration": "帐户 {account} 未与工作区集成", "IntegrationIsUnstable": "集成服务出现问题。某些功能可能无法正常工作。", diff --git a/plugins/setting-resources/src/components/integrations/IntegrationCard.svelte b/plugins/setting-resources/src/components/integrations/IntegrationCard.svelte index d4e5c627573..a4eabae0337 100644 --- a/plugins/setting-resources/src/components/integrations/IntegrationCard.svelte +++ b/plugins/setting-resources/src/components/integrations/IntegrationCard.svelte @@ -13,10 +13,9 @@ // limitations under the License. --> - + From a9091e42929e06d5d830bb151a036297dd921587 Mon Sep 17 00:00:00 2001 From: Artem Savchenko Date: Tue, 7 Oct 2025 12:46:47 +0700 Subject: [PATCH 2/5] Fix integration enable Signed-off-by: Artem Savchenko --- packages/integration-client/src/client.ts | 15 ++------------- packages/integration-client/src/types.ts | 5 ----- .../integrations/IntegrationCard.svelte | 2 +- .../src/components/Connect.svelte | 11 +++++++++-- 4 files changed, 12 insertions(+), 21 deletions(-) diff --git a/packages/integration-client/src/client.ts b/packages/integration-client/src/client.ts index 4d4d6bdf288..8241e22c699 100644 --- a/packages/integration-client/src/client.ts +++ b/packages/integration-client/src/client.ts @@ -338,17 +338,6 @@ export class IntegrationClientImpl implements IntegrationClient { } } - async removeSecrets (integration: Integration): Promise { - const secrets = await this.client.listIntegrationsSecrets({ - socialId: integration.socialId, - kind: integration.kind, - workspaceUuid: integration.workspaceUuid - }) - for (const secret of secrets) { - await this.client.deleteIntegrationSecret(secret) - } - } - async setIntegrationEnabled (integrationKey: IntegrationKey, enabled: boolean): Promise { try { const integration = await this.client.getIntegration(integrationKey) @@ -363,14 +352,14 @@ export class IntegrationClientImpl implements IntegrationClient { await this.client.updateIntegration({ ...integration, - disabled: !enabled + data }) const eventData: IntegrationEventData = { integration: { ...integration, data }, timestamp: Date.now() } - this.emit(enabled ? 'integration:enabled' : 'integration:disabled', eventData) + this.emit('integration:updated', eventData) } catch (error) { const errorData: IntegrationErrorData = { operation: 'setIntegrationEnabled', diff --git a/packages/integration-client/src/types.ts b/packages/integration-client/src/types.ts index 45e02f17647..3afbc3e5a93 100644 --- a/packages/integration-client/src/types.ts +++ b/packages/integration-client/src/types.ts @@ -73,11 +73,6 @@ export interface IntegrationClient { */ setSecret: (data: IntegrationSecret) => Promise - /** - * Remove all integration secrets - */ - removeSecrets: (integration: Integration) => Promise - /** * Disable or enable an integration */ diff --git a/plugins/setting-resources/src/components/integrations/IntegrationCard.svelte b/plugins/setting-resources/src/components/integrations/IntegrationCard.svelte index a4eabae0337..8507c91f11c 100644 --- a/plugins/setting-resources/src/components/integrations/IntegrationCard.svelte +++ b/plugins/setting-resources/src/components/integrations/IntegrationCard.svelte @@ -58,7 +58,7 @@ } async function reconnect (res: any): Promise { - if (res?.successful === true && integration !== undefined) { + if (res?.connected === true && integration !== undefined) { await integrationClient?.setIntegrationEnabled(integration, true) } } diff --git a/plugins/telegram-resources/src/components/Connect.svelte b/plugins/telegram-resources/src/components/Connect.svelte index 8fd4b4f57f9..968fe191a8a 100644 --- a/plugins/telegram-resources/src/components/Connect.svelte +++ b/plugins/telegram-resources/src/components/Connect.svelte @@ -200,6 +200,8 @@ // If reconnecting, start authentication flow from the beginning if (reconnect) { await disconnectSession(phoneNumber) + // Add small delay to ensure session is fully disconnected + await new Promise((resolve) => setTimeout(resolve, 100)) integrationState = await commandWithLoading(phoneNumber, 'start') } else { integrationState = await getState(phoneNumber) @@ -228,7 +230,7 @@ async function disconnectSession (phoneNumber: string): Promise { try { await disconnect(phoneNumber) - } catch (error) { + } catch (error: any) { Analytics.handleError(error) } } @@ -240,7 +242,12 @@
-
+
{ + close() + }} + >
From b0c85ebeeceb865cf58ac631bc56bcf76227143f Mon Sep 17 00:00:00 2001 From: Artem Savchenko Date: Mon, 13 Oct 2025 11:02:10 +0700 Subject: [PATCH 3/5] Fix refresh Signed-off-by: Artem Savchenko --- .../integrations/IntegrationCard.svelte | 31 +++++++++++++++++-- .../integrations/IntegrationLabel.svelte | 4 +-- .../src/components/IntegrationState.svelte | 13 +++++++- 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/plugins/setting-resources/src/components/integrations/IntegrationCard.svelte b/plugins/setting-resources/src/components/integrations/IntegrationCard.svelte index 8507c91f11c..4a2269c6037 100644 --- a/plugins/setting-resources/src/components/integrations/IntegrationCard.svelte +++ b/plugins/setting-resources/src/components/integrations/IntegrationCard.svelte @@ -13,7 +13,7 @@ // limitations under the License. --> diff --git a/plugins/telegram-resources/src/components/IntegrationState.svelte b/plugins/telegram-resources/src/components/IntegrationState.svelte index 191f3171f2d..322cfff26f7 100644 --- a/plugins/telegram-resources/src/components/IntegrationState.svelte +++ b/plugins/telegram-resources/src/components/IntegrationState.svelte @@ -19,6 +19,7 @@ IntegrationClient, IntegrationUpdatedData, onIntegrationEvent, + isDisabled, isUnauthorizedError } from '@hcengineering/integration-client' import { BaseIntegrationState, IntegrationStateRow } from '@hcengineering/setting-resources' @@ -38,6 +39,9 @@ const unsubscribers: (() => void)[] = [] async function handleUnauthorized (): Promise { + if (isDisabled(integration)) { + return + } if (integrationClient === undefined) { integrationClient = await getIntegrationClient() } @@ -86,6 +90,7 @@ data.integration?.socialId === integration.socialId && data.integration?.workspaceUuid === integration.workspaceUuid ) { + integration = { ...integration, ...data.integration } const channelConfig: TelegramChannelData[] = data.newConfig?.channels if (channelConfig != null) { channels = channels.map((channel) => { @@ -98,7 +103,8 @@ } return channel }) - } else { + } + if (channelConfig == null || status?.code === ERROR.code) { void refresh() } } @@ -106,6 +112,9 @@ async function refresh (): Promise { try { + if (isDisabled(integration)) { + return + } if (integrationClient === undefined) { integrationClient = await getIntegrationClient() } @@ -116,8 +125,10 @@ ...channel, syncEnabled: channel.mode === 'sync' })) + status = OK } catch (err: any) { console.error('Error refresh channels:', err.message) + status = ERROR if (isUnauthorizedError(err as Error)) { await handleUnauthorized() } From 8ada1f82c2b023127c8c7d5fd311da4f19aa7311 Mon Sep 17 00:00:00 2001 From: Artem Savchenko Date: Mon, 13 Oct 2025 11:02:41 +0700 Subject: [PATCH 4/5] Update lock Signed-off-by: Artem Savchenko --- common/config/rush/pnpm-lock.yaml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index de4b44cecba..1e87033d4b2 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -37,9 +37,6 @@ importers: '@hcengineering/account-client': specifier: ^0.7.3 version: 0.7.3 - '@hcengineering/analytics': - specifier: ^0.7.3 - version: 0.7.3 '@hcengineering/analytics-service': specifier: ^0.7.3 version: 0.7.3(encoding@0.1.13) @@ -5929,7 +5926,7 @@ packages: version: 0.0.0 '@rush-temp/telegram-resources@file:projects/telegram-resources.tgz': - resolution: {integrity: sha512-A3Qw8AlxTQQvtbyhT/0DW9O7T2LgA9D14Be40U+STjCGcLXQaDoXdpMQ8IaU/kTWQ95S+ojNRpLNC7onsUp/DA==, tarball: file:projects/telegram-resources.tgz} + resolution: {integrity: sha512-AGJbEBk6KmlF51NLad6gDEEX9HU2l2HJ5uMj2LKsNLYjN/6z/KuPLmF9qxMDeY3ifS1NuaATcbqEsS1cxuke7w==, tarball: file:projects/telegram-resources.tgz} version: 0.0.0 '@rush-temp/telegram@file:projects/telegram.tgz': @@ -30900,6 +30897,7 @@ snapshots: '@rush-temp/telegram-resources@file:projects/telegram-resources.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@types/node@22.15.29)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.25.9)(postcss-load-config@4.0.2(postcss@8.5.3)(ts-node@10.9.2(@swc/core@1.13.5)(@types/node@22.15.29)(typescript@5.8.3)))(postcss@8.5.3)(prosemirror-inputrules@1.4.0)(prosemirror-model@1.24.1)(prosemirror-state@1.4.3)(prosemirror-view@1.37.2)(ts-node@10.9.2(@swc/core@1.13.5)(@types/node@22.15.29)(typescript@5.8.3))': dependencies: '@hcengineering/account-client': 0.7.3 + '@hcengineering/analytics': 0.7.3 '@hcengineering/core': 0.7.3 '@hcengineering/platform': 0.7.3 '@hcengineering/platform-rig': 0.7.10 From 99ff45c8fd9b55941cdfa68e20ad69550a257832 Mon Sep 17 00:00:00 2001 From: Artem Savchenko Date: Mon, 13 Oct 2025 12:29:58 +0700 Subject: [PATCH 5/5] Fix version mismatch Signed-off-by: Artem Savchenko --- plugins/telegram-resources/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/telegram-resources/package.json b/plugins/telegram-resources/package.json index 10e362f99bc..bc6bae0ddb5 100644 --- a/plugins/telegram-resources/package.json +++ b/plugins/telegram-resources/package.json @@ -39,7 +39,7 @@ }, "dependencies": { "@hcengineering/account-client": "^0.7.3", - "@hcengineering/analytics": "^0.7.0", + "@hcengineering/analytics": "^0.7.3", "@hcengineering/attachment": "^0.7.0", "@hcengineering/attachment-resources": "^0.7.0", "@hcengineering/card": "^0.7.0",