You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@answer.apache.org by li...@apache.org on 2025/01/06 02:35:45 UTC

(incubator-answer-plugins) branch main updated (d99270e -> 8a25e44)

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

linkinstar pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-answer-plugins.git


    from d99270e  build(render-markdown-codehighlight): bump version to 0.2.2
     new 9d75869  feat: add wecom notification
     new 19bf88c  feat: update package name for find plugins
     new 0126396  feat: update package name for find plugins in go.mod
     new e0fbafb  Revert "feat: update package name for find plugins in go.mod"
     new cded6aa  feat: update notication-wecom package name and version
     new d0b0cc7  feat: adjust apache header and recheck code
     new 8a25e44  feat: format code and add notification-wecom to README.md

The 7 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 README.md                                          |   1 +
 notification-wecom/README.md                       |  35 ++++++++++
 notification-wecom/README_CN.md                    |  35 ++++++++++
 .../config.go                                      |   4 +-
 notification-wecom/docs/wecom-config.png           | Bin 0 -> 104028 bytes
 {connector-dingtalk => notification-wecom}/go.mod  |   3 +-
 .../go.sum                                         |   4 +-
 .../i18n/en_US.yaml                                |  49 +++++---------
 notification-wecom/i18n/translation.go             |  53 +++++++++++++++
 .../i18n/zh_CN.yaml                                |  48 ++++---------
 notification-wecom/info.yaml                       |   5 ++
 .../notification_wecom.go                          |  74 ++++++++++++++-------
 .../schema.go                                      |  11 ++-
 .../user_config.go                                 |   4 +-
 14 files changed, 221 insertions(+), 105 deletions(-)
 create mode 100644 notification-wecom/README.md
 create mode 100644 notification-wecom/README_CN.md
 copy {notification-dingtalk => notification-wecom}/config.go (94%)
 create mode 100644 notification-wecom/docs/wecom-config.png
 copy {connector-dingtalk => notification-wecom}/go.mod (94%)
 copy {notification-dingtalk => notification-wecom}/go.sum (98%)
 copy {notification-dingtalk => notification-wecom}/i18n/en_US.yaml (55%)
 create mode 100644 notification-wecom/i18n/translation.go
 copy {notification-dingtalk => notification-wecom}/i18n/zh_CN.yaml (55%)
 create mode 100644 notification-wecom/info.yaml
 copy user-center-wecom/notification.go => notification-wecom/notification_wecom.go (70%)
 copy {notification-dingtalk => notification-wecom}/schema.go (82%)
 copy {notification-dingtalk => notification-wecom}/user_config.go (97%)


(incubator-answer-plugins) 05/07: feat: update notication-wecom package name and version

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

linkinstar pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-answer-plugins.git

commit cded6aa9b251822502eb11578f90c940ae109323
Author: lihui <me...@lihui.net>
AuthorDate: Fri Jan 3 12:09:59 2025 +0800

    feat: update notication-wecom package name and version
---
 notification-wecom/README.md             |  2 +-
 notification-wecom/README_CN.md          |  2 +-
 notification-wecom/config.go             |  2 +-
 notification-wecom/go.mod                |  2 +-
 notification-wecom/info.yaml             |  4 +--
 notification-wecom/notification_wecom.go | 42 +++++++++++++++-----------------
 notification-wecom/user_config.go        |  2 +-
 7 files changed, 26 insertions(+), 30 deletions(-)

diff --git a/notification-wecom/README.md b/notification-wecom/README.md
index 5006009..e7a3dca 100644
--- a/notification-wecom/README.md
+++ b/notification-wecom/README.md
@@ -5,7 +5,7 @@
 To use the notification-wecom plugin with your application, install it using the following command:
 
 ```bash
-./answer build --with github.com/lhui/incubator-answer-plugins/notification-wecom
+./answer build --with github.com/apache/incubator-answer-plugins/notification-wecom
 ```
 
 
diff --git a/notification-wecom/README_CN.md b/notification-wecom/README_CN.md
index 607f225..ca3e362 100644
--- a/notification-wecom/README_CN.md
+++ b/notification-wecom/README_CN.md
@@ -5,7 +5,7 @@
 要使用通知企业微信通知插件,请使用以下命令进行安装:
 
 ```bash
-./answer build --with github.com/lhui/incubator-answer-plugins/notification-wecom
+./answer build --with github.com/apache/incubator-answer-plugins/notification-wecom
 ```
 
 
diff --git a/notification-wecom/config.go b/notification-wecom/config.go
index 19a7fe1..0bdcc81 100644
--- a/notification-wecom/config.go
+++ b/notification-wecom/config.go
@@ -22,7 +22,7 @@ package wecom
 import (
 	"encoding/json"
 
-	"github.com/lhui/incubator-answer-plugins/notification-wecom/i18n"
+	"github.com/apache/incubator-answer-plugins/notification-wecom/i18n"
 	"github.com/apache/incubator-answer/plugin"
 )
 
diff --git a/notification-wecom/go.mod b/notification-wecom/go.mod
index 6e1292c..2465589 100644
--- a/notification-wecom/go.mod
+++ b/notification-wecom/go.mod
@@ -1,4 +1,4 @@
-module github.com/lhui/incubator-answer-plugins/notification-wecom
+module github.com/apache/incubator-answer-plugins/notification-wecom
 
 go 1.23.4
 
diff --git a/notification-wecom/info.yaml b/notification-wecom/info.yaml
index bb07c5c..7158022 100644
--- a/notification-wecom/info.yaml
+++ b/notification-wecom/info.yaml
@@ -1,5 +1,5 @@
 slug_name: notification_wecom
 type: notification
-version: 0.0.1
+version: 1.0.0
 author: lihui
-link: https://github.com/lhui/incubator-answer-plugins/tree/dev/notification-wecom
+link: https://github.com/apache/incubator-answer-plugins/tree/main/notification-wecom
diff --git a/notification-wecom/notification_wecom.go b/notification-wecom/notification_wecom.go
index 3f6e438..f76be4a 100644
--- a/notification-wecom/notification_wecom.go
+++ b/notification-wecom/notification_wecom.go
@@ -1,15 +1,14 @@
 package wecom
 
 import (
-  "embed"
-  "github.com/apache/incubator-answer/plugin"
-  "github.com/go-resty/resty/v2"
-  "strings"
-
-  "github.com/apache/incubator-answer-plugins/util"
-  wecomI18n "github.com/lhui/incubator-answer-plugins/notification-wecom/i18n"
-  "github.com/segmentfault/pacman/i18n"
-  "github.com/segmentfault/pacman/log"
+	"embed"
+	"github.com/apache/incubator-answer/plugin"
+	"strings"
+
+	wecomI18n "github.com/apache/incubator-answer-plugins/notification-wecom/i18n"
+	"github.com/apache/incubator-answer-plugins/util"
+	"github.com/segmentfault/pacman/i18n"
+	"github.com/segmentfault/pacman/log"
 )
 
 //go:embed  info.yaml
