Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion desktop/src/ui/platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ export async function configurePlatform (): Promise<void> {
setMetadata(presentation.metadata.FrontVersion, config.VERSION)
}
setMetadata(telegram.metadata.TelegramURL, config.TELEGRAM_URL ?? 'http://localhost:8086')
setMetadata(telegram.metadata.BotUrl, config.TELEGRAM_BOT_URL)
setMetadata(telegram.metadata.BotUrl, config.TELEGRAM_BOT_URL ?? 'http://localhost:4020')
setMetadata(gmail.metadata.GmailURL, config.GMAIL_URL ?? 'http://localhost:8087')
setMetadata(calendar.metadata.CalendarServiceURL, config.CALENDAR_URL ?? 'http://localhost:8095')
setMetadata(notification.metadata.PushPublicKey, config.PUSH_PUBLIC_KEY)
Expand Down
2 changes: 2 additions & 0 deletions models/telegram/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
},
"dependencies": {
"@hcengineering/activity": "^0.6.0",
"@hcengineering/chunter": "^0.6.20",
"@hcengineering/love": "^0.6.0",
"@hcengineering/model": "^0.6.11",
"@hcengineering/core": "^0.6.32",
"@hcengineering/platform": "^0.6.11",
Expand Down
14 changes: 13 additions & 1 deletion models/telegram/src/notification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import { type Builder } from '@hcengineering/model'
import notification from '@hcengineering/model-notification'
import core from '@hcengineering/model-core'
import contact from '@hcengineering/model-contact'
import chunter from '@hcengineering/chunter'
import love from '@hcengineering/love'

import telegram from './plugin'

Expand Down Expand Up @@ -66,7 +68,17 @@ export function defineNotifications (builder: Builder): void {

builder.createDoc(notification.class.NotificationProviderDefaults, core.space.Model, {
provider: notification.providers.InboxNotificationProvider,
ignoredTypes: [notification.ids.CollaboratoAddNotification],
ignoredTypes: [],
enabledTypes: [telegram.ids.NewMessageNotification]
})

builder.createDoc(notification.class.NotificationProviderDefaults, core.space.Model, {
provider: telegram.providers.TelegramNotificationProvider,
ignoredTypes: [
notification.ids.CollaboratoAddNotification,
love.ids.InviteNotification,
love.ids.KnockNotification
],
enabledTypes: [chunter.ids.DMNotification, chunter.ids.ThreadNotification]
})
}
17 changes: 10 additions & 7 deletions packages/ui/src/components/Modal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
export let allowFullsize: boolean = false
export let hideFooter: boolean = false
export let adaptive: 'default' | 'freezeActions' | 'doubleRow' | 'disabled' = 'disabled'
export let showCancelButton: boolean = true

const dispatch = createEventDispatcher()

Expand Down Expand Up @@ -97,13 +98,15 @@
on:click={okAction}
disabled={!canSave}
/>
<ButtonBase
type={'type-button'}
kind={'secondary'}
size={type === 'type-aside' ? 'large' : 'medium'}
label={ui.string.Cancel}
on:click={onCancel}
/>
{#if showCancelButton}
<ButtonBase
type={'type-button'}
kind={'secondary'}
size={type === 'type-aside' ? 'large' : 'medium'}
label={ui.string.Cancel}
on:click={onCancel}
/>
{/if}
</div>
{/if}
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
NotificationGroup,
NotificationType,
NotificationTypeSetting,
NotificationProviderDefaults
NotificationProviderDefaults,
NotificationProviderSetting
} from '@hcengineering/notification'
import { getResource, IntlString } from '@hcengineering/platform'
import { getClient } from '@hcengineering/presentation'
Expand Down Expand Up @@ -132,12 +133,13 @@

async function getFilteredProviders (
providers: NotificationProvider[],
types: BaseNotificationType[]
types: BaseNotificationType[],
providersSettings: NotificationProviderSetting[]
): Promise<NotificationProvider[]> {
const result: NotificationProvider[] = []

for (const provider of providers) {
const providerSetting = $providersSettings.find((p) => p.attachedTo === provider._id)
const providerSetting = providersSettings.find((p) => p.attachedTo === provider._id)

if (providerSetting !== undefined && !providerSetting.enabled) continue
if (providerSetting === undefined && !provider.defaultEnabled) continue
Expand All @@ -164,7 +166,7 @@

let filteredProviders: NotificationProvider[] = []

$: void getFilteredProviders(providers, types).then((result) => {
$: void getFilteredProviders(providers, types, $providersSettings).then((result) => {
filteredProviders = result
})

Expand Down
209 changes: 209 additions & 0 deletions plugins/telegram-resources/src/components/ConfigureBotPopup.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
<!--
// Copyright © 2024 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
-->

<script lang="ts">
import { CodeForm, Icon, IconCheckmark, Label, Loading, Modal, ModernButton } from '@hcengineering/ui'
import presentation from '@hcengineering/presentation'
import { getEmbeddedLabel, getMetadata, IntlString } from '@hcengineering/platform'
import { concatLink, getCurrentAccount } from '@hcengineering/core'
import { onMount } from 'svelte'

import telegram from '../plugin'
import TelegramColor from './icons/TelegramColor.svelte'

let isTestingConnection = false
let isConnectionEstablished = false
let connectionError: Error | undefined

let info: { name: string, username: string, photoUrl: string } | undefined = undefined
let isLoading = false

const url = getMetadata(telegram.metadata.BotUrl) ?? ''

onMount(() => {
void loadBotInfo()
})

async function loadBotInfo (): Promise<void> {
if (info !== undefined || isLoading) return
isLoading = true
try {
const link = concatLink(url, '/info')
const res = await fetch(link, {
method: 'GET',
headers: {
Authorization: 'Bearer ' + getMetadata(presentation.metadata.Token),
'Content-Type': 'application/json'
}
})
info = await res.json()
} catch (e) {}
isLoading = false
}

async function handleTestConnection (): Promise<void> {
isTestingConnection = true
isConnectionEstablished = false
connectionError = undefined

try {
const link = concatLink(url, '/test')
const res = await fetch(link, {
method: 'POST',
headers: {
Authorization: 'Bearer ' + getMetadata(presentation.metadata.Token),
'Content-Type': 'application/json'
}
})
isConnectionEstablished = res.ok
if (!res.ok) {
connectionError = new Error('Connection failed')
}
} catch (e) {
connectionError = e as Error
}
isTestingConnection = false
}

const codeFields = [
{ id: 'code-1', name: 'code-1', optional: false },
{ id: 'code-2', name: 'code-2', optional: false },
{ id: 'code-3', name: 'code-3', optional: false },
{ id: 'code-4', name: 'code-4', optional: false },
{ id: 'code-5', name: 'code-5', optional: false },
{ id: 'code-6', name: 'code-6', optional: false }
]

let isCodeValid = false
let codeError: IntlString | undefined

async function handleCode (event: CustomEvent<string>): Promise<void> {
isCodeValid = false
codeError = undefined

try {
const link = concatLink(url, '/auth')
const res = await fetch(link, {
method: 'POST',
headers: {
Authorization: 'Bearer ' + getMetadata(presentation.metadata.Token),
'Content-Type': 'application/json'
},
body: JSON.stringify({ code: event.detail, account: getCurrentAccount()._id })
})
isCodeValid = res.ok
if (!res.ok) {
codeError = res.status === 409 ? telegram.string.AccountAlreadyConnected : telegram.string.InvalidCode
}
} catch (e) {
codeError = telegram.string.SomethingWentWrong
}
}
</script>

<Modal
label={getEmbeddedLabel('Connect Telegram Bot')}
type="type-popup"
okLabel={presentation.string.Ok}
okAction={() => {}}
showCancelButton={false}
canSave
on:close
>
<div class="hulyModal-content__titleGroup" style="padding: 0">
{#if isLoading}
<div class="flex-row-top mt-2 h-32">
<Loading size="medium" />
</div>
{:else if info}
<div class="flex-col mt-2">
<div class="title overflow-label mb-4">
<div class="flex-row-center flex-gap-2">
{#if info.photoUrl !== ''}
<img class="photo" src={info.photoUrl} alt="" />
{:else}
<Icon icon={TelegramColor} size="x-large" />
{/if}
{info.name} (@{info.username})
<ModernButton
label={telegram.string.TestConnection}
size="small"
loading={isTestingConnection}
on:click={handleTestConnection}
/>
{#if isConnectionEstablished}
<span class="flex-row-center flex-gap-1 label-connected">
<Label label={telegram.string.Connected} />
<Icon icon={IconCheckmark} size="medium" />
</span>
{/if}
</div>
{#if connectionError}
<span class="label-error mt-2">
<Label label={telegram.string.ConnectBotError} />
</span>
{/if}
</div>
<div class="flex-row-center flex-gap-1 mt-2">
<Label label={telegram.string.ConnectBotInfoStart} />
<a target="_blank" href={`https://t.me/${info.username}`}>{info.username}</a>
<Label label={telegram.string.ConnectBotInfoEnd} />
</div>

<CodeForm fields={codeFields} size="small" on:submit={handleCode} />
{#if codeError}
<span class="label-error mt-2">
<Label label={codeError} />
</span>
{:else if isCodeValid}
<span class="flex-row-center flex-gap-1 mt-2 label-connected">
<Label label={telegram.string.Connected} />
<Icon icon={IconCheckmark} size="medium" />
</span>
{/if}
</div>
{:else}
<span class="label-error mt-2">
<Label label={getEmbeddedLabel('Unable connect to service. Please try again.')} />
</span>
{/if}
</div>
</Modal>

<style lang="scss">
.label-connected {
color: var(--global-online-color);
}

.label-error {
color: var(--global-error-TextColor);
}

a {
color: var(--theme-link-color);

&:hover,
&:active,
&:visited {
color: var(--theme-link-color);
}
}

.photo {
border-radius: 50%;
width: 2.5rem;
height: 2.5rem;
}
</style>
Loading