This is an automated email from the ASF dual-hosted git repository.

zhongjiajie pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/dolphinscheduler.git


The following commit(s) were added to refs/heads/dev by this push:
     new 84b004d  [Feature-8245][Alert] Add Alert Plugin Telegram (#8246)
84b004d is described below

commit 84b004d9608637abcf67053f714941ee6b62cdf1
Author: pinkhello <[email protected]>
AuthorDate: Mon Feb 7 09:51:18 2022 +0800

    [Feature-8245][Alert] Add Alert Plugin Telegram (#8246)
---
 .github/actions/reviewdog-setup                    |   2 +-
 .../alert/slack/SlackAlertChannelFactory.java      |   2 +-
 .../plugin/alert/slack/SlackParamsConstants.java   |   2 +-
 .../plugin/alert/slack/SlackSender.java            |   2 +-
 .../plugin/alert/slack/SlackSenderTest.java        |   2 +-
 .../{ => dolphinscheduler-alert-telegram}/pom.xml  |  28 +--
 .../alert/telegram/TelegramAlertChannel.java}      |  32 ++-
 .../telegram/TelegramAlertChannelFactory.java      | 123 ++++++++++
 .../alert/telegram/TelegramAlertConstants.java}    |  29 ++-
 .../alert/telegram/TelegramParamsConstants.java    |  54 +++++
 .../plugin/alert/telegram/TelegramSender.java      | 251 +++++++++++++++++++++
 .../telegram/TelegramAlertChannelFactoryTest.java} |  36 +--
 .../plugin/alert/telegram/TelegramSenderTest.java  | 111 +++++++++
 .../dolphinscheduler-alert-plugins/pom.xml         |   1 +
 .../dolphinscheduler-alert-server/pom.xml          |   5 +
 .../src/locales/modules/en_US.ts                   |   5 +-
 .../src/locales/modules/zh_CN.ts                   |   5 +-
 pom.xml                                            |   5 +
 18 files changed, 629 insertions(+), 66 deletions(-)

diff --git a/.github/actions/reviewdog-setup b/.github/actions/reviewdog-setup
index 2fc905b..c2fa3e5 160000
--- a/.github/actions/reviewdog-setup
+++ b/.github/actions/reviewdog-setup
@@ -1 +1 @@
-Subproject commit 2fc905b1875f2e6b91c4201a4dc6eaa21b86547e
+Subproject commit c2fa3e5a37b75a5819e2c8127caec1c2a0d088e8
diff --git 
a/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-slack/src/main/java/org/apache/dolphinscheduler/plugin/alert/slack/SlackAlertChannelFactory.java
 
