Skip to content

Commit 0fa0afa

Browse files
author
lenye
committed
feat: mattermost bot
1 parent 96c575e commit 0fa0afa

File tree

11 files changed

+315
-0
lines changed

11 files changed

+315
-0
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
* 飞书自定义机器人消息
1010
* Slack机器人消息
1111
* Discord机器人消息
12+
* Mattermost机器人消息
1213

1314
### 微信
1415

@@ -61,6 +62,7 @@ https://github.com/lenye/pmsg/tree/main/docs
6162
discord discord
6263
feishu 飞书
6364
help Help about any command
65+
mattermost mattermost
6466
slack slack
6567
weixin 微信:公众号、小程序
6668
workweixin 企业微信

cmd/mattermost/mattermost.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright 2022-2025 The pmsg Authors. All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package mattermost
16+
17+
import (
18+
"github.com/spf13/cobra"
19+
20+
"github.com/lenye/pmsg/cmd/variable"
21+
"github.com/lenye/pmsg/flags"
22+
)
23+
24+
// Cmd mattermost
25+
var Cmd = &cobra.Command{
26+
Use: "mattermost",
27+
Aliases: []string{"mm"},
28+
Short: "mattermost",
29+
}
30+
31+
func init() {
32+
Cmd.PersistentFlags().StringVarP(&variable.UserAgent, flags.UserAgent, "a", "", "http user agent")
33+
34+
Cmd.AddCommand(botCmd)
35+
}

cmd/mattermost/mattermost_bot.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// Copyright 2022-2025 The pmsg Authors. All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package mattermost
16+
17+
import (
18+
"fmt"
19+
20+
"github.com/spf13/cobra"
21+
22+
"github.com/lenye/pmsg/cmd/variable"
23+
"github.com/lenye/pmsg/flags"
24+
"github.com/lenye/pmsg/im"
25+
"github.com/lenye/pmsg/im/mattermost/bot"
26+
)
27+
28+
// botCmd mattermost bot
29+
var botCmd = &cobra.Command{
30+
Use: "bot",
31+
Short: "publish mattermost bot message",
32+
Args: cobra.ExactArgs(1),
33+
Run: func(cmd *cobra.Command, args []string) {
34+
arg := bot.CmdSendParams{
35+
UserAgent: variable.UserAgent,
36+
URL: variable.Url,
37+
}
38+
39+
if variable.IsRaw {
40+
arg.Data = args[0]
41+
} else {
42+
var err error
43+
arg.Data, err = im.StrRaw2Interpreted(args[0])
44+
if err != nil {
45+
fmt.Println(err)
46+
return
47+
}
48+
}
49+
50+
if err := bot.CmdSend(&arg); err != nil {
51+
fmt.Println(err)
52+
}
53+
},
54+
Example: "pmsg mattermost bot --Url webhook_url 'Hello, World!'",
55+
}
56+
57+
func init() {
58+
botCmd.Flags().SortFlags = false
59+
botCmd.Flags().StringVar(&variable.Url, flags.Url, "", "mattermost webhook Url")
60+
_ = botCmd.MarkFlagRequired(flags.Url)
61+
62+
botCmd.Flags().BoolVar(&variable.IsRaw, flags.IsRaw, false, "消息内容是原始字符串字面值(不转义处理)")
63+
}

cmd/root.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"github.com/lenye/pmsg/cmd/dingtalk"
2424
"github.com/lenye/pmsg/cmd/discord"
2525
"github.com/lenye/pmsg/cmd/feishu"
26+
"github.com/lenye/pmsg/cmd/mattermost"
2627
"github.com/lenye/pmsg/cmd/slack"
2728
"github.com/lenye/pmsg/cmd/weixin"
2829
"github.com/lenye/pmsg/cmd/workweixin"
@@ -69,4 +70,5 @@ func init() {
6970
rootCmd.AddCommand(feishu.Cmd)
7071
rootCmd.AddCommand(slack.Cmd)
7172
rootCmd.AddCommand(discord.Cmd)
73+
rootCmd.AddCommand(mattermost.Cmd)
7274
}

docs/install.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
discord discord
2626
feishu 飞书
2727
help Help about any command
28+
mattermost mattermost
2829
slack slack
2930
weixin 微信:公众号、小程序
3031
workweixin 企业微信