@@ -28,21 +27,19 @@ func init() {
 	plugin.Register(uc)
 }
 func (*Notification) Info() plugin.Info {
-  info := &util.Info{}
+	info := &util.Info{}
 	info.GetInfo(Info)
 
-  return plugin.Info{
-    Name:        plugin.MakeTranslator(wecomI18n.InfoName),
-    SlugName:    info.SlugName,
-    Description: plugin.MakeTranslator(wecomI18n.InfoDescription),
-    Author:      info.Author,
-    Version:     info.Version,
-    Link:        info.Link,
-  }
+	return plugin.Info{
+		Name:        plugin.MakeTranslator(wecomI18n.InfoName),
+		SlugName:    info.SlugName,
+		Description: plugin.MakeTranslator(wecomI18n.InfoDescription),
+		Author:      info.Author,
+		Version:     info.Version,
+		Link:        info.Link,
+	}
 }
 
-
-
 // GetNewQuestionSubscribers returns the subscribers of the new question notification
 func (n *Notification) GetNewQuestionSubscribers() (userIDs []string) {
 	for userID, conf := range n.UserConfigCache.userConfigMapping {
@@ -98,7 +95,7 @@ func (n *Notification) Notify(msg plugin.NotificationMessage) {
 		return
 	}
 
-	notificationMsg:= renderNotification(msg)
+	notificationMsg := renderNotification(msg)
 	// no need to send empty message
 	if len(notificationMsg) == 0 {
 		log.Debugf("this type of notification will be drop, the type is %s", msg.Type)
@@ -119,7 +116,7 @@ func (n *Notification) Notify(msg plugin.NotificationMessage) {
 	}
 }
 
-func renderNotification(msg plugin.NotificationMessage) (string) {
+func renderNotification(msg plugin.NotificationMessage) string {
 	lang := i18n.Language(msg.ReceiverLang)
 	switch msg.Type {
 	case plugin.NotificationUpdateQuestion:
@@ -146,4 +143,3 @@ func renderNotification(msg plugin.NotificationMessage) (string) {
 	}
 	return ""
 }
-
diff --git a/notification-wecom/user_config.go b/notification-wecom/user_config.go
index 30562d2..bb294a8 100644
--- a/notification-wecom/user_config.go
+++ b/notification-wecom/user_config.go
@@ -24,7 +24,7 @@ import (
 	"fmt"
 	"sync"
 
-	"github.com/lhui/incubator-answer-plugins/notification-wecom/i18n"
+	"github.com/apache/incubator-answer-plugins/notification-wecom/i18n"
 	"github.com/apache/incubator-answer/plugin"
 	"github.com/segmentfault/pacman/log"
 )


(incubator-answer-plugins) 06/07: feat: adjust apache header and recheck code

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

linkinstar pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-answer-plugins.git

commit d0b0cc78ab039ff9db20a2c15c75a253c4064156
Author: lihui <me...@lihui.net>
AuthorDate: Fri Jan 3 13:42:28 2025 +0800

    feat: adjust apache header and recheck code
---
 notification-wecom/README.md             |  2 ++
 notification-wecom/README_CN.md          |  4 +++-
 notification-wecom/go.mod                |  5 +++--
 notification-wecom/go.sum                |  4 ++++
 notification-wecom/notification_wecom.go | 20 ++++++++++++++++++++
 5 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/notification-wecom/README.md b/notification-wecom/README.md
index e7a3dca..53b3b34 100644
--- a/notification-wecom/README.md
+++ b/notification-wecom/README.md
@@ -1,5 +1,7 @@
 # Wecom Notification Plugin
 
+[English](./README.md) | [中文](./README_CN.md)
+
 ## How to use
 
 To use the notification-wecom plugin with your application, install it using the following command:
diff --git a/notification-wecom/README_CN.md b/notification-wecom/README_CN.md
index ca3e362..926ba35 100644
--- a/notification-wecom/README_CN.md
+++ b/notification-wecom/README_CN.md
@@ -1,5 +1,7 @@
 # 企业微信通知插件
 
+[English](./README.md) | [中文](./README_CN.md)
+
 ## 使用指南
 
 要使用通知企业微信通知插件,请使用以下命令进行安装:
@@ -30,4 +32,4 @@ https://developer.work.weixin.qq.com/document/path/91770
 
 ## 致谢
 
-感谢钉钉通知插件的开发,本插件很多代码参考壶或者直接沿用了钉钉通知插件的代码。
\ No newline at end of file
+感谢钉钉通知插件的开发,本插件很多代码参考或者直接沿用了钉钉通知插件的代码。
\ No newline at end of file
diff --git a/notification-wecom/go.mod b/notification-wecom/go.mod
index 2465589..1e191c7 100644
--- a/notification-wecom/go.mod
+++ b/notification-wecom/go.mod
@@ -1,10 +1,12 @@
 module github.com/apache/incubator-answer-plugins/notification-wecom
 
-go 1.23.4
+go 1.22.0
 
 require (
 	github.com/apache/incubator-answer v1.4.1
 	github.com/apache/incubator-answer-plugins/util v1.0.2
+	github.com/go-resty/resty/v2 v2.16.2
+	github.com/segmentfault/pacman v1.0.5-0.20230822083413-c0075a2d401f
 )
 
 require (
@@ -32,7 +34,6 @@ require (
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 	github.com/modern-go/reflect2 v1.0.2 // indirect
 	github.com/pelletier/go-toml/v2 v2.2.3 // indirect
-	github.com/segmentfault/pacman v1.0.5-0.20230822083413-c0075a2d401f // indirect
 	github.com/segmentfault/pacman/contrib/i18n v0.0.0-20230822083413-c0075a2d401f // indirect
 	github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
 	github.com/ugorji/go/codec v1.2.12 // indirect
diff --git a/notification-wecom/go.sum b/notification-wecom/go.sum
index b08ce5b..1bd7f18 100644
--- a/notification-wecom/go.sum
+++ b/notification-wecom/go.sum
@@ -36,6 +36,8 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn
 github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
 github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA=
 github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
+github.com/go-resty/resty/v2 v2.16.2 h1:CpRqTjIzq/rweXUt9+GxzzQdlkqMdt8Lm/fuK/CAbAg=
+github.com/go-resty/resty/v2 v2.16.2/go.mod h1:0fHAoK7JoBy/Ch36N8VFeMsK7xQOHhvWaC3iOktwmIU=
 github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
 github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
 github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
@@ -126,6 +128,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
 golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
+golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
+golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190422233926-fe54fb35175b/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
diff --git a/notification-wecom/notification_wecom.go b/notification-wecom/notification_wecom.go
index f76be4a..9b01256 100644
--- a/notification-wecom/notification_wecom.go
+++ b/notification-wecom/notification_wecom.go
@@ -1,8 +1,28 @@
+/*
+ * 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 wecom
 
 import (
 	"embed"
 	"github.com/apache/incubator-answer/plugin"
+	"github.com/go-resty/resty/v2"
 	"strings"
 
 	wecomI18n "github.com/apache/incubator-answer-plugins/notification-wecom/i18n"


(incubator-answer-plugins) 01/07: feat: add wecom notification

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

linkinstar pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-answer-plugins.git

commit 9d75869e3d3748de367e9ce8768b45414f3595dd
Author: lihui <me...@lihui.net>
AuthorDate: Fri Jan 3 00:53:32 2025 +0800

    feat: add wecom notification
---
 notification-wecom/README.md             |  33 +++++++
 notification-wecom/README_CN.md          |  33 +++++++
 notification-wecom/config.go             |  53 +++++++++++
 notification-wecom/docs/wecom-config.png | Bin 0 -> 104028 bytes
 notification-wecom/go.mod                |  47 ++++++++++
 notification-wecom/go.sum                | 147 ++++++++++++++++++++++++++++++
 notification-wecom/i18n/en_US.yaml       |  93 +++++++++++++++++++
 notification-wecom/i18n/translation.go   |  52 +++++++++++
 notification-wecom/i18n/zh_CN.yaml       |  92 +++++++++++++++++++
 notification-wecom/info.yaml             |   5 ++
 notification-wecom/notification_wecom.go | 149 +++++++++++++++++++++++++++++++
 notification-wecom/schema.go             |  38 ++++++++
 notification-wecom/user_config.go        | 137 ++++++++++++++++++++++++++++
 13 files changed, 879 insertions(+)

diff --git a/notification-wecom/README.md b/notification-wecom/README.md
new file mode 100644
index 0000000..5006009
--- /dev/null
+++ b/notification-wecom/README.md
@@ -0,0 +1,33 @@
+# Wecom Notification Plugin
+
+## How to use
+
+To use the notification-wecom plugin with your application, install it using the following command:
+
+```bash
+./answer build --with github.com/lhui/incubator-answer-plugins/notification-wecom
+```
+
+
+## Feature
+
+- Send message to Wecom
+
+## Config
+
+> Config Webhook URL and open the notification
+
+- Webhook URL: such as `https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`
+
+## Preview
+
+![Wecom Config](./docs/wecom-config.png)
+
+## Document
+
+https://open.work.weixin.qq.com/help2/pc/14931
+https://developer.work.weixin.qq.com/document/path/91770
+
+## Thanks
+
+Thanks for sharing the DingTalk notification plugin, it's a helpful reference for this plugin development.
diff --git a/notification-wecom/README_CN.md b/notification-wecom/README_CN.md
new file mode 100644
index 0000000..607f225
--- /dev/null
+++ b/notification-wecom/README_CN.md
@@ -0,0 +1,33 @@
+# 企业微信通知插件
+
+## 使用指南
+
+要使用通知企业微信通知插件,请使用以下命令进行安装:
+
+```bash
+./answer build --with github.com/lhui/incubator-answer-plugins/notification-wecom
+```
+
+
+## 功能
+
+- 通过企业微信群机器人发送信息到企业微信
+
+## 配置
+
+> 配置Webhook URL并打开通知
+
+- Webhook 地址: 类似于 `https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`
+
+## 预览
+
+![企业微信配置](./docs/wecom-config.png)
+
+## 开发文档
+
+https://open.work.weixin.qq.com/help2/pc/14931
+https://developer.work.weixin.qq.com/document/path/91770
+
+## 致谢
+
+感谢钉钉通知插件的开发,本插件很多代码参考壶或者直接沿用了钉钉通知插件的代码。
\ No newline at end of file
diff --git a/notification-wecom/config.go b/notification-wecom/config.go
new file mode 100644
index 0000000..0bdcc81
--- /dev/null
+++ b/notification-wecom/config.go
@@ -0,0 +1,53 @@
+/*
+ * 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 wecom
+
+import (
+	"encoding/json"
+
+	"github.com/apache/incubator-answer-plugins/notification-wecom/i18n"
+	"github.com/apache/incubator-answer/plugin"
+)
+
+type NotificationConfig struct {
+	Notification bool `json:"notification"`
+}
+
+func (n *Notification) ConfigFields() []plugin.ConfigField {
+	return []plugin.ConfigField{
+		{
+			Name:        "notification",
+			Type:        plugin.ConfigTypeSwitch,
+			Title:       plugin.MakeTranslator(i18n.ConfigNotificationTitle),
+			Description: plugin.MakeTranslator(i18n.ConfigNotificationDescription),
+			UIOptions: plugin.ConfigFieldUIOptions{
+				Label: plugin.MakeTranslator(i18n.ConfigNotificationLabel),
+			},
+			Value: n.Config.Notification,
+		},
+	}
+}
+
+func (n *Notification) ConfigReceiver(config []byte) error {
+	c := &NotificationConfig{}
+	_ = json.Unmarshal(config, c)
+	n.Config = c
+	return nil
+}
diff --git a/notification-wecom/docs/wecom-config.png b/notification-wecom/docs/wecom-config.png
new file mode 100644
index 0000000..be534f1
Binary files /dev/null and b/notification-wecom/docs/wecom-config.png differ
diff --git a/notification-wecom/go.mod b/notification-wecom/go.mod
new file mode 100644
index 0000000..2465589
--- /dev/null
+++ b/notification-wecom/go.mod
@@ -0,0 +1,47 @@
+module github.com/apache/incubator-answer-plugins/notification-wecom
+
+go 1.23.4
+
+require (
+	github.com/apache/incubator-answer v1.4.1
+	github.com/apache/incubator-answer-plugins/util v1.0.2
+)
+
+require (
+	github.com/LinkinStars/go-i18n/v2 v2.2.2 // indirect
+	github.com/aymerick/douceur v0.2.0 // indirect
+	github.com/bytedance/sonic v1.12.2 // indirect
+	github.com/bytedance/sonic/loader v0.2.0 // indirect
+	github.com/cloudwego/base64x v0.1.4 // indirect
+	github.com/cloudwego/iasm v0.2.0 // indirect
+	github.com/gabriel-vasile/mimetype v1.4.5 // indirect
+	github.com/gin-contrib/sse v0.1.0 // indirect
+	github.com/gin-gonic/gin v1.10.0 // indirect
+	github.com/go-playground/locales v0.14.1 // indirect
+	github.com/go-playground/universal-translator v0.18.1 // indirect
+	github.com/go-playground/validator/v10 v10.22.1 // indirect
+	github.com/goccy/go-json v0.10.3 // indirect
+	github.com/google/wire v0.5.0 // indirect
+	github.com/gorilla/css v1.0.1 // indirect
+	github.com/json-iterator/go v1.1.12 // indirect
+	github.com/klauspost/cpuid/v2 v2.2.8 // indirect
+	github.com/kr/text v0.2.0 // indirect
+	github.com/leodido/go-urn v1.4.0 // indirect
+	github.com/mattn/go-isatty v0.0.20 // indirect
+	github.com/microcosm-cc/bluemonday v1.0.27 // indirect
+	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
+	github.com/modern-go/reflect2 v1.0.2 // indirect
+	github.com/pelletier/go-toml/v2 v2.2.3 // indirect
+	github.com/segmentfault/pacman v1.0.5-0.20230822083413-c0075a2d401f // indirect
+	github.com/segmentfault/pacman/contrib/i18n v0.0.0-20230822083413-c0075a2d401f // indirect
+	github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
+	github.com/ugorji/go/codec v1.2.12 // indirect
+	golang.org/x/arch v0.10.0 // indirect
+	golang.org/x/crypto v0.27.0 // indirect
+	golang.org/x/net v0.29.0 // indirect
+	golang.org/x/sys v0.25.0 // indirect
+	golang.org/x/text v0.18.0 // indirect
+	google.golang.org/protobuf v1.34.2 // indirect
+	gopkg.in/yaml.v3 v3.0.1 // indirect
+	sigs.k8s.io/yaml v1.4.0 // indirect
+)
diff --git a/notification-wecom/go.sum b/notification-wecom/go.sum
new file mode 100644
index 0000000..b08ce5b
--- /dev/null
+++ b/notification-wecom/go.sum
@@ -0,0 +1,147 @@
+github.com/BurntSushi/toml v1.0.0 h1:dtDWrepsVPfW9H/4y7dDgFc2MBUSeJhlaDtK13CxFlU=
+github.com/BurntSushi/toml v1.0.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
+github.com/LinkinStars/go-i18n/v2 v2.2.2 h1:ZfjpzbW13dv6btv3RALKZkpN9A+7K1JA//2QcNeWaxU=
+github.com/LinkinStars/go-i18n/v2 v2.2.2/go.mod h1:hLglSJ4/3M0Y7ZVcoEJI+OwqkglHCA32DdjuJJR2LbM=
+github.com/apache/incubator-answer v1.4.1 h1:O7BJyhLmc0JxYgjBz/vkapN2vtI0ylFx+PdOzqROM0c=
+github.com/apache/incubator-answer v1.4.1/go.mod h1:L0GTnyO7ykalUVJkApwtbWGLfsknwSyTKdJG5V4x/d8=
+github.com/apache/incubator-answer-plugins/util v1.0.2 h1:PontocVaiEm+oTj+4aDonwWDZnxywUeHsaTwlQgclfA=
+github.com/apache/incubator-answer-plugins/util v1.0.2/go.mod h1:KPMSiM4ec4uEl2njaGINYuSl6zVmHdvPB2nHUxVcQDo=
+github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
+github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
+github.com/bytedance/sonic v1.12.2 h1:oaMFuRTpMHYLpCntGca65YWt5ny+wAceDERTkT2L9lg=
+github.com/bytedance/sonic v1.12.2/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk=
+github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
+github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM=
+github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
+github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
+github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
+github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
+github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
+github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/gabriel-vasile/mimetype v1.4.5 h1:J7wGKdGu33ocBOhGy0z653k/lFKLFDPJMG8Gql0kxn4=
+github.com/gabriel-vasile/mimetype v1.4.5/go.mod h1:ibHel+/kbxn9x2407k1izTA1S81ku1z/DlgOW2QE0M4=
+github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
+github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
+github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
+github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
+github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
+github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
+github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
+github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
+github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
+github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
+github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA=
+github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
+github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
+github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
+github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
+github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
+github.com/google/wire v0.5.0 h1:I7ELFeVBr3yfPIcc8+MWvrjk+3VjbcSzoXm3JVa+jD8=
+github.com/google/wire v0.5.0/go.mod h1:ngWDr9Qvq3yZA10YrxfyGELY/AFWGVpy9c1LTRi1EoU=
+github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8=
+github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0=
+github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
+github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
+github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
+github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM=
+github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
+github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
+github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
+github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
+github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
+github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
+github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
+github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
+github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk=
+github.com/microcosm-cc/bluemonday v1.0.27/go.mod h1:jFi9vgW+H7c3V0lb6nR74Ib/DIB5OBs92Dimizgw2cA=
+github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
+github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
+github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
+github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
+github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
+github.com/segmentfault/pacman v1.0.5-0.20230822083413-c0075a2d401f h1:9f2Bjf6bdMvNyUop32wAGJCdp+Jdm/d6nKBYvFvkRo0=
+github.com/segmentfault/pacman v1.0.5-0.20230822083413-c0075a2d401f/go.mod h1:5lNp5REd8QMThmBUvR3Fi9Y3AsOB4GRq7soCB4QLqOs=
+github.com/segmentfault/pacman/contrib/i18n v0.0.0-20230822083413-c0075a2d401f h1:xia6AXJor4UV4T6htmHlfN7CGXZ04vlWwybVtFKJ/mA=
+github.com/segmentfault/pacman/contrib/i18n v0.0.0-20230822083413-c0075a2d401f/go.mod h1:7QcRmnV7OYq4hNOOCWXT5HXnN/u756JUsqIW0Bw8n9E=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
+github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
+github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
+github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
+github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+golang.org/x/arch v0.10.0 h1:S3huipmSclq3PJMNe76NGwkBR504WFkQ5dhzWzP8ZW8=
+golang.org/x/arch v0.10.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
+golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
+golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
+golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
+golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190422233926-fe54fb35175b/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
+google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
+gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
+sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
+sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
diff --git a/notification-wecom/i18n/en_US.yaml b/notification-wecom/i18n/en_US.yaml
new file mode 100644
index 0000000..ba01cdc
--- /dev/null
+++ b/notification-wecom/i18n/en_US.yaml
@@ -0,0 +1,93 @@
+# 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.
+
+
+plugin:
+  wecom_notification:
+    backend:
+      info:
+        name:
+          other: Wecom Notification
+        description:
+          other: Send notifications to Wecom
+      config:
+        tip:
+          title:
+            other: Push notification service has been turned off.
+        notification:
+          label:
+            other: Turn on push notifications
+          title:
+            other: Notifications
+          description:
+            other: Users will receive notifications on Wecom.
+      user_config:
+        webhook_url:
+          title:
+            other: Webhook URL
+        inbox_notifications:
+          title:
+            other: Inbox Notifications
+          label:
+            other: Turn on inbox notifications
+          description:
+            other: Answers to your questions, comments, invites, and more.
+        all_new_questions:
+          title:
+            other: All New Questions
+          label:
+            other: Turn on all new questions
+          description:
+            other: Get notified of all new questions. Up to 50 questions per week.
+        new_questions_for_following_tags:
+          title:
+            other: New Questions for Following Tags
+          label:
+            other: Turn on new questions for following tags
+          description:
+            other: Get notified of new questions for following tags.
+      tpl:
+        update_question:
+          text:
+            other: "[{{.TriggerUserDisplayName}}]({{.TriggerUserUrl}}) updated question [{{.QuestionTitle}}]({{.QuestionUrl}})"
+        answer_the_question:
+          text:
+            other: "[{{.TriggerUserDisplayName}}]({{.TriggerUserUrl}}) answered the question [{{.QuestionTitle}}]({{.AnswerUrl}})"
+        update_answer:
+          text:
+            other: "[{{.TriggerUserDisplayName}}]({{.TriggerUserUrl}}) updated answer [{{.QuestionTitle}}]({{.AnswerUrl}})"
+        accept_answer:
+          text:
+            other: "[{{.TriggerUserDisplayName}}]({{.TriggerUserUrl}}) accepted answer [{{.QuestionTitle}}]({{.AnswerUrl}})"
+        comment_question:
+          text:
+            other: "[{{.TriggerUserDisplayName}}]({{.TriggerUserUrl}}) commented question [{{.QuestionTitle}}]({{.CommentUrl}})"
+        comment_answer:
+          text:
+            other: "[{{.TriggerUserDisplayName}}]({{.TriggerUserUrl}}) commented answer [{{.QuestionTitle}}]({{.CommentUrl}})"
+        reply_to_you:
+          text:
+            other: "[{{.TriggerUserDisplayName}}]({{.TriggerUserUrl}}) replied you [{{.QuestionTitle}}]({{.CommentUrl}})"
+        mention_you:
+          text:
+            other: "[{{.TriggerUserDisplayName}}]({{.TriggerUserUrl}}) mentioned you [{{.QuestionTitle}}]({{.CommentUrl}})"
+        invited_you_to_answer:
+          text:
+            other: "[{{.TriggerUserDisplayName}}]({{.TriggerUserUrl}}) invited you to answer [{{.QuestionTitle}}]({{.QuestionUrl}})"
+        new_question:
+          text:
+            other: "New question:\n[{{.QuestionTitle}}]({{.QuestionUrl}})\n Tag: {{.QuestionTags}}"
diff --git a/notification-wecom/i18n/translation.go b/notification-wecom/i18n/translation.go
new file mode 100644
index 0000000..80db37e
--- /dev/null
+++ b/notification-wecom/i18n/translation.go
@@ -0,0 +1,52 @@
+/*
+ * 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 i18n
+
+const (
+	InfoName                      = "plugin.wecom_notification.backend.info.name"
+	InfoDescription               = "plugin.wecom_notification.backend.info.description"
+	ConfigTipTitle                = "plugin.wecom_notification.backend.config.tip.title"
+	ConfigNotificationLabel       = "plugin.wecom_notification.backend.config.notification.label"
+	ConfigNotificationTitle       = "plugin.wecom_notification.backend.config.notification.title"
+	ConfigNotificationDescription = "plugin.wecom_notification.backend.config.notification.description"
+
+	UserConfigWebhookURLTitle               = "plugin.wecom_notification.backend.user_config.webhook_url.title"
+	UserConfigInboxNotificationsTitle       = "plugin.wecom_notification.backend.user_config.inbox_notifications.title"
+	UserConfigInboxNotificationsLabel       = "plugin.wecom_notification.backend.user_config.inbox_notifications.label"
+	UserConfigInboxNotificationsDescription = "plugin.wecom_notification.backend.user_config.inbox_notifications.description"
+
+	UserConfigAllNewQuestionsNotificationsTitle       = "plugin.wecom_notification.backend.user_config.all_new_questions.title"
+	UserConfigAllNewQuestionsNotificationsLabel       = "plugin.wecom_notification.backend.user_config.all_new_questions.label"
+	UserConfigAllNewQuestionsNotificationsDescription = "plugin.wecom_notification.backend.user_config.all_new_questions.description"
+
+	UserConfigNewQuestionsForFollowingTagsTitle       = "plugin.wecom_notification.backend.user_config.new_questions_for_following_tags.title"
+	UserConfigNewQuestionsForFollowingTagsLabel       = "plugin.wecom_notification.backend.user_config.new_questions_for_following_tags.label"
+	UserConfigNewQuestionsForFollowingTagsDescription = "plugin.wecom_notification.backend.user_config.new_questions_for_following_tags.description"
+
+	TplUpdateQuestion          = "plugin.wecom_notification.backend.tpl.update_question.text"
+	TplAnswerTheQuestion       = "plugin.wecom_notification.backend.tpl.answer_the_question.text"
+	TplUpdateAnswer            = "plugin.wecom_notification.backend.tpl.update_answer.text"
+	TplAcceptAnswer            = "plugin.wecom_notification.backend.tpl.accept_answer.text"
+	TplCommentQuestion         = "plugin.wecom_notification.backend.tpl.comment_question.text"
+	TplCommentAnswer           = "plugin.wecom_notification.backend.tpl.comment_answer.text"
+	TplReplyToYou              = "plugin.wecom_notification.backend.tpl.reply_to_you.text"
+	TplMentionYou              = "plugin.wecom_notification.backend.tpl.mention_you.text"
+	TplInvitedYouToAnswer      = "plugin.wecom_notification.backend.tpl.invited_you_to_answer.text"
+	TplNewQuestion             = "plugin.wecom_notification.backend.tpl.new_question.text"
+)
diff --git a/notification-wecom/i18n/zh_CN.yaml b/notification-wecom/i18n/zh_CN.yaml
new file mode 100644
index 0000000..2354703
--- /dev/null
+++ b/notification-wecom/i18n/zh_CN.yaml
@@ -0,0 +1,92 @@
+# 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.
+
+plugin:
+  wecom_notification:
+    backend:
+      info:
+        name:
+          other: 企业微信通知
+        description:
+          other: 发送通知到企业微信
+      config:
+        tip:
+          title:
+            other: 推送通知服务已关闭。
+        notification:
+          label:
+            other: 打开通知
+          title:
+            other: 通知
+          description:
+            other: 用户将在企业微信上收到通知。
+      user_config:
+        webhook_url:
+          title:
+            other: Webhook URL
+        inbox_notifications:
+          title:
+            other: 收件箱通知
+          label:
+            other: 打开收件箱通知
+          description:
+            other: 问题的答案、评论、邀请等。
+        all_new_questions:
+          title:
+            other: 所有新问题通知
+          label:
+            other: 打开所有新问题通知
+          description:
+            other: 收到所有新问题的通知。每周最多 50 个问题。
+        new_questions_for_following_tags:
+          title:
+            other: 关注标签的新问题通知
+          label:
+            other: 打开关注标签的新问题通知
+          description:
+            other: 收到以下标签的新问题通知。
+      tpl:
+        update_question:
+          text:
+            other: "[{{.TriggerUserDisplayName}}]({{.TriggerUserUrl}}) 更新问题 [{{.QuestionTitle}}]({{.QuestionUrl}})"
+        answer_the_question:
+          text:
+            other: "[{{.TriggerUserDisplayName}}]({{.TriggerUserUrl}}) 回答了问题 [{{.QuestionTitle}}]({{.AnswerUrl}})"
+        update_answer:
+          text:
+            other: "[{{.TriggerUserDisplayName}}]({{.TriggerUserUrl}}) 更新答案 [{{.QuestionTitle}}]({{.AnswerUrl}})"
+        accept_answer:
+          text:
+            other: "[{{.TriggerUserDisplayName}}]({{.TriggerUserUrl}}) 接受答案 [{{.QuestionTitle}}]({{.AnswerUrl}})"
+        comment_question:
+          text:
+            other: "[{{.TriggerUserDisplayName}}]({{.TriggerUserUrl}}) 评论提问 [{{.QuestionTitle}}]({{.CommentUrl}})"
+        comment_answer:
+          text:
+            other: "[{{.TriggerUserDisplayName}}]({{.TriggerUserUrl}}) 评论回答 [{{.QuestionTitle}}]({{.CommentUrl}})"
+        reply_to_you:
+          text:
+            other: "[{{.TriggerUserDisplayName}}]({{.TriggerUserUrl}}) 回复了问题 [{{.QuestionTitle}}]({{.CommentUrl}})"
+        mention_you:
+          text:
+            other: "[{{.TriggerUserDisplayName}}]({{.TriggerUserUrl}}) 提到了你 [{{.QuestionTitle}}]({{.CommentUrl}})"
+        invited_you_to_answer:
+          text:
+            other: "[{{.TriggerUserDisplayName}}]({{.TriggerUserUrl}}) 邀请你回答 [{{.QuestionTitle}}]({{.QuestionUrl}})"
+        new_question:
+          text:
+            other: "新问题:\n [{{.QuestionTitle}}]({{.QuestionUrl}}) \n 标签: {{.QuestionTags}}"
diff --git a/notification-wecom/info.yaml b/notification-wecom/info.yaml
new file mode 100644
index 0000000..bb07c5c
--- /dev/null
+++ b/notification-wecom/info.yaml
@@ -0,0 +1,5 @@
+slug_name: notification_wecom
+type: notification
+version: 0.0.1
+author: lihui
+link: https://github.com/lhui/incubator-answer-plugins/tree/dev/notification-wecom
diff --git a/notification-wecom/notification_wecom.go b/notification-wecom/notification_wecom.go
new file mode 100644
index 0000000..64fc0f5
--- /dev/null
+++ b/notification-wecom/notification_wecom.go
@@ -0,0 +1,149 @@
+package wecom
+
+import (
+  "embed"
+  "github.com/apache/incubator-answer/plugin"
+  "github.com/go-resty/resty/v2"
+  "strings"
+
+  "github.com/apache/incubator-answer-plugins/util"
+  wecomI18n "github.com/apache/incubator-answer-plugins/notification-wecom/i18n"
+  "github.com/segmentfault/pacman/i18n"
+  "github.com/segmentfault/pacman/log"
+)
+
+//go:embed  info.yaml
+var Info embed.FS
+
+type Notification struct {
+	Config          *NotificationConfig
+	UserConfigCache *UserConfigCache
+}
+
+func init() {
+	uc := &Notification{
+		Config:          &NotificationConfig{},
+		UserConfigCache: NewUserConfigCache(),
+	}
+	plugin.Register(uc)
+}
+func (*Notification) Info() plugin.Info {
+  info := &util.Info{}
+	info.GetInfo(Info)
+
+  return plugin.Info{
+    Name:        plugin.MakeTranslator(wecomI18n.InfoName),
+    SlugName:    info.SlugName,
+    Description: plugin.MakeTranslator(wecomI18n.InfoDescription),
+    Author:      info.Author,
+    Version:     info.Version,
+    Link:        info.Link,
+  }
+}
+
+
+
+// GetNewQuestionSubscribers returns the subscribers of the new question notification
+func (n *Notification) GetNewQuestionSubscribers() (userIDs []string) {
+	for userID, conf := range n.UserConfigCache.userConfigMapping {
+		if conf.AllNewQuestions {
+			userIDs = append(userIDs, userID)
+		}
+	}
+	return userIDs
+}
+
+// Notify sends a notification to the user
+func (n *Notification) Notify(msg plugin.NotificationMessage) {
+	log.Debugf("try to send notification %+v", msg)
+
+	if !n.Config.Notification {
+		return
+	}
+
+	// get user config
+	userConfig, err := n.getUserConfig(msg.ReceiverUserID)
+	if err != nil {
+		log.Errorf("get user config failed: %v", err)
+		return
+	}
+	if userConfig == nil {
+		log.Debugf("user %s has no config", msg.ReceiverUserID)
+		return
+	}
+
+	// check if the notification is enabled
+	switch msg.Type {
+	case plugin.NotificationNewQuestion:
+		if !userConfig.AllNewQuestions {
+			log.Debugf("user %s not config the new question", msg.ReceiverUserID)
+			return
+		}
+	case plugin.NotificationNewQuestionFollowedTag:
+		if !userConfig.NewQuestionsForFollowingTags {
+			log.Debugf("user %s not config the new question followed tag", msg.ReceiverUserID)
+			return
+		}
+	default:
+		if !userConfig.InboxNotifications {
+			log.Debugf("user %s not config the inbox notification", msg.ReceiverUserID)
+			return
+		}
+	}
+
+	log.Debugf("user %s config the notification", msg.ReceiverUserID)
+
+	if len(userConfig.WebhookURL) == 0 {
+		log.Errorf("user %s has no webhook url", msg.ReceiverUserID)
+		return
+	}
+
+	notificationMsg:= renderNotification(msg)
+	// no need to send empty message
+	if len(notificationMsg) == 0 {
+		log.Debugf("this type of notification will be drop, the type is %s", msg.Type)
+		return
+	}
+
+	// Create a Resty Client
+	client := resty.New()
+	resp, err := client.R().
+		SetHeader("Content-Type", "application/json").
+		SetBody(NewWebhookReq(notificationMsg)).
+		Post(userConfig.WebhookURL)
+
+	if err != nil {
+		log.Errorf("send message failed: %v %v", err, resp)
+	} else {
+		log.Infof("send message to %s success, resp: %s", msg.ReceiverUserID, resp.String())
+	}
+}
+
+func renderNotification(msg plugin.NotificationMessage) (string) {
+	lang := i18n.Language(msg.ReceiverLang)
+	switch msg.Type {
+	case plugin.NotificationUpdateQuestion:
+		return plugin.TranslateWithData(lang, wecomI18n.TplUpdateQuestion, msg)
+	case plugin.NotificationAnswerTheQuestion:
+		return plugin.TranslateWithData(lang, wecomI18n.TplAnswerTheQuestion, msg)
+	case plugin.NotificationUpdateAnswer:
+		return plugin.TranslateWithData(lang, wecomI18n.TplUpdateAnswer, msg)
+	case plugin.NotificationAcceptAnswer:
+		return plugin.TranslateWithData(lang, wecomI18n.TplAcceptAnswer, msg)
+	case plugin.NotificationCommentQuestion:
+		return plugin.TranslateWithData(lang, wecomI18n.TplCommentQuestion, msg)
+	case plugin.NotificationCommentAnswer:
+		return plugin.TranslateWithData(lang, wecomI18n.TplCommentAnswer, msg)
+	case plugin.NotificationReplyToYou:
+		return plugin.TranslateWithData(lang, wecomI18n.TplReplyToYou, msg)
+	case plugin.NotificationMentionYou:
+		return plugin.TranslateWithData(lang, wecomI18n.TplMentionYou, msg)
+	case plugin.NotificationInvitedYouToAnswer:
+		return plugin.TranslateWithData(lang, wecomI18n.TplInvitedYouToAnswer, msg)
+	case plugin.NotificationNewQuestion, plugin.NotificationNewQuestionFollowedTag:
+		msg.QuestionTags = strings.Join(strings.Split(msg.QuestionTags, ","), ", ")
+		return plugin.TranslateWithData(lang, wecomI18n.TplNewQuestion, msg)
+	}
+	return ""
+}
+
diff --git a/notification-wecom/schema.go b/notification-wecom/schema.go
new file mode 100644
index 0000000..45b0811
--- /dev/null
+++ b/notification-wecom/schema.go
@@ -0,0 +1,38 @@
+/*
+ * 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 wecom
+
+type WebhookReq struct {
+	MsgType  string `json:"msgtype"`
+	Markdown struct {
+		Text  string `json:"content"`
+	} `json:"markdown"`
+}
+
+func NewWebhookReq(content string) *WebhookReq {
+	return &WebhookReq{
+		MsgType: "markdown",
+		Markdown: struct {
+			Text  string `json:"content"`
+		}{
+			Text:  content,
+		},
+	}
+}
diff --git a/notification-wecom/user_config.go b/notification-wecom/user_config.go
new file mode 100644
index 0000000..bb294a8
--- /dev/null
+++ b/notification-wecom/user_config.go
@@ -0,0 +1,137 @@
+/*
+ * 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 wecom
+
+import (
+	"encoding/json"
+	"fmt"
+	"sync"
+
+	"github.com/apache/incubator-answer-plugins/notification-wecom/i18n"
+	"github.com/apache/incubator-answer/plugin"
+	"github.com/segmentfault/pacman/log"
+)
+
+type UserConfig struct {
+	WebhookURL                   string `json:"webhook_url"`
+	InboxNotifications           bool   `json:"inbox_notifications"`
+	AllNewQuestions              bool   `json:"all_new_questions"`
+	NewQuestionsForFollowingTags bool   `json:"new_questions_for_following_tags"`
+}
+
+type UserConfigCache struct {
+	// key: userID value: user config
+	userConfigMapping map[string]*UserConfig
+	sync.Mutex
+}
+
+func NewUserConfigCache() *UserConfigCache {
+	ucc := &UserConfigCache{
+		userConfigMapping: make(map[string]*UserConfig),
+	}
+	return ucc
+}
+
+func (ucc *UserConfigCache) SetUserConfig(userID string, config *UserConfig) {
+	ucc.Lock()
+	defer ucc.Unlock()
+	ucc.userConfigMapping[userID] = config
+}
+
+func (n *Notification) UserConfigFields() []plugin.ConfigField {
+	fields := make([]plugin.ConfigField, 0)
+	// Show tip for user, if the notification service is disabled
+	if !n.Config.Notification {
+		fields = append(fields, plugin.ConfigField{
+			Name:        "tip",
+			Type:        plugin.ConfigTypeLegend,
+			Title:       plugin.MakeTranslator(i18n.ConfigTipTitle),
+			Description: plugin.Translator{},
+			UIOptions: plugin.ConfigFieldUIOptions{
+				ClassName:      "mb-3",
+				FieldClassName: "mb-0 text-danger",
+			},
+		})
+	}
+	fields = append(fields, plugin.ConfigField{
+		Name:     "webhook_url",
+		Type:     plugin.ConfigTypeInput,
+		Title:    plugin.MakeTranslator(i18n.UserConfigWebhookURLTitle),
+		Required: true,
+		UIOptions: plugin.ConfigFieldUIOptions{
+			InputType: plugin.InputTypeText,
+		},
+	})
+	fields = append(fields, createSwitchConfig(
+		"inbox_notifications",
+		i18n.UserConfigInboxNotificationsTitle,
+		i18n.UserConfigInboxNotificationsLabel,
+		i18n.UserConfigInboxNotificationsDescription,
+	))
+	fields = append(fields, createSwitchConfig(
+		"all_new_questions",
+		i18n.UserConfigAllNewQuestionsNotificationsTitle,
+		i18n.UserConfigAllNewQuestionsNotificationsLabel,
+		i18n.UserConfigAllNewQuestionsNotificationsDescription,
+	))
+	fields = append(fields, createSwitchConfig(
+		"new_questions_for_following_tags",
+		i18n.UserConfigNewQuestionsForFollowingTagsTitle,
+		i18n.UserConfigNewQuestionsForFollowingTagsLabel,
+		i18n.UserConfigNewQuestionsForFollowingTagsDescription,
+	))
+	return fields
+}
+
+func createSwitchConfig(name, title, label, desc string) plugin.ConfigField {
+	return plugin.ConfigField{
+		Name:        name,
+		Type:        plugin.ConfigTypeSwitch,
+		Title:       plugin.MakeTranslator(title),
+		Description: plugin.MakeTranslator(desc),
+		UIOptions: plugin.ConfigFieldUIOptions{
+			Label: plugin.MakeTranslator(label),
+		},
+	}
+}
+
+func (n *Notification) UserConfigReceiver(userID string, config []byte) error {
+	log.Debugf("receive user config %s %s", userID, string(config))
+	var userConfig UserConfig
+	err := json.Unmarshal(config, &userConfig)
+	if err != nil {
+		return fmt.Errorf("unmarshal user config failed: %w", err)
+	}
+	n.UserConfigCache.SetUserConfig(userID, &userConfig)
+	return nil
+}
+
+func (n *Notification) getUserConfig(userID string) (config *UserConfig, err error) {
+	userConfig := plugin.GetPluginUserConfig(userID, n.Info().SlugName)
+	if len(userConfig) == 0 {
+		return nil, nil
+	}
+	config = &UserConfig{}
+	err = json.Unmarshal(userConfig, config)
+	if err != nil {
+		return nil, fmt.Errorf("unmarshal user config failed: %w", err)
+	}
+	return config, nil
+}


(incubator-answer-plugins) 03/07: feat: update package name for find plugins in go.mod

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

linkinstar pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-answer-plugins.git

commit 012639633a0055f656387f51b4865d9c4b555dd5
Author: lihui <me...@lihui.net>
AuthorDate: Fri Jan 3 01:28:17 2025 +0800

    feat: update package name for find plugins in go.mod
---
 notification-wecom/go.mod | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/notification-wecom/go.mod b/notification-wecom/go.mod
index 6e1292c..2465589 100644
--- a/notification-wecom/go.mod
+++ b/notification-wecom/go.mod
@@ -1,4 +1,4 @@
-module github.com/lhui/incubator-answer-plugins/notification-wecom
+module github.com/apache/incubator-answer-plugins/notification-wecom
 
 go 1.23.4
 


(incubator-answer-plugins) 02/07: feat: update package name for find plugins

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

linkinstar pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-answer-plugins.git

commit 19bf88c8e0c853bd58566785c3a53b5aff4aa52a
Author: lihui <me...@lihui.net>
AuthorDate: Fri Jan 3 01:24:16 2025 +0800

    feat: update package name for find plugins
---
 notification-wecom/config.go             | 2 +-
 notification-wecom/go.mod                | 2 +-
 notification-wecom/notification_wecom.go | 2 +-
 notification-wecom/user_config.go        | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/notification-wecom/config.go b/notification-wecom/config.go
index 0bdcc81..19a7fe1 100644
--- a/notification-wecom/config.go
+++ b/notification-wecom/config.go
@@ -22,7 +22,7 @@ package wecom
 import (
 	"encoding/json"
 
-	"github.com/apache/incubator-answer-plugins/notification-wecom/i18n"
+	"github.com/lhui/incubator-answer-plugins/notification-wecom/i18n"
 	"github.com/apache/incubator-answer/plugin"
 )
 
diff --git a/notification-wecom/go.mod b/notification-wecom/go.mod
index 2465589..6e1292c 100644
--- a/notification-wecom/go.mod
+++ b/notification-wecom/go.mod
@@ -1,4 +1,4 @@
-module github.com/apache/incubator-answer-plugins/notification-wecom
+module github.com/lhui/incubator-answer-plugins/notification-wecom
 
 go 1.23.4
 
diff --git a/notification-wecom/notification_wecom.go b/notification-wecom/notification_wecom.go
index 64fc0f5..3f6e438 100644
--- a/notification-wecom/notification_wecom.go
+++ b/notification-wecom/notification_wecom.go
@@ -7,7 +7,7 @@ import (
   "strings"
 
   "github.com/apache/incubator-answer-plugins/util"
-  wecomI18n "github.com/apache/incubator-answer-plugins/notification-wecom/i18n"
+  wecomI18n "github.com/lhui/incubator-answer-plugins/notification-wecom/i18n"
   "github.com/segmentfault/pacman/i18n"
   "github.com/segmentfault/pacman/log"
 )
diff --git a/notification-wecom/user_config.go b/notification-wecom/user_config.go
index bb294a8..30562d2 100644
--- a/notification-wecom/user_config.go
+++ b/notification-wecom/user_config.go
@@ -24,7 +24,7 @@ import (
 	"fmt"
 	"sync"
 
-	"github.com/apache/incubator-answer-plugins/notification-wecom/i18n"
+	"github.com/lhui/incubator-answer-plugins/notification-wecom/i18n"
 	"github.com/apache/incubator-answer/plugin"
 	"github.com/segmentfault/pacman/log"
 )


(incubator-answer-plugins) 04/07: Revert "feat: update package name for find plugins in go.mod"

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

linkinstar pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-answer-plugins.git

commit e0fbafb0d3c846d971dc1a5076d449d6332e017a
Author: lihui <me...@lihui.net>
AuthorDate: Fri Jan 3 01:35:32 2025 +0800

    Revert "feat: update package name for find plugins in go.mod"
    
    This reverts commit e78df67c48d905755d349ece38618428027f5607.
---
 notification-wecom/go.mod | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/notification-wecom/go.mod b/notification-wecom/go.mod
index 2465589..6e1292c 100644
--- a/notification-wecom/go.mod
+++ b/notification-wecom/go.mod
@@ -1,4 +1,4 @@
-module github.com/apache/incubator-answer-plugins/notification-wecom
+module github.com/lhui/incubator-answer-plugins/notification-wecom
 
 go 1.23.4
 


(incubator-answer-plugins) 07/07: feat: format code and add notification-wecom to README.md

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

linkinstar pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-answer-plugins.git

commit 8a25e44234f528f3adaa91593caa8c6da623e322
Author: lihui <me...@lihui.net>
AuthorDate: Fri Jan 3 13:48:30 2025 +0800

    feat: format code and add notification-wecom to README.md
---
 README.md                              |  1 +
 notification-wecom/i18n/translation.go | 21 +++++++++++----------
 2 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/README.md b/README.md
index 0b8d4c4..250f0f5 100644
--- a/README.md
+++ b/README.md
@@ -56,6 +56,7 @@ The Notification plugin helps us to send messages to third-party notification sy
 - [x] [Slack](https://github.com/apache/incubator-answer-plugins/tree/main/notification-slack)
 - [x] [Lark](https://github.com/apache/incubator-answer-plugins/tree/main/notification-lark)
 - [x] [Ding talk](https://github.com/apache/incubator-answer-plugins/tree/main/notification-dingtalk)
+- [x] [WeCom](https://github.com/apache/incubator-answer-plugins/tree/main/notification-wecom)
 
 ### Route
 
diff --git a/notification-wecom/i18n/translation.go b/notification-wecom/i18n/translation.go
index 80db37e..d0ce534 100644
--- a/notification-wecom/i18n/translation.go
+++ b/notification-wecom/i18n/translation.go
@@ -16,6 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+
 package i18n
 
 const (
@@ -39,14 +40,14 @@ const (
 	UserConfigNewQuestionsForFollowingTagsLabel       = "plugin.wecom_notification.backend.user_config.new_questions_for_following_tags.label"
 	UserConfigNewQuestionsForFollowingTagsDescription = "plugin.wecom_notification.backend.user_config.new_questions_for_following_tags.description"
 
-	TplUpdateQuestion          = "plugin.wecom_notification.backend.tpl.update_question.text"
-	TplAnswerTheQuestion       = "plugin.wecom_notification.backend.tpl.answer_the_question.text"
-	TplUpdateAnswer            = "plugin.wecom_notification.backend.tpl.update_answer.text"
-	TplAcceptAnswer            = "plugin.wecom_notification.backend.tpl.accept_answer.text"
-	TplCommentQuestion         = "plugin.wecom_notification.backend.tpl.comment_question.text"
-	TplCommentAnswer           = "plugin.wecom_notification.backend.tpl.comment_answer.text"
-	TplReplyToYou              = "plugin.wecom_notification.backend.tpl.reply_to_you.text"
-	TplMentionYou              = "plugin.wecom_notification.backend.tpl.mention_you.text"
-	TplInvitedYouToAnswer      = "plugin.wecom_notification.backend.tpl.invited_you_to_answer.text"
-	TplNewQuestion             = "plugin.wecom_notification.backend.tpl.new_question.text"
+	TplUpdateQuestion     = "plugin.wecom_notification.backend.tpl.update_question.text"
+	TplAnswerTheQuestion  = "plugin.wecom_notification.backend.tpl.answer_the_question.text"
+	TplUpdateAnswer       = "plugin.wecom_notification.backend.tpl.update_answer.text"
+	TplAcceptAnswer       = "plugin.wecom_notification.backend.tpl.accept_answer.text"
+	TplCommentQuestion    = "plugin.wecom_notification.backend.tpl.comment_question.text"
+	TplCommentAnswer      = "plugin.wecom_notification.backend.tpl.comment_answer.text"
+	TplReplyToYou         = "plugin.wecom_notification.backend.tpl.reply_to_you.text"
+	TplMentionYou         = "plugin.wecom_notification.backend.tpl.mention_you.text"
+	TplInvitedYouToAnswer = "plugin.wecom_notification.backend.tpl.invited_you_to_answer.text"
+	TplNewQuestion        = "plugin.wecom_notification.backend.tpl.new_question.text"
 )