b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-slack/src/main/java/org/apache/dolphinscheduler/plugin/alert/slack/SlackAlertChannelFactory.java
index 9819ed4..f86e329 100644
--- 
a/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-slack/src/main/java/org/apache/dolphinscheduler/plugin/alert/slack/SlackAlertChannelFactory.java
+++ 
b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-slack/src/main/java/org/apache/dolphinscheduler/plugin/alert/slack/SlackAlertChannelFactory.java
@@ -39,7 +39,7 @@ public final class SlackAlertChannelFactory implements 
AlertChannelFactory {
     public List<PluginParams> params() {
         List<PluginParams> paramsList = new LinkedList<>();
 
-        InputParam webHookParam = 
InputParam.newBuilder(SlackParamsConstants.SLACK_WEN_HOOK_URL_NAME, 
SlackParamsConstants.SLACK_WEB_HOOK_URL)
+        InputParam webHookParam = 
InputParam.newBuilder(SlackParamsConstants.SLACK_WEB_HOOK_URL_NAME, 
SlackParamsConstants.SLACK_WEB_HOOK_URL)
                                             .addValidate(Validate.newBuilder()
                                                                  
.setRequired(true)
                                                                  .build())
diff --git 
a/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-slack/src/main/java/org/apache/dolphinscheduler/plugin/alert/slack/SlackParamsConstants.java
 
b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-slack/src/main/java/org/apache/dolphinscheduler/plugin/alert/slack/SlackParamsConstants.java
index 928eba6..a3c9f19 100644
--- 
a/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-slack/src/main/java/org/apache/dolphinscheduler/plugin/alert/slack/SlackParamsConstants.java
+++ 
b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-slack/src/main/java/org/apache/dolphinscheduler/plugin/alert/slack/SlackParamsConstants.java
@@ -19,7 +19,7 @@ package org.apache.dolphinscheduler.plugin.alert.slack;
 
 public final class SlackParamsConstants {
     public static final String SLACK_WEB_HOOK_URL = "$t('webhook')";
-    public static final String SLACK_WEN_HOOK_URL_NAME = "webHook";
+    public static final String SLACK_WEB_HOOK_URL_NAME = "webHook";
     public static final String SLACK_BOT = "$t('Username')";
     public static final String SLACK_BOT_NAME = "username";
     public static final String TEXT = "text";
diff --git 
a/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-slack/src/main/java/org/apache/dolphinscheduler/plugin/alert/slack/SlackSender.java
 
b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-slack/src/main/java/org/apache/dolphinscheduler/plugin/alert/slack/SlackSender.java
index 95eeca6..1017c83 100644
--- 
a/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-slack/src/main/java/org/apache/dolphinscheduler/plugin/alert/slack/SlackSender.java
+++ 
b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-slack/src/main/java/org/apache/dolphinscheduler/plugin/alert/slack/SlackSender.java
@@ -50,7 +50,7 @@ public final class SlackSender {
     private final String botName;
 
     public SlackSender(Map<String, String> slackAlertParam) {
-        webHookUrl = 
slackAlertParam.get(SlackParamsConstants.SLACK_WEN_HOOK_URL_NAME);
+        webHookUrl = 
slackAlertParam.get(SlackParamsConstants.SLACK_WEB_HOOK_URL_NAME);
         botName = slackAlertParam.get(SlackParamsConstants.SLACK_BOT_NAME);
         Preconditions.checkArgument(!Objects.isNull(webHookUrl), 
"SlackWebHookURL can not be null");
         
Preconditions.checkArgument(webHookUrl.startsWith("https://hooks.slack.com/services/";),
 "SlackWebHookURL invalidate");
diff --git 
a/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-slack/src/test/java/org/apache/dolphinscheduler/plugin/alert/slack/SlackSenderTest.java
 
b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-slack/src/test/java/org/apache/dolphinscheduler/plugin/alert/slack/SlackSenderTest.java
index c675aca..7e26130 100644
--- 
a/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-slack/src/test/java/org/apache/dolphinscheduler/plugin/alert/slack/SlackSenderTest.java
+++ 
b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-slack/src/test/java/org/apache/dolphinscheduler/plugin/alert/slack/SlackSenderTest.java
@@ -28,7 +28,7 @@ public class SlackSenderTest {
     @Test
     public void testSendMessage() {
         Map<String, String> alertparam = new HashMap<>();
-        alertparam.put(SlackParamsConstants.SLACK_WEN_HOOK_URL_NAME,
+        alertparam.put(SlackParamsConstants.SLACK_WEB_HOOK_URL_NAME,
             "https://hooks.slack.com/services/123456";);
         alertparam.put(SlackParamsConstants.SLACK_BOT_NAME, 
"Dolphinscheduler");
 
diff --git a/dolphinscheduler-alert/dolphinscheduler-alert-plugins/pom.xml 
b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-telegram/pom.xml
similarity index 62%
copy from dolphinscheduler-alert/dolphinscheduler-alert-plugins/pom.xml
copy to 
dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-telegram/pom.xml
index c3b9be8..b5685f6 100644
--- a/dolphinscheduler-alert/dolphinscheduler-alert-plugins/pom.xml
+++ 
b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-telegram/pom.xml
@@ -19,31 +19,23 @@
          xmlns="http://maven.apache.org/POM/4.0.0";
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
     <parent>
-        <artifactId>dolphinscheduler-alert</artifactId>
+        <artifactId>dolphinscheduler-alert-plugins</artifactId>
         <groupId>org.apache.dolphinscheduler</groupId>
         <version>2.0.4-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
-    <artifactId>dolphinscheduler-alert-plugins</artifactId>
-    <packaging>pom</packaging>
-
-    <modules>
-        <module>dolphinscheduler-alert-email</module>
-        <module>dolphinscheduler-alert-wechat</module>
-        <module>dolphinscheduler-alert-dingtalk</module>
-        <module>dolphinscheduler-alert-script</module>
-        <module>dolphinscheduler-alert-http</module>
-        <module>dolphinscheduler-alert-feishu</module>
-        <module>dolphinscheduler-alert-slack</module>
-        <module>dolphinscheduler-alert-pagerduty</module>
-        <module>dolphinscheduler-alert-webexteams</module>
-    </modules>
+    <artifactId>dolphinscheduler-alert-telegram</artifactId>
+    <packaging>jar</packaging>
 
     <dependencies>
         <dependency>
-            <groupId>org.apache.dolphinscheduler</groupId>
-            <artifactId>dolphinscheduler-alert-api</artifactId>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
         </dependency>
-    </dependencies>
 
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+    </dependencies>
 </project>
diff --git 
a/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-slack/src/test/java/org/apache/dolphinscheduler/plugin/alert/slack/SlackSenderTest.java
 
b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-telegram/src/main/java/org/apache/dolphinscheduler/plugin/alert/telegram/TelegramAlertChannel.java
similarity index 52%
copy from 
dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-slack/src/test/java/org/apache/dolphinscheduler/plugin/alert/slack/SlackSenderTest.java
copy to 
dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-telegram/src/main/java/org/apache/dolphinscheduler/plugin/alert/telegram/TelegramAlertChannel.java
index c675aca..26db453 100644
--- 
a/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-slack/src/test/java/org/apache/dolphinscheduler/plugin/alert/slack/SlackSenderTest.java
+++ 
b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-telegram/src/main/java/org/apache/dolphinscheduler/plugin/alert/telegram/TelegramAlertChannel.java
@@ -15,25 +15,23 @@
  * limitations under the License.
  */
 
-package org.apache.dolphinscheduler.plugin.alert.slack;
+package org.apache.dolphinscheduler.plugin.alert.telegram;
 
-import java.util.HashMap;
-import java.util.Map;
-
-import org.junit.Assert;
-import org.junit.Test;
+import org.apache.dolphinscheduler.alert.api.AlertChannel;
+import org.apache.dolphinscheduler.alert.api.AlertData;
+import org.apache.dolphinscheduler.alert.api.AlertInfo;
+import org.apache.dolphinscheduler.alert.api.AlertResult;
 
-public class SlackSenderTest {
-
-    @Test
-    public void testSendMessage() {
-        Map<String, String> alertparam = new HashMap<>();
-        alertparam.put(SlackParamsConstants.SLACK_WEN_HOOK_URL_NAME,
-            "https://hooks.slack.com/services/123456";);
-        alertparam.put(SlackParamsConstants.SLACK_BOT_NAME, 
"Dolphinscheduler");
+import java.util.Map;
 
-        SlackSender slackSender = new SlackSender(alertparam);
-        String response = slackSender.sendMessage("test title", "test 
content");
-        Assert.assertNotEquals("ok", response);
+public final class TelegramAlertChannel implements AlertChannel {
+    @Override
+    public AlertResult process(AlertInfo info) {
+        Map<String, String> alertParams = info.getAlertParams();
+        if (alertParams == null || alertParams.isEmpty()) {
+            return new AlertResult("false", "Telegram alert params is empty");
+        }
+        AlertData data = info.getAlertData();
+        return new TelegramSender(alertParams).sendMessage(data);
     }
 }
diff --git 
a/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-telegram/src/main/java/org/apache/dolphinscheduler/plugin/alert/telegram/TelegramAlertChannelFactory.java
 
b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-telegram/src/main/java/org/apache/dolphinscheduler/plugin/alert/telegram/TelegramAlertChannelFactory.java
new file mode 100644
index 0000000..f282cb5
--- /dev/null
+++ 
b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-telegram/src/main/java/org/apache/dolphinscheduler/plugin/alert/telegram/TelegramAlertChannelFactory.java
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache 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
+ *
+ *    http://www.apache.org/licenses/LICENSE-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.
+ */
+
+package org.apache.dolphinscheduler.plugin.alert.telegram;
+
+import com.google.auto.service.AutoService;
+import org.apache.dolphinscheduler.alert.api.AlertChannel;
+import org.apache.dolphinscheduler.alert.api.AlertChannelFactory;
+import org.apache.dolphinscheduler.spi.params.PasswordParam;
+import org.apache.dolphinscheduler.spi.params.base.ParamsOptions;
+import org.apache.dolphinscheduler.spi.params.base.PluginParams;
+import org.apache.dolphinscheduler.spi.params.base.Validate;
+import org.apache.dolphinscheduler.spi.params.input.InputParam;
+import org.apache.dolphinscheduler.spi.params.radio.RadioParam;
+import org.apache.dolphinscheduler.spi.params.select.SelectParam;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static org.apache.dolphinscheduler.spi.utils.Constants.*;
+
+@AutoService(AlertChannelFactory.class)
+public final class TelegramAlertChannelFactory implements AlertChannelFactory {
+
+    @Override
+    public String name() {
+        return "Telegram";
+    }
+
+    @Override
+    public AlertChannel create() {
+        return new TelegramAlertChannel();
+    }
+
+    @Override
+    public List<PluginParams> params() {
+
+
+        InputParam webHookParam = 
InputParam.newBuilder(TelegramParamsConstants.NAME_TELEGRAM_WEB_HOOK, 
TelegramParamsConstants.TELEGRAM_WEB_HOOK)
+                .addValidate(Validate.newBuilder()
+                        .setRequired(true)
+                        .build())
+                .setPlaceholder("telegram web hook")
+                .build();
+
+        InputParam botTokenParam = 
InputParam.newBuilder(TelegramParamsConstants.NAME_TELEGRAM_BOT_TOKEN, 
TelegramParamsConstants.TELEGRAM_BOT_TOKEN)
+                .addValidate(Validate.newBuilder()
+                        .setRequired(true)
+                        .build())
+                .setPlaceholder("telegram bot token")
+                .build();
+
+        InputParam chatIdParam = 
InputParam.newBuilder(TelegramParamsConstants.NAME_TELEGRAM_CHAT_ID, 
TelegramParamsConstants.TELEGRAM_CHAT_ID)
+                .addValidate(Validate.newBuilder()
+                        .setRequired(true)
+                        .build())
+                .setPlaceholder("telegram channel chat id")
+                .build();
+
+        SelectParam parseMode = 
SelectParam.newBuilder(TelegramParamsConstants.NAME_TELEGRAM_PARSE_MODE, 
TelegramParamsConstants.TELEGRAM_PARSE_MODE)
+                .addOptions(new 
ParamsOptions(TelegramAlertConstants.PARSE_MODE_TXT, 
TelegramAlertConstants.PARSE_MODE_TXT, false))
+                .addOptions(new 
ParamsOptions(TelegramAlertConstants.PARSE_MODE_MARKDOWN, 
TelegramAlertConstants.PARSE_MODE_MARKDOWN, false))
+                .addOptions(new 
ParamsOptions(TelegramAlertConstants.PARSE_MODE_MARKDOWN_V2, 
TelegramAlertConstants.PARSE_MODE_MARKDOWN_V2, false))
+                .addOptions(new 
ParamsOptions(TelegramAlertConstants.PARSE_MODE_HTML, 
TelegramAlertConstants.PARSE_MODE_HTML, false))
+                .setValue(TelegramAlertConstants.PARSE_MODE_TXT)
+                .addValidate(Validate.newBuilder()
+                        .setRequired(true)
+                        .build())
+                .build();
+
+        RadioParam isEnableProxy = 
RadioParam.newBuilder(TelegramParamsConstants.NAME_TELEGRAM_PROXY_ENABLE, 
TelegramParamsConstants.TELEGRAM_PROXY_ENABLE)
+                .addParamsOptions(new ParamsOptions(STRING_YES, STRING_TRUE, 
false))
+                .addParamsOptions(new ParamsOptions(STRING_NO, STRING_FALSE, 
false))
+                .setValue(STRING_FALSE)
+                .addValidate(Validate.newBuilder()
+                        .setRequired(false)
+                        .build())
+                .build();
+
+        InputParam proxyParam = 
InputParam.newBuilder(TelegramParamsConstants.NAME_TELEGRAM_PROXY, 
TelegramParamsConstants.TELEGRAM_PROXY)
+                .addValidate(Validate.newBuilder()
+                        .setRequired(false)
+                        .build())
+                .build();
+
+        InputParam portParam = 
InputParam.newBuilder(TelegramParamsConstants.NAME_TELEGRAM_PORT, 
TelegramParamsConstants.TELEGRAM_PORT)
+                .addValidate(Validate.newBuilder()
+                        .setRequired(false)
+                        .build())
+                .build();
+
+        InputParam userParam = 
InputParam.newBuilder(TelegramParamsConstants.NAME_TELEGRAM_USER, 
TelegramParamsConstants.TELEGRAM_USER)
+                .addValidate(Validate.newBuilder()
+                        .setRequired(false)
+                        .build())
+                .build();
+
+        PasswordParam passwordParam = 
PasswordParam.newBuilder(TelegramParamsConstants.NAME_TELEGRAM_PASSWORD, 
TelegramParamsConstants.TELEGRAM_PASSWORD)
+                .addValidate(Validate.newBuilder()
+                        .setRequired(false)
+                        .build())
+                .setPlaceholder("if enable use authentication, you need input 
password")
+                .build();
+
+        return Arrays.asList(webHookParam, botTokenParam, chatIdParam, 
parseMode, isEnableProxy, proxyParam, portParam, userParam, passwordParam);
+    }
+
+
+}
diff --git 
a/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-slack/src/main/java/org/apache/dolphinscheduler/plugin/alert/slack/SlackParamsConstants.java
 
b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-telegram/src/main/java/org/apache/dolphinscheduler/plugin/alert/telegram/TelegramAlertConstants.java
similarity index 60%
copy from 
dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-slack/src/main/java/org/apache/dolphinscheduler/plugin/alert/slack/SlackParamsConstants.java
copy to 
dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-telegram/src/main/java/org/apache/dolphinscheduler/plugin/alert/telegram/TelegramAlertConstants.java
index 928eba6..3092506 100644
--- 
a/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-slack/src/main/java/org/apache/dolphinscheduler/plugin/alert/slack/SlackParamsConstants.java
+++ 
b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-telegram/src/main/java/org/apache/dolphinscheduler/plugin/alert/telegram/TelegramAlertConstants.java
@@ -15,19 +15,28 @@
  * limitations under the License.
  */
 
-package org.apache.dolphinscheduler.plugin.alert.slack;
+package org.apache.dolphinscheduler.plugin.alert.telegram;
 
-public final class SlackParamsConstants {
-    public static final String SLACK_WEB_HOOK_URL = "$t('webhook')";
-    public static final String SLACK_WEN_HOOK_URL_NAME = "webHook";
-    public static final String SLACK_BOT = "$t('Username')";
-    public static final String SLACK_BOT_NAME = "username";
-    public static final String TEXT = "text";
-    public static final String ATTACHMENT = "attachments";
+public final class TelegramAlertConstants {
 
-    public static final Integer MAX_SHOW_NUMBER = 100;
+    static final String PARSE_MODE_TXT = "Txt";
 
-    private SlackParamsConstants() {
+    static final String PARSE_MODE_MARKDOWN = "Markdown";
+
+    static final String PARSE_MODE_MARKDOWN_V2 = "MarkdownV2";
+
+    static final String PARSE_MODE_HTML = "Html";
+
+    /**
+     * TELEGRAM_PUSH_URL
+     *
+     * <pre>
+     *     https://api.telegram.org/bot{botToken}/sendMessage
+     * </pre>
+     */
+    static final String TELEGRAM_PUSH_URL = 
"https://api.telegram.org/bot{botToken}/sendMessage";;
+
+    private TelegramAlertConstants() {
         throw new UnsupportedOperationException("This is a utility class and 
cannot be instantiated");
     }
 }
diff --git 
a/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-telegram/src/main/java/org/apache/dolphinscheduler/plugin/alert/telegram/TelegramParamsConstants.java
 
b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-telegram/src/main/java/org/apache/dolphinscheduler/plugin/alert/telegram/TelegramParamsConstants.java
new file mode 100644
index 0000000..d9fbb3f
--- /dev/null
+++ 
b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-telegram/src/main/java/org/apache/dolphinscheduler/plugin/alert/telegram/TelegramParamsConstants.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache 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
+ *
+ *    http://www.apache.org/licenses/LICENSE-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.
+ */
+
+package org.apache.dolphinscheduler.plugin.alert.telegram;
+
+
+public final class TelegramParamsConstants {
+
+    static final String TELEGRAM_WEB_HOOK = "$t('webHook')";
+    static final String NAME_TELEGRAM_WEB_HOOK = "webHook";
+
+    static final String TELEGRAM_BOT_TOKEN = "botToken";
+    static final String NAME_TELEGRAM_BOT_TOKEN = "botToken";
+
+    static final String TELEGRAM_CHAT_ID = "chatId";
+    static final String NAME_TELEGRAM_CHAT_ID = "chatId";
+
+    static final String TELEGRAM_PARSE_MODE = "parseMode";
+    static final String NAME_TELEGRAM_PARSE_MODE = "parseMode";
+
+    static final String TELEGRAM_PROXY_ENABLE = "$t('isEnableProxy')";
+    static final String NAME_TELEGRAM_PROXY_ENABLE = "IsEnableProxy";
+
+    static final String TELEGRAM_PROXY = "$t('proxy')";
+    static final String NAME_TELEGRAM_PROXY = "Proxy";
+
+    static final String TELEGRAM_PORT = "$t('port')";
+    static final String NAME_TELEGRAM_PORT = "Port";
+
+    static final String TELEGRAM_USER = "$t('user')";
+    static final String NAME_TELEGRAM_USER = "User";
+
+    static final String TELEGRAM_PASSWORD = "$t('password')";
+    static final String NAME_TELEGRAM_PASSWORD = "Password";
+
+    private TelegramParamsConstants() {
+        throw new UnsupportedOperationException("This is a utility class and 
cannot be instantiated");
+    }
+
+}
diff --git 
a/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-telegram/src/main/java/org/apache/dolphinscheduler/plugin/alert/telegram/TelegramSender.java
 
b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-telegram/src/main/java/org/apache/dolphinscheduler/plugin/alert/telegram/TelegramSender.java
new file mode 100644
index 0000000..dd9ac0d
--- /dev/null
+++ 
b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-telegram/src/main/java/org/apache/dolphinscheduler/plugin/alert/telegram/TelegramSender.java
@@ -0,0 +1,251 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache 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
+ *
+ *    http://www.apache.org/licenses/LICENSE-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.
+ */
+
+package org.apache.dolphinscheduler.plugin.alert.telegram;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import org.apache.dolphinscheduler.alert.api.AlertData;
+import org.apache.dolphinscheduler.alert.api.AlertResult;
+import org.apache.dolphinscheduler.spi.utils.JSONUtils;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpHeaders;
+import org.apache.http.HttpHost;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Map;
+
+public final class TelegramSender {
+
+    private static final Logger logger = 
LoggerFactory.getLogger(TelegramSender.class);
+
+    private static final String BOT_TOKEN_REGEX = "{botToken}";
+
+    private final String chatId;
+
+    private final String parseMode;
+
+    private final Boolean enableProxy;
+
+    private String botToken;
+
+    private String url;
+
+    private String proxy;
+
+    private Integer port;
+
+    private String user;
+
+    private String password;
+
+
+    TelegramSender(Map<String, String> config) {
+        url = config.get(TelegramParamsConstants.NAME_TELEGRAM_WEB_HOOK);
+        botToken = config.get(TelegramParamsConstants.NAME_TELEGRAM_BOT_TOKEN);
+        chatId = config.get(TelegramParamsConstants.NAME_TELEGRAM_CHAT_ID);
+        parseMode = 
config.get(TelegramParamsConstants.NAME_TELEGRAM_PARSE_MODE);
+        if (url == null || url.isEmpty()) {
+            url = 
TelegramAlertConstants.TELEGRAM_PUSH_URL.replace(BOT_TOKEN_REGEX, botToken);
+        } else {
+            url = url.replace(BOT_TOKEN_REGEX, botToken);
+        }
+        enableProxy = 
Boolean.valueOf(config.get(TelegramParamsConstants.NAME_TELEGRAM_PROXY_ENABLE));
+        if (Boolean.TRUE.equals(enableProxy)) {
+            port = 
Integer.parseInt(config.get(TelegramParamsConstants.NAME_TELEGRAM_PORT));
+            proxy = config.get(TelegramParamsConstants.NAME_TELEGRAM_PROXY);
+            user = config.get(TelegramParamsConstants.NAME_TELEGRAM_USER);
+            password = 
config.get(TelegramParamsConstants.NAME_TELEGRAM_PASSWORD);
+        }
+    }
+
+    /**
+     * sendMessage
+     *
+     * @param alertData alert data
+     * @return alert result
+     * @see <a href="https://core.telegram.org/bots/api#sendmessage";>telegram 
bot api</a>
+     */
+    public AlertResult sendMessage(AlertData alertData) {
+        AlertResult result;
+        try {
+            String resp = sendInvoke(alertData.getTitle(), 
alertData.getContent());
+            result = parseRespToResult(resp);
+        } catch (Exception e) {
+            logger.warn("send telegram alert msg exception : {}", 
e.getMessage());
+            result = new AlertResult();
+            result.setStatus("false");
+            result.setMessage(String.format("send telegram alert fail. %s", 
e.getMessage()));
+        }
+        return result;
+    }
+
+    private AlertResult parseRespToResult(String resp) {
+        AlertResult result = new AlertResult();
+        result.setStatus("false");
+        if (null == resp || resp.isEmpty()) {
+            result.setMessage("send telegram msg error. telegram server resp 
is empty");
+            return result;
+        }
+        TelegramSendMsgResponse response = JSONUtils.parseObject(resp, 
TelegramSendMsgResponse.class);
+        if (null == response) {
+            result.setMessage("send telegram msg fail.");
+            return result;
+        }
+        if (!response.isOk()) {
+            result.setMessage(String.format("send telegram alert fail. 
telegram server error_code: %d, description: %s",
+                    response.errorCode, response.description));
+        } else {
+            result.setStatus("true");
+            result.setMessage("send telegram msg success.");
+        }
+        return result;
+    }
+
+
+    private String sendInvoke(String title, String content) throws IOException 
{
+        HttpPost httpPost = buildHttpPost(url, buildMsgJsonStr(content));
+        CloseableHttpClient httpClient;
+        if (Boolean.TRUE.equals(enableProxy)) {
+            httpClient = getProxyClient(proxy, port, user, password);
+            RequestConfig rcf = getProxyConfig(proxy, port);
+            httpPost.setConfig(rcf);
+        } else {
+            httpClient = getDefaultClient();
+        }
+
+        try {
+            CloseableHttpResponse response = httpClient.execute(httpPost);
+            String resp;
+            try {
+                HttpEntity entity = response.getEntity();
+                resp = EntityUtils.toString(entity, "UTF-8");
+                EntityUtils.consume(entity);
+            } finally {
+                response.close();
+            }
+            logger.info("Telegram send title :{},content : {}, resp: {}", 
title, content, resp);
+            return resp;
+        } finally {
+            httpClient.close();
+        }
+    }
+
+    private String buildMsgJsonStr(String content) {
+        Map<String, Object> items = new HashMap<>();
+        items.put("chat_id", chatId);
+        if (!isTextParseMode()) {
+            items.put("parse_mode", parseMode);
+        }
+        items.put("text", content);
+        return JSONUtils.toJsonString(items);
+    }
+
+    private boolean isTextParseMode() {
+        return null == parseMode || 
TelegramAlertConstants.PARSE_MODE_TXT.equals(parseMode);
+    }
+
+    static class TelegramSendMsgResponse {
+        @JsonProperty("ok")
+        private Boolean ok;
+        @JsonProperty("error_code")
+        private Integer errorCode;
+        @JsonProperty("description")
+        private String description;
+        @JsonProperty("result")
+        private Object result;
+
+        public boolean isOk() {
+            return null != ok && ok;
+        }
+
+        public Boolean getOk() {
+            return ok;
+        }
+
+        @JsonProperty("ok")
+        public void setOk(Boolean ok) {
+            this.ok = ok;
+        }
+
+        @JsonProperty("error_code")
+        public void setErrorCode(Integer errorCode) {
+            this.errorCode = errorCode;
+        }
+
+        public Integer getErrorCode() {
+            return errorCode;
+        }
+
+        public String getDescription() {
+            return description;
+        }
+
+        @JsonProperty("description")
+        public void setDescription(String description) {
+            this.description = description;
+        }
+
+        public Object getResult() {
+            return result;
+        }
+
+        @JsonProperty("result")
+        public void setResult(Object result) {
+            this.result = result;
+        }
+    }
+
+    private static HttpPost buildHttpPost(String url, String msg) {
+        HttpPost post = new HttpPost(url);
+        StringEntity entity = new StringEntity(msg, StandardCharsets.UTF_8);
+        post.setEntity(entity);
+        post.addHeader(HttpHeaders.CONTENT_TYPE, 
ContentType.APPLICATION_JSON.toString());
+        return post;
+    }
+
+    private static CloseableHttpClient getDefaultClient() {
+        return HttpClients.createDefault();
+    }
+
+    private static CloseableHttpClient getProxyClient(String proxy, int port, 
String user, String password) {
+        HttpHost httpProxy = new HttpHost(proxy, port);
+        CredentialsProvider provider = new BasicCredentialsProvider();
+        provider.setCredentials(new AuthScope(httpProxy), new 
UsernamePasswordCredentials(user, password));
+        return 
HttpClients.custom().setDefaultCredentialsProvider(provider).build();
+    }
+
+    private static RequestConfig getProxyConfig(String proxy, int port) {
+        HttpHost httpProxy = new HttpHost(proxy, port);
+        return RequestConfig.custom().setProxy(httpProxy).build();
+    }
+}
diff --git 
a/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-slack/src/test/java/org/apache/dolphinscheduler/plugin/alert/slack/SlackSenderTest.java
 
b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-telegram/src/test/java/org/apache/dolphinscheduler/plugin/alert/telegram/TelegramAlertChannelFactoryTest.java
similarity index 51%
copy from 
dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-slack/src/test/java/org/apache/dolphinscheduler/plugin/alert/slack/SlackSenderTest.java
copy to 
dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-telegram/src/test/java/org/apache/dolphinscheduler/plugin/alert/telegram/TelegramAlertChannelFactoryTest.java
index c675aca..0ffe062 100644
--- 
a/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-slack/src/test/java/org/apache/dolphinscheduler/plugin/alert/slack/SlackSenderTest.java
+++ 
b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-telegram/src/test/java/org/apache/dolphinscheduler/plugin/alert/telegram/TelegramAlertChannelFactoryTest.java
@@ -15,25 +15,33 @@
  * limitations under the License.
  */
 
-package org.apache.dolphinscheduler.plugin.alert.slack;
-
-import java.util.HashMap;
-import java.util.Map;
+package org.apache.dolphinscheduler.plugin.alert.telegram;
 
+import org.apache.dolphinscheduler.alert.api.AlertChannel;
+import org.apache.dolphinscheduler.spi.params.base.PluginParams;
 import org.junit.Assert;
 import org.junit.Test;
 
-public class SlackSenderTest {
+import java.util.List;
+
+public class TelegramAlertChannelFactoryTest {
+
+    private TelegramAlertChannelFactory telegramAlertChannelFactory = new 
TelegramAlertChannelFactory();
+
+    @Test
+    public void testTestGetName() {
+        Assert.assertEquals("Telegram", telegramAlertChannelFactory.name());
+    }
+
+    @Test
+    public void testGetParams() {
+        List<PluginParams> params = telegramAlertChannelFactory.params();
+        Assert.assertEquals(9, params.size());
+    }
 
     @Test
-    public void testSendMessage() {
-        Map<String, String> alertparam = new HashMap<>();
-        alertparam.put(SlackParamsConstants.SLACK_WEN_HOOK_URL_NAME,
-            "https://hooks.slack.com/services/123456";);
-        alertparam.put(SlackParamsConstants.SLACK_BOT_NAME, 
"Dolphinscheduler");
-
-        SlackSender slackSender = new SlackSender(alertparam);
-        String response = slackSender.sendMessage("test title", "test 
content");
-        Assert.assertNotEquals("ok", response);
+    public void testCreate() {
+        AlertChannel alertChannel = telegramAlertChannelFactory.create();
+        Assert.assertTrue(alertChannel instanceof TelegramAlertChannel);
     }
 }
diff --git 
a/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-telegram/src/test/java/org/apache/dolphinscheduler/plugin/alert/telegram/TelegramSenderTest.java
 
b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-telegram/src/test/java/org/apache/dolphinscheduler/plugin/alert/telegram/TelegramSenderTest.java
new file mode 100644
index 0000000..8ebd6fc
--- /dev/null
+++ 
b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-telegram/src/test/java/org/apache/dolphinscheduler/plugin/alert/telegram/TelegramSenderTest.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache 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
+ *
+ *    http://www.apache.org/licenses/LICENSE-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.
+ */
+
+package org.apache.dolphinscheduler.plugin.alert.telegram;
+
+import org.apache.dolphinscheduler.alert.api.AlertData;
+import org.apache.dolphinscheduler.alert.api.AlertResult;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class TelegramSenderTest {
+
+    private static Map<String, String> telegramConfig = new HashMap<>();
+
+    @Before
+    public void initConfig() {
+        telegramConfig.put(TelegramParamsConstants.NAME_TELEGRAM_WEB_HOOK,
+                "https://api.telegram.org/bot{botToken}/sendMessage";);
+        telegramConfig.put(
+                TelegramParamsConstants.NAME_TELEGRAM_BOT_TOKEN, "BOT_TOKEN");
+        telegramConfig.put(
+                TelegramParamsConstants.NAME_TELEGRAM_CHAT_ID, "CHAT_ID");
+        telegramConfig.put(
+                TelegramParamsConstants.NAME_TELEGRAM_PARSE_MODE, 
TelegramAlertConstants.PARSE_MODE_TXT);
+    }
+
+
+    @Test
+    public void testSendMessageFailByParamToken() {
+        AlertData alertData = new AlertData();
+        alertData.setTitle("[telegram alert] test title");
+        alertData.setContent("telegram test content");
+        telegramConfig.put(
+                TelegramParamsConstants.NAME_TELEGRAM_BOT_TOKEN, "XXXXXXX");
+        TelegramSender telegramSender = new TelegramSender(telegramConfig);
+        AlertResult result = telegramSender.sendMessage(alertData);
+        Assert.assertEquals("false", result.getStatus());
+
+    }
+
+    @Test
+    public void testSendMessageFailByChatId() {
+        AlertData alertData = new AlertData();
+        alertData.setTitle("[telegram alert] test title");
+        alertData.setContent("telegram test content");
+        telegramConfig.put(
+                TelegramParamsConstants.NAME_TELEGRAM_CHAT_ID, "-XXXXXXX");
+        TelegramSender telegramSender = new TelegramSender(telegramConfig);
+        AlertResult result = telegramSender.sendMessage(alertData);
+        Assert.assertEquals("false", result.getStatus());
+    }
+
+
+
+    @Test
+    public void testSendMessage() {
+        AlertData alertData = new AlertData();
+        alertData.setTitle("[telegram alert] test title");
+        alertData.setContent("telegram test content");
+        TelegramSender telegramSender = new TelegramSender(telegramConfig);
+        AlertResult result = telegramSender.sendMessage(alertData);
+        Assert.assertEquals("false", result.getStatus());
+
+    }
+
+    @Test
+    public void testSendMessageByMarkdown() {
+        AlertData alertData = new AlertData();
+        alertData.setTitle("[telegram alert]test markdown");
+        alertData.setContent("```python \npre-formatted fixed-width code block 
written in the Python programming language```");
+        telegramConfig.put(
+                TelegramParamsConstants.NAME_TELEGRAM_PARSE_MODE, 
TelegramAlertConstants.PARSE_MODE_MARKDOWN);
+        TelegramSender telegramSender = new TelegramSender(telegramConfig);
+        AlertResult result = telegramSender.sendMessage(alertData);
+        Assert.assertEquals("false", result.getStatus());
+
+    }
+
+    @Test
+    public void testSendMessageByHtml() {
+        AlertData alertData = new AlertData();
+        alertData.setTitle("[telegram alert]test html");
+        alertData.setContent("<b>bold</b>");
+        telegramConfig.put(
+                TelegramParamsConstants.NAME_TELEGRAM_PARSE_MODE, 
TelegramAlertConstants.PARSE_MODE_HTML);
+        TelegramSender telegramSender = new TelegramSender(telegramConfig);
+        AlertResult result = telegramSender.sendMessage(alertData);
+        Assert.assertEquals("false", result.getStatus());
+
+    }
+
+
+}
diff --git a/dolphinscheduler-alert/dolphinscheduler-alert-plugins/pom.xml 
b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/pom.xml
index c3b9be8..42f2db2 100644
--- a/dolphinscheduler-alert/dolphinscheduler-alert-plugins/pom.xml
+++ b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/pom.xml
@@ -37,6 +37,7 @@
         <module>dolphinscheduler-alert-slack</module>
         <module>dolphinscheduler-alert-pagerduty</module>
         <module>dolphinscheduler-alert-webexteams</module>
+        <module>dolphinscheduler-alert-telegram</module>
     </modules>
 
     <dependencies>
diff --git a/dolphinscheduler-alert/dolphinscheduler-alert-server/pom.xml 
b/dolphinscheduler-alert/dolphinscheduler-alert-server/pom.xml
index 8be15f4..750ea50 100644
--- a/dolphinscheduler-alert/dolphinscheduler-alert-server/pom.xml
+++ b/dolphinscheduler-alert/dolphinscheduler-alert-server/pom.xml
@@ -77,6 +77,11 @@
 
         <dependency>
             <groupId>org.apache.dolphinscheduler</groupId>
+            <artifactId>dolphinscheduler-alert-telegram</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dolphinscheduler</groupId>
             <artifactId>dolphinscheduler-dao</artifactId>
         </dependency>
 
diff --git a/dolphinscheduler-ui-next/src/locales/modules/en_US.ts 
b/dolphinscheduler-ui-next/src/locales/modules/en_US.ts
index db1fb23..dd49a21 100644
--- a/dolphinscheduler-ui-next/src/locales/modules/en_US.ts
+++ b/dolphinscheduler-ui-next/src/locales/modules/en_US.ts
@@ -664,7 +664,10 @@ const security = {
     path: 'Script Path',
     type: 'Type',
     sendType: 'Send Type',
-    username: 'Username'
+    username: 'Username',
+    botToken: 'Bot Token',
+    chatId: 'Channel Chat Id',
+    parseMode: 'Parse Mode'
   }
 }
 
diff --git a/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts 
b/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts
index 20c41a8..3878cdd 100644
--- a/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts
+++ b/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts
@@ -660,7 +660,10 @@ const security = {
     path: '脚本路径',
     type: '类型',
     sendType: '发送类型',
-    username: '用户名'
+    username: '用户名',
+    botToken: '机器人Token',
+    chatId: '频道ID',
+    parseMode: '解析类型'
   }
 }
 
diff --git a/pom.xml b/pom.xml
index e2cae23..9c7bceb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -364,6 +364,11 @@
             </dependency>
             <dependency>
                 <groupId>org.apache.dolphinscheduler</groupId>
+                <artifactId>dolphinscheduler-alert-telegram</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.dolphinscheduler</groupId>
                 <artifactId>dolphinscheduler-registry-api</artifactId>
                 <version>${project.version}</version>
             </dependency>

Reply via email to