diff --git a/README.md b/README.md
index 183e587..80b50c4 100644
--- a/README.md
+++ b/README.md
@@ -11,31 +11,29 @@
![GitHub Repo stars](https://img.shields.io/github/stars/shanghaobo/http-win-notice)
![GitHub all releases](https://img.shields.io/github/downloads/shanghaobo/http-win-notice/total)
![GitHub last commit (branch)](https://img.shields.io/github/last-commit/shanghaobo/http-win-notice/master)
-
-
-> 一个运行在Windows本机的服务,监听http接口请求触发windows消息通知
+
+> 一个运行在 Windows 本机的服务,监听 http 接口请求触发 windows 消息通知
## 功能
-- [x] http接口请求
+- [x] http 接口请求
- [x] Windows 消息弹窗
- [x] 历史消息记录
- [x] 开机启动
- [x] 托盘控制
- [x] 端口配置
-- [x] frp内网穿透集成
+- [x] frp 内网穿透集成
- [x] 公网调用
-
+- [x] 自定义通知按钮
## 架构
![](images/jiagou.png)
-- 内网环境下,局域网内可通过内网ip+端口调用,如`http://192.168.124.11:19000`
-- 公网环境可选择开启,配置开启后可通过公网调用,如`http://123.123.1.2:19001`,此时公网调用请求会转发到本机的web服务,从而触发消息通知。详情查看[公网调用](#公网调用)
-
+- 内网环境下,局域网内可通过内网 ip+端口调用,如`http://192.168.124.11:19000`
+- 公网环境可选择开启,配置开启后可通过公网调用,如`http://123.123.1.2:19001`,此时公网调用请求会转发到本机的 web 服务,从而触发消息通知。详情查看[公网调用](#公网调用)
## 使用
@@ -43,22 +41,26 @@
2. 解压后双击`http-win-notice.exe`启动
3. 右击托盘图标勾选开机启动
4. 通知调用
- - 方式1
-
+
+ - 方式 1
+
浏览器输入链接`http://127.0.0.1:19000/api/toast?msg=哈喽,我是新的消息通知`
- - 方式2 (python调用示例)
-
+
+ - 方式 2 (python 调用示例)
+
```python
import requests
-
+
title = "自定义通知标题"
msg = "我是测试消息通知啦啦啦啦啦"
res = requests.get(f"http://127.0.0.1:19000/api/toast?msg={msg}&title={title}")
print(res.json())
- ```
+ ```
+
详情可见 [接口文档](#接口文档)
+
5. 可右击托盘图标,点击配置文件修改端口号
-6. 可打开web界面查看历史消息记录
+6. 可打开 web 界面查看历史消息记录
## 效果
@@ -66,8 +68,7 @@
![](images/demo3.png)
-
-- 调用http消息通知接口
+- 调用 http 消息通知接口
![](images/demo2.png)
@@ -83,29 +84,32 @@
- 请求方式:`GET`
- 请求参数
-| 参数名 | 默认值 | 解释 |
-|----------|----------|--------------------------------|
-| title | 消息通知 | 通知标题 |
-| msg | 这是一条测试消息 | 通知内容 | |
-| remark | 空 | 备注 | |
-| icon | 0 | 图标索引,配合配置文件使用 |
-| duration | short | 持续时长,short-短,大概6秒 long-长,大概25秒 |
-| audio | default | 声音 |
+| 参数名 | 默认值 | 解释 |
+| -------- | ---------------------- | ------------------------------------------------- |
+| title | 消息通知 | 通知标题 |
+| msg | 这是一条测试消息 | 通知内容 |
+| remark | 空 | 备注 |
+| icon | 0 | 图标索引,配合配置文件使用 |
+| duration | short | 持续时长,short-短,大概 6 秒 long-长,大概 25 秒 |
+| audio | default | 声音 |
+| button | (默认展示全部消息按钮) | 自定义按钮(见下方【button 参数说明】) |
其中`icon`需修改配置文件,参考配置如下:
+
```yaml
toast:
icons:
- logo.png
- logo2.png
```
+
此时传`icon=1`表示使用`logo2.png`图标,图标图片需放在`config.yml`同级的`images`目录内
audio的参数可选值如下:
-| 值 | 描述 |
-|----------------|----------------|
+| 值 | 描述 |
+| -------------- | -------------- |
| default | Default |
| im | IM |
| mail | Mail |
@@ -134,53 +138,92 @@ toast:
+
+button参数说明
+button 参数值为 json 格式,结构如下:
+
+| 参数名 | 解释 | 额外说明 |
+| ------ | ---------------- | --------------------------------------- |
+| name | 按钮名称 | |
+| url | 点击按钮跳转链接 | 配置常量'$WEB_PAGE'时为消息记录页面地址 |
+
+使用自定义 button 的示例调用(Python 版)
+
+```python
+import json
+import requests
+
+msg = "测试"
+button = [
+ {
+ "name": "百度",
+ "url": "https://www.baidu.com",
+ },
+ {
+ "name": "全部消息",
+ "url": "$WEB_PAGE",
+ }
+]
+button_text = json.dumps(button)
+
+api = f"http://127.0.0.1:19000/api/toast?msg={msg}&button={button_text}"
+requests.get(api)
+```
+
+
+
## 公网调用
-- 开启公网调用需要有一台带公网ip的服务器
+- 开启公网调用需要有一台带公网 ip 的服务器
- 配置并开启后可实现公网调用接口发送通知
-### 方式1: 使用forward(推荐)
+### 方式 1: 使用 forward(推荐)
#### 服务端配置
+
1. 下载对应的`forward-server`,[下载地址](https://github.com/shanghaobo/http-win-notice/releases/latest)
2. 在同级目录下创建`config.yml`配置文件,参考如下:
- ```yaml
- server_port: 9919
- token: httpwinnotice123456
- api_port: 19009
- api_token: httpforward123456
- ```
- - server_port: 转发服务的socket端口号
+ ```yaml
+ server_port: 9919
+ token: httpwinnotice123456
+ api_port: 19009
+ api_token: httpforward123456
+ ```
+
+ - server_port: 转发服务的 socket 端口号
- token: 安全认证,与客户端配置保持一致,建议修改默认值
- - api_port: 转发api的端口号
- - api_token: 调用转发api的认证token
+ - api_port: 转发 api 的端口号
+ - api_token: 调用转发 api 的认证 token
-3. 启动转发服务(Linux环境)
+3. 启动转发服务(Linux 环境)
- ```bash
+ ```bash
chmod +x ./forward-server
-
- # 直接启动
- ./forward-server
-
- # 后台启动
- nohup ./forward-server >> nohup.out &
- ```
+
+ # 直接启动
+ ./forward-server
+
+ # 后台启动
+ nohup ./forward-server >> nohup.out &
+ ```
+
#### 客户端配置
+
1. 右击托盘图标选择`配置文件`,修改配置文件内`forward`相关内容并保存。参考配置如下:
- ```yaml
- forward:
- enable: 1
- server_addr: 123.123.1.1
- server_port: 9919
- token: httpwinnotice123456
- ```
+ ```yaml
+ forward:
+ enable: 1
+ server_addr: 123.123.1.1
+ server_port: 9919
+ token: httpwinnotice123456
+ ```
+
- enable: 0-关闭 1-开启转发服务
- - server_addr: 转发服务器ip
+ - server_addr: 转发服务器 ip
- server_port: 转发服务端口号
- - token: 与服务器配置的token保持一致,建议修改默认值
+ - token: 与服务器配置的 token 保持一致,建议修改默认值
配置好后重启程序
@@ -188,7 +231,7 @@ toast:
按示例的配置,浏览器请求`http://123.123.1.1:19009?msg=哈喽`,若本机出现弹窗证明成功
-### 方式2: 使用frp内网穿透
+### 方式 2: 使用 frp 内网穿透
#### 服务端配置
@@ -196,11 +239,13 @@ toast:
2. 修改`frps.ini`配置文件,配置参考:
- frps.ini
+
```ini
[common]
bind_port = 7000
token = httpwinnotice123456
```
+
3. 启动服务端:
```bash
@@ -212,22 +257,22 @@ chmod +x ./frps
1. 右击托盘图标选择配置目录,下载`frpc.exe`文件并移动到打开的配置目录内。[下载地址](https://github.com/fatedier/frp/releases/latest)
2. 右击托盘图标选择配置文件,修改配置文件中`frp`相关内容并保存。参考配置如下:
-
+
```yaml
frp:
- enable: 1
- server_addr: 123.123.1.2
- server_port: 7000
- token: httpwinnotice123456
- remote_port: 19001
+ enable: 1
+ server_addr: 123.123.1.2
+ server_port: 7000
+ token: httpwinnotice123456
+ remote_port: 19001
```
配置的各项解释如下:
-- enable: 1-开启frp,0-关闭frp
-- server_addr: 部署frps服务器的公网ip
-- server_port: frps服务端口号
-- token: 与服务器端配置token一致,建议将默认值修改
+- enable: 1-开启 frp,0-关闭 frp
+- server_addr: 部署 frps 服务器的公网 ip
+- server_port: frps 服务端口号
+- token: 与服务器端配置 token 一致,建议将默认值修改
- remote_port: 转发的远端端口号
注意服务器防火墙放开对应的端口号,以上示例配置在公网调用时使用`http://123.123.1.2:19001/api/toast`
@@ -236,8 +281,7 @@ frp:
#### 测试
-浏览器打开`http://123.123.1.2:19001/api/toast?msg=哈喽` 如果windows通知出现证明开启成功(ip和端口号替换为自己的)
-
+浏览器打开`http://123.123.1.2:19001/api/toast?msg=哈喽` 如果 windows 通知出现证明开启成功(ip 和端口号替换为自己的)
## 其他
@@ -260,4 +304,4 @@ frp:
server_port: 7000
token: httpwinnotice123456
remote_port: 19001
-```
\ No newline at end of file
+```
diff --git a/api/api.go b/api/api.go
index 24bee4b..e8a4e45 100644
--- a/api/api.go
+++ b/api/api.go
@@ -1,6 +1,7 @@
package api
import (
+ "encoding/json"
"github.com/gin-gonic/gin"
"http-win-notice/model"
"http-win-notice/utils/constant"
@@ -9,15 +10,34 @@ import (
"strconv"
)
+type Button struct {
+ Name string `json:"name"`
+ Url string `json:"url"`
+}
+
func ToastApi(c *gin.Context) {
msg := c.DefaultQuery("msg", constant.DefaultMsg)
title := c.DefaultQuery("title", constant.DefaultTitle)
icon := c.DefaultQuery("icon", constant.DefaultIcon)
duration := c.DefaultQuery("duration", string(constant.DefaultDuration))
audio := c.DefaultQuery("audio", string(constant.DefaultAudio))
+ button := c.DefaultQuery("button", "")
remark := c.Query("remark")
+ var buttonData []Button
+ var actions []notice.Action
+ err := json.Unmarshal([]byte(button), &buttonData)
+ if err == nil {
+ for _, bt := range buttonData {
+ action := notice.Action{
+ Type: "protocol",
+ Label: bt.Name,
+ Arguments: bt.Url,
+ }
+ actions = append(actions, action)
+ }
+ }
data := model.Msg{
Title: title,
Msg: msg,
@@ -31,7 +51,7 @@ func ToastApi(c *gin.Context) {
return
}
go func() {
- err := notice.Notice(msg, title, icon, duration, audio)
+ err := notice.Notice(msg, title, icon, duration, audio, actions)
if err != nil {
model.UpdateMsgStatus(data.ID, 9)
} else {
diff --git a/utils/notice/notice.go b/utils/notice/notice.go
index c51f098..7b21eaa 100644
--- a/utils/notice/notice.go
+++ b/utils/notice/notice.go
@@ -8,6 +8,8 @@ import (
"strconv"
)
+type Action = toast.Action
+
func notificationSetAttr(n *toast.Notification, duration string, audio string) {
switch duration {
case "long":
@@ -77,7 +79,7 @@ func notificationSetAttr(n *toast.Notification, duration string, audio string) {
}
-func Notice(msg, title, icon, duration, audio string) error {
+func Notice(msg, title, icon, duration, audio string, actions []toast.Action) error {
iconIndex, err := strconv.Atoi(icon)
if err != nil {
iconIndex = 0
@@ -89,14 +91,22 @@ func Notice(msg, title, icon, duration, audio string) error {
} else {
iconPath = path.Join(setting.ImagesDir, setting.Config.Toast.Icons[iconIndex])
}
+ for i := range actions {
+ if actions[i].Arguments == "$WEB_PAGE" {
+ actions[i].Arguments = setting.HomeUrl()
+ }
+ }
+ if len(actions) == 0 {
+ actions = []Action{
+ {"protocol", "查看", setting.HomeUrl()},
+ }
+ }
notification := toast.Notification{
AppID: constant.AppID,
Title: title,
Message: msg,
Icon: iconPath,
- Actions: []toast.Action{
- {"protocol", "查看", setting.HomeUrl()},
- },
+ Actions: actions,
}
notificationSetAttr(¬ification, duration, audio)
//fmt.Println("n=", notification)