docs/mattermost/bot_message.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
### 推送Mattermost机器人消息
2+
3+
命令参数说明
4+
5+
```text
6+
$ pmsg mattermost bot -h
7+
8+
-a, --user_agent string http user agent
9+
10+
--url string mattermost webhook url
11+
--raw 消息内容是原始字符串字面值,没有任何转义处理
12+
13+
args 参数:消息内容,默认是解释字符串,支持“\”转义
14+
```
15+
16+
样例
17+
18+
linux
19+
20+
```shell
21+
$ pmsg mattermost bot --url webhook_url 'Hello, World!'
22+
23+
ok
24+
```
25+
26+
官方开发文档 [推送mattermost机器人消息](https://developers.mattermost.com/integrate/webhooks/incoming/)

docs/readme.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@
3131

3232
* [机器人消息](discord/bot_message.md)
3333

34+
### Mattermost
35+
36+
* [机器人消息](mattermost/bot_message.md)
37+
3438
## 微信
3539

3640
* [获取接口调用凭证(公众号、小程序)](weixin/access_token.md)access_token

im/mattermost/bot/message.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// Copyright 2022-2025 The pmsg Authors. All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package bot
16+
17+
import (
18+
"github.com/lenye/pmsg/im/mattermost/client"
19+
)
20+
21+
// Message Mattermost机器人消息
22+
type Message struct {
23+
Text string `json:"text"`
24+
Username string `json:"username,omitempty"`
25+
IconEmoji string `json:"icon_emoji,omitempty"`
26+
Channel string `json:"channel,omitempty"`
27+
Attachments []Attachment `json:"attachments,omitempty"`
28+
}
29+
30+
type Attachment struct {
31+
Text string `json:"text,omitempty"`
32+
Fallback string `json:"fallback,omitempty"`
33+
Pretext string `json:"pretext,omitempty"`
34+
35+
Color string `json:"color,omitempty"`
36+
37+
AuthorName string `json:"author_name,omitempty"`
38+
AuthorLink string `json:"author_link,omitempty"`
39+
AuthorIcon string `json:"author_icon,omitempty"`
40+
41+
Title string `json:"title,omitempty"`
42+
TitleLink string `json:"title_link,omitempty"`
43+
44+
Fields []Field `json:"fields,omitempty"`
45+
46+
ImageURL string `json:"image_url,omitempty"`
47+
ThumbURL string `json:"thumb_url,omitempty"`
48+
}
49+
50+
type Field struct {
51+
Title string `json:"title,omitempty"`
52+
Value string `json:"value,omitempty"`
53+
Short bool `json:"short,omitempty"`
54+
}
55+
56+
// Send 发送消息
57+
func Send(webhookUrl string, msg *Message) error {
58+
_, err := client.PostJSON(webhookUrl, msg)
59+
if err != nil {
60+
return err
61+
}
62+
return nil
63+
}

im/mattermost/bot/message_cmd.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright 2022-2025 The pmsg Authors. All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package bot
16+
17+
import (
18+
"fmt"
19+
20+
"github.com/lenye/pmsg/httpclient"
21+
"github.com/lenye/pmsg/im/mattermost"
22+
)
23+
24+
type CmdSendParams struct {
25+
UserAgent string
26+
URL string
27+
Data string
28+
}
29+
30+
// CmdSend 发送消息
31+
func CmdSend(arg *CmdSendParams) error {
32+
33+
httpclient.SetUserAgent(arg.UserAgent)
34+
35+
msg := Message{
36+
Text: arg.Data,
37+
}
38+
39+
if err := Send(arg.URL, &msg); err != nil {
40+
return fmt.Errorf("%w, %w", mattermost.ErrRequest, err)
41+
}
42+
fmt.Println(mattermost.MessageOK)
43+
44+
return nil
45+
}

im/mattermost/client/client.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright 2022-2025 The pmsg Authors. All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package client
16+
17+
import (
18+
"fmt"
19+
"io"
20+
"net/http"
21+
22+
"github.com/lenye/pmsg/httpclient"
23+
"github.com/lenye/pmsg/im"
24+
)
25+
26+
func PostJSON(url string, reqBody any) (http.Header, error) {
27+
body, err := im.JsonEncode(reqBody)
28+
if err != nil {
29+
return nil, err
30+
}
31+
resp, err := httpclient.Post(url, httpclient.HdrValApplicationJson, body)
32+
if err != nil {
33+
return nil, err
34+
}
35+
defer func(Body io.ReadCloser) {
36+
_ = Body.Close()
37+
}(resp.Body)
38+
39+
if resp.StatusCode == http.StatusTooManyRequests {
40+
return resp.Header, fmt.Errorf("rate limit exceeded, retry after %s second", resp.Header.Get("Retry-After"))
41+
}
42+
43+
// Slack seems to send an HTML body along with 5xx error codes. Don't parse it.
44+
if resp.StatusCode != http.StatusOK {
45+
return resp.Header, fmt.Errorf("invalid http.response.status: %s", resp.Status)
46+
}
47+
48+
return resp.Header, nil
49+
}

0 commit comments

Comments
 (0)