diff --git a/packages/backend/src/apps/telegram-bot/actions/index.ts b/packages/backend/src/apps/telegram-bot/actions/index.ts
new file mode 100644
index 00000000..37aeb338
--- /dev/null
+++ b/packages/backend/src/apps/telegram-bot/actions/index.ts
@@ -0,0 +1,3 @@
+import sendMessage from './send-message';
+
+export default [sendMessage];
diff --git a/packages/backend/src/apps/telegram-bot/actions/send-message/index.ts b/packages/backend/src/apps/telegram-bot/actions/send-message/index.ts
new file mode 100644
index 00000000..5d884cb7
--- /dev/null
+++ b/packages/backend/src/apps/telegram-bot/actions/send-message/index.ts
@@ -0,0 +1,59 @@
+import qs from 'qs';
+import defineAction from '../../../../helpers/define-action';
+
+export default defineAction({
+ name: 'Send message',
+ key: 'sendMessage',
+ description: 'Sends a message to a chat you specify.',
+ arguments: [
+ {
+ label: 'Chat ID',
+ key: 'chatId',
+ type: 'string' as const,
+ required: true,
+ description: 'Unique identifier for the target chat or username of the target channel (in the format @channelusername).',
+ variables: true,
+ },
+ {
+ label: 'Message text',
+ key: 'text',
+ type: 'string' as const,
+ required: true,
+ description: 'Text of the message to be sent, 1-4096 characters.',
+ variables: true,
+ },
+ {
+ label: 'Disable notification?',
+ key: 'disableNotification',
+ type: 'dropdown' as const,
+ required: false,
+ value: false,
+ description: 'Sends the message silently. Users will receive a notification with no sound.',
+ variables: false,
+ options: [
+ {
+ label: 'Yes',
+ value: true,
+ },
+ {
+ label: 'No',
+ value: false,
+ },
+ ],
+ },
+ ],
+
+ async run($) {
+ const payload = {
+ chat_id: $.step.parameters.chatId,
+ text: $.step.parameters.text,
+ disable_notification: $.step.parameters.disableNotification,
+ };
+
+ const response = await $.http.post('/sendMessage', payload);
+
+ $.setActionItem({
+ raw: response.data,
+ });
+ },
+});
diff --git a/packages/backend/src/apps/telegram-bot/assets/favicon.svg b/packages/backend/src/apps/telegram-bot/assets/favicon.svg
new file mode 100644
index 00000000..8f16fb17
--- /dev/null
+++ b/packages/backend/src/apps/telegram-bot/assets/favicon.svg
@@ -0,0 +1,14 @@
+
+
\ No newline at end of file
diff --git a/packages/backend/src/apps/telegram-bot/auth/index.ts b/packages/backend/src/apps/telegram-bot/auth/index.ts
new file mode 100644
index 00000000..01e68c2f
--- /dev/null
+++ b/packages/backend/src/apps/telegram-bot/auth/index.ts
@@ -0,0 +1,21 @@
+import verifyCredentials from './verify-credentials';
+import isStillVerified from './is-still-verified';
+
+export default {
+ fields: [
+ {
+ key: 'token',
+ label: 'Bot token',
+ type: 'string' as const,
+ required: true,
+ readOnly: false,
+ value: null,
+ placeholder: null,
+ description: 'Bot token which should be retrieved from @botfather.',
+ clickToCopy: false,
+ },
+ ],
+
+ verifyCredentials,
+ isStillVerified,
+};
diff --git a/packages/backend/src/apps/telegram-bot/auth/is-still-verified.ts b/packages/backend/src/apps/telegram-bot/auth/is-still-verified.ts
new file mode 100644
index 00000000..66bb963e
--- /dev/null
+++ b/packages/backend/src/apps/telegram-bot/auth/is-still-verified.ts
@@ -0,0 +1,9 @@
+import { IGlobalVariable } from '@automatisch/types';
+import verifyCredentials from './verify-credentials';
+
+const isStillVerified = async ($: IGlobalVariable) => {
+ await verifyCredentials($);
+ return true;
+};
+
+export default isStillVerified;
diff --git a/packages/backend/src/apps/telegram-bot/auth/verify-credentials.ts b/packages/backend/src/apps/telegram-bot/auth/verify-credentials.ts
new file mode 100644
index 00000000..17bbfa94
--- /dev/null
+++ b/packages/backend/src/apps/telegram-bot/auth/verify-credentials.ts
@@ -0,0 +1,12 @@
+import { IGlobalVariable } from '@automatisch/types';
+
+const verifyCredentials = async ($: IGlobalVariable) => {
+ const { data } = await $.http.get('/getMe');
+ const { result: me } = data;
+
+ await $.auth.set({
+ screenName: me.first_name,
+ });
+};
+
+export default verifyCredentials;
diff --git a/packages/backend/src/apps/telegram-bot/common/add-auth-header.ts b/packages/backend/src/apps/telegram-bot/common/add-auth-header.ts
new file mode 100644
index 00000000..aa17b14f
--- /dev/null
+++ b/packages/backend/src/apps/telegram-bot/common/add-auth-header.ts
@@ -0,0 +1,13 @@
+import { TBeforeRequest } from '@automatisch/types';
+import { URL } from 'node:url';
+
+const addAuthHeader: TBeforeRequest = ($, requestConfig) => {
+ if ($.auth.data?.token) {
+ const token = $.auth.data.token as string;
+ requestConfig.baseURL = (new URL(`/bot${token}`, requestConfig.baseURL)).toString();
+ }
+
+ return requestConfig;
+};
+
+export default addAuthHeader;
diff --git a/packages/backend/src/apps/telegram-bot/index.d.ts b/packages/backend/src/apps/telegram-bot/index.d.ts
new file mode 100644
index 00000000..e69de29b
diff --git a/packages/backend/src/apps/telegram-bot/index.ts b/packages/backend/src/apps/telegram-bot/index.ts
new file mode 100644
index 00000000..364e01d0
--- /dev/null
+++ b/packages/backend/src/apps/telegram-bot/index.ts
@@ -0,0 +1,18 @@
+import defineApp from '../../helpers/define-app';
+import addAuthHeader from './common/add-auth-header';
+import auth from './auth';
+import actions from './actions';
+
+export default defineApp({
+ name: 'Telegram',
+ key: 'telegram-bot',
+ iconUrl: '{BASE_URL}/apps/telegram-bot/assets/favicon.svg',
+ authDocUrl: 'https://automatisch.io/docs/apps/telegram-bot/connection',
+ supportsConnections: true,
+ baseUrl: 'https://telegram.org',
+ apiBaseUrl: 'https://api.telegram.org',
+ primaryColor: '2AABEE',
+ beforeRequest: [addAuthHeader],
+ auth,
+ actions,
+});
diff --git a/packages/docs/pages/.vitepress/config.js b/packages/docs/pages/.vitepress/config.js
index 1841d88a..912ef91b 100644
--- a/packages/docs/pages/.vitepress/config.js
+++ b/packages/docs/pages/.vitepress/config.js
@@ -123,6 +123,14 @@ export default defineConfig({
{ text: 'Connection', link: '/apps/stripe/connection' },
],
},
+ {
+ text: 'Telegram',
+ collapsible: true,
+ items: [
+ { text: 'Actions', link: '/apps/telegram-bot/actions' },
+ { text: 'Connection', link: '/apps/telegram-bot/connection' },
+ ],
+ },
{
text: 'Twilio',
collapsible: true,
diff --git a/packages/docs/pages/apps/telegram-bot/actions.md b/packages/docs/pages/apps/telegram-bot/actions.md
new file mode 100644
index 00000000..261d241d
--- /dev/null
+++ b/packages/docs/pages/apps/telegram-bot/actions.md
@@ -0,0 +1,12 @@
+---
+favicon: /favicons/telegram-bot.svg
+items:
+ - name: Send a message
+ desc: Sends a message to a chat you specify.
+---
+
+
+
+
diff --git a/packages/docs/pages/apps/telegram-bot/connection.md b/packages/docs/pages/apps/telegram-bot/connection.md
new file mode 100644
index 00000000..4a015cc9
--- /dev/null
+++ b/packages/docs/pages/apps/telegram-bot/connection.md
@@ -0,0 +1,14 @@
+# Telegram
+
+:::info
+This page explains the steps you need to follow to set up the Telegram
+connection in Automatisch. If any of the steps are outdated, please let us know!
+:::
+
+1. Start a chat with [Botfather](https://telegram.me/BotFather).
+1. Enter `/newbot`.
+1. Enter a name for your bot.
+1. Enter a username for your bot.
+1. Copy the **token** value from the answer to the **Bot token** field on Automatisch.
+1. Click **Submit** button on Automatisch.
+1. Congrats! Start using your new Telegram connection within the flows.
diff --git a/packages/docs/pages/guide/available-apps.md b/packages/docs/pages/guide/available-apps.md
index 5697771f..545a1743 100644
--- a/packages/docs/pages/guide/available-apps.md
+++ b/packages/docs/pages/guide/available-apps.md
@@ -16,5 +16,7 @@ Following integrations are currently supported by Automatisch.
- [Slack](/apps/slack/actions)
- [SMTP](/apps/smtp/actions)
- [Stripe](/apps/stripe/triggers)
+- [Telegram](/apps/telegram-bot/triggers)
- [Twilio](/apps/twilio/triggers)
- [Twitter](/apps/twitter/triggers)
+- [Typeform](/apps/typeform/triggers)
diff --git a/packages/docs/pages/public/favicons/telegram-bot.svg b/packages/docs/pages/public/favicons/telegram-bot.svg
new file mode 100644
index 00000000..8f16fb17
--- /dev/null
+++ b/packages/docs/pages/public/favicons/telegram-bot.svg
@@ -0,0 +1,14 @@
+
+
\ No newline at end of file
diff --git a/packages/web/src/components/AppRow/index.tsx b/packages/web/src/components/AppRow/index.tsx
index f059c6cc..0ac728d1 100644
--- a/packages/web/src/components/AppRow/index.tsx
+++ b/packages/web/src/components/AppRow/index.tsx
@@ -25,11 +25,11 @@ const countTranslation = (value: React.ReactNode) => (
function AppRow(props: AppRowProps): React.ReactElement {
const formatMessage = useFormatMessage();
- const { name, primaryColor, iconUrl, connectionCount, flowCount } =
+ const { name, key, primaryColor, iconUrl, connectionCount, flowCount } =
props.application;
return (
-
+