Project Icon

Message-Push-Nest

多渠道消息推送整合开源平台

Message-Push-Nest是一个开源的消息推送整合平台,支持邮件、钉钉和企业微信等多种渠道。该平台提供统一的API接口,简化多渠道消息推送的管理和定制。开发者可以自由组合不同消息渠道,实现一键推送到多个平台。项目支持Docker部署,具备自定义定时消息发送和数据统计展示等功能,适用于需要集中管理多种消息通知方式的开发团队。

Message Nest 🕊️

Message Nest 是一个灵活而强大的消息推送整合平台,旨在简化并自定义多种消息通知方式。

项目名叫信息巢,意思是一个拥有各种渠道信息方式的集合站点。

如果你有很多消息推送方式,每次都需要调用各种接口去发送消息到各个渠道,或者不同的项目你都需要复制同样的发消息代码,这个项目可以帮你管理各种消息方式,并提供统一的发送api接入。你可以自由组合各种消息渠道,一个api推送到各种渠道,帮你省去接入的繁琐步骤。

演示站点(演示站点的服务器比较烂,见谅) demo

特色 ✨

  • 🔄 整合性: 提供了多种消息推送方式,包括邮件、钉钉、企业微信等,方便你集中管理和定制通知。
  • 🎨 自定义性: 可以根据需求定制消息推送策略,满足不同场景的个性化需求。
  • 🛠 开放性: 易于扩展和集成新的消息通知服务,以适应未来的变化。

进度 🔨

项目还在不断更新中,欢迎大家提出各种建议。

关于日志,考虑到目前多数服务以收集控制台输出为主,暂时不支持写出日志文件。

2024.04.29

  • 支持sqlite部署,支持不同版本mysql

2024.04.11

  • 支持自定义的定时消息发送

2024.03.05

  • 支持微信测试公众号模板消息发送

2024.01.28

  • 支持docker部署,从环境变量启动服务

2024.01.24

  • 支持数据统计展示

2024.01.20

  • 添加日志查看自动刷新

2024.01.07

  • 支持站点信息自定义

2024.01.03

  • 支持企业微信

  • 单应用打包,直接运行,不用部署前端页面

  • 支持邮件发送

  • 用户密码设置

  • 支持用户定时任务清理,更新定时时间

  • 查看定时清理日志

  • 单应用的html浏览器自动缓存

  • gin的日志使用logrus

  • 支持异步发送

  • 支持邮件发送

  • 支持钉钉

  • 支持自定义的webhook消息发送

  • 企业微信

  • ....

项目来由 💡

自己常常写一些脚本需要消息推送,经常需要接入不同的消息发送,很不方便,于是就有了这个项目。

效果图 📺

image

使用方法 🚀

1. 直接运行最新的release打包的可执行文件(推荐,不用部署前端页面🍀🍀)
  1. 下载最新的系统版本对应的release, 解压
  2. 新建一个数据库
  3. 重命名conf/app.example.ini为conf/app.ini
  4. 修改app.ini对应的配置
  5. 将配置中EmbedHtml = disable, 进行注释,以单应用方式运行,完整配置参考如下:
[app]
JwtSecret = message-nest
LogLevel = INFO

[server]
RunMode = release
HttpPort = 8000
ReadTimeout = 60
WriteTimeout = 60
; 注释EmbedHtml,启用单应用模式
; EmbedHtml = disable

[database]
; 关闭SQL打印
; SqlDebug = enable

; Type = sqlite
Type = mysql
User = root
Password = Aa123456
Host = vm.server
Port = 3308
Name = yourDbName
TablePrefix = message_

  1. 启动项目会自动创建表和账号
# INFO日志级别启动回出现如下日志

[2024-01-13 13:40:09.075]  INFO [migrate.go:70 Setup] [Init Data]: Migrate table: message_auth
[2024-01-13 13:40:11.778]  INFO [migrate.go:70 Setup] [Init Data]: Migrate table: message_send_tasks
[2024-01-13 13:40:16.518]  INFO [migrate.go:70 Setup] [Init Data]: Migrate table: message_send_ways
[2024-01-13 13:40:23.300]  INFO [migrate.go:70 Setup] [Init Data]: Migrate table: message_send_tasks_logs
[2024-01-13 13:40:28.715]  INFO [migrate.go:70 Setup] [Init Data]: Migrate table: message_send_tasks_ins
[2024-01-13 13:40:39.538]  INFO [migrate.go:70 Setup] [Init Data]: Migrate table: message_settings
[2024-01-13 13:40:46.299]  INFO [migrate.go:74 Setup] [Init Data]: Init Account data...
[2024-01-13 13:40:46.751]  INFO [migrate.go:77 Setup] [Init Data]: All table data init done.

  1. 启动项目,访问8000端口,初始账号为admin,密码为123456
2. 前后端分离部署(待更新)
3. 开发调试运行
  1. 重命名conf/app.example.ini为conf/app.ini, 关键配置如下
[app]
JwtSecret = message-nest
LogLevel = INFO

[server]
; RunMode务必设置成debug,会自动添加跨域
RunMode = debug
HttpPort = 8000
ReadTimeout = 60
WriteTimeout = 60
; 取消EmbedHtml的注释(启用前后端分离),然后到web目录下面,npm run dev启动前端页面
EmbedHtml = disable

[database]
; 开启SQL打印
SqlDebug = enable

; Type = sqlite
Type = mysql
User = root
Password = Aa123456
Host = vm.server
Port = 3308
Name = yourDbName
TablePrefix = message_

  1. 运行main.go,服务启动后会运行在8000端口
go mod tidy
go run main.go
  1. 启动前端页面,页面启动后会提示访问url,一般是http://127.0.0.1:5173
cd web
npm i
npm run dev
  1. 访问http://127.0.0.1:5173,进行调试开发,接口会自动转发到go服务http://localhost:8000
4. docker/docker-compose部署(推荐指数🍀🍀🍀🍀🍀)
docker挂载app.ini部署
  1. 新建一个数据库,准备一个conf文件夹
  2. 新增conf/app.ini
  3. 修改app.ini对应的配置
  4. 将配置中EmbedHtml = disable, 进行注释,以单应用方式运行,完整配置参考如下:
[app]
JwtSecret = message-nest
LogLevel = INFO

[server]
RunMode = release
; docker模式下端口配置文件中只能为8000
HttpPort = 8000
ReadTimeout = 60
WriteTimeout = 60
; 注释EmbedHtml,启用单应用模式
; EmbedHtml = disable

[database]
; 关闭SQL打印
; SqlDebug = enable

; Type = sqlite
Type = mysql
User = root
Password = Aa123456
Host = vm.server
Port = 3308
Name = yourDbName
TablePrefix = message_

  1. 使用命令启动,端口使用-p自定义
docker pull engigu/message-nest:latest
# 测试运行
docker run --rm -ti \
  -p 8000:8000 \
  -v /your/path/conf:/app/conf \
  engigu/message-nest:latest 
  
# 正式运行
docker run -d \
  -p 8000:8000 \
  -v /your/path/conf:/app/conf \
  engigu/message-nest:latest 
  1. 启动项目,访问8000端口,初始账号为admin,密码为123456
使用docker-compose挂载app.ini部署
  1. 准备app.ini,文件内容如上docker部署
  2. 准备docker-compose.yml,内容如下:
version: "3.7"
services:

  message-nest:
    image: engigu/message-nest:latest
    container_name: message-nest
    restart: always
    volumes:
      - ./conf:/app/conf
    ports:
      - "8000:8000"
  1. 文件目录结构
.
├── conf
│   └── app.ini
├── docker-compose.yml

  1. 启动项目
# 测试运行
docker-compose up
# 正式运行
docker-compose up -d
使用docker/docker-compose环境变量部署(推荐指数🍀🍀🍀🍀🍀🍀🍀🍀🍀)

环境变量介绍

变量说明
JWT_SECRETjwt秘钥,可选,默认为message-nest
LOG_LEVEL日志等级,可选,默认为INFO,DEBUG/INFO/ERROR
RUN_MODE运行模式,可选,默认release,为debug将自动添加跨域
DB_TYPE数据库类型,sqlite/mysql。默认为sqlite,存储路径为conf/database.db
MYSQL_HOSTmysql-host,DB_TYPE=mysql必填
MYSQL_PORTmysql端口,DB_TYPE=mysql必填
MYSQL_USERmysql用户名,DB_TYPE=mysql必填
MYSQL_PASSWORDmysql数据库密码,DB_TYPE=mysql必填
MYSQL_DBmysql数据库名字,DB_TYPE=mysql必填
MYSQL_TABLE_PREFIXmysql数据表前缀,DB_TYPE=mysql必填
SQL_DEBUG是否打印SQL,可选,默认关,设置enable为开启

docker运行


# 正式运行(mysql)
docker run -d  \
  -p 8000:8000 \
  -e MYSQL_HOST=192.168.64.133  \
  -e MYSQL_PORT=3308 \
  -e MYSQL_USER=root \
  -e MYSQL_PASSWORD=Aa123456 \
  -e MYSQL_DB=test_11 \
  -e MYSQL_TABLE_PREFIX=message_ \
  --name message-nest  \
  engigu/message-nest:latest 

# 正式运行(sqlite)
docker run -d  \
  -p 8000:8000 \
  -v you/path/database.db=conf/database.db  \
  --name message-nest  \
  engigu/message-nest:latest 

docker-compose运行(mysql)

version: "3.7"
services:

  message-nest:
    image: engigu/message-nest:latest
    container_name: message-nest
    restart: always
    ports:
      - "8000:8000"
    environment:
      - MYSQL_HOST=192.168.64.133
      - MYSQL_PORT=3308
      - MYSQL_USER=root
      - MYSQL_PASSWORD=Aa123456
      - MYSQL_DB=test_11
      - MYSQL_TABLE_PREFIX=message_

docker-compose运行(sqlite)

version: "3.7"
services:

  message-nest:
    image: engigu/message-nest:latest
    container_name: message-nest
    restart: always
    ports:
      - "8000:8000"
    volumes:
      - you/path/database.db:conf/database.db
# 正式运行
docker-compose -up -d

关于EmbedHtml配置的说明

这个配置可以理解为单应用模式(或者前后端分离)的开关

  1. 打开这个配置,表示前后端分离,表示go服务启动的时候只会有api服务,需要到web目录下,npm run dev启动前端项目。然后访问前端项目提示的端口服务,一般是127.0.0.1:5173。 或者使用npm run build,用Nginx部署前端。

  2. 注释这个配置,表示单应用,启动go服务,会把web/dist目录下文件作为前端静态资源。 如果目录下没有静态资源文件,需要到web目录下,npm run build构建生成。

两种方式各有优缺点,综合考虑下来,推荐直接使用release的打包执行文件(或者docker环境变量进行部署),其中已经内置了页面静态资源,只用运行一个服务。

完整配置说明 ⚙️

点击展开
[app]
JwtSecret = message-nest
; 暂时无用
RuntimeRootPath = runtime/
LogLevel = INFO

[server]
; debug or release
; debug模式下会自动添加跨域headers
RunMode = release
HttpPort = 8000
ReadTimeout = 60
WriteTimeout = 60
; use embed html static file
; 是否使用embed打包的静态资源
; 如果运行release打包后的应用,请注释这个设置。
; 如果取消这个注释,只会单独运行api服务,前端页面需要到web目录手动npm run dev, 运行前端服务
; EmbedHtml = disable   

[database]
; 配置使用sqlite
;Type = sqlite

; 配置使用mysql
Type = mysql
User = root
Password = password
Host = 123.1.1.1
Name = db_name
Port = 3306

; 其他配置
; 表前缀
TablePrefix = message_
; 是否打开sql打印
; SqlDebug = enable

客户端调用示例 💻️

CURL
curl -X POST --location 'http://127.0.0.1:5173/api/v1/message/send' \
        --header 'Content-Type: application/json' \
        --data '{
    "task_id": "T-JiXpO8EO7u",
    "title": "message title",
    "text": "Hello World!"
}'
Python
import requests

headers = {
    'Content-Type': 'application/json',
}
json_data = {
    "task_id": "T-JiXpO8EO7u",
    "title": "message title",
    "text": "Hello World!"
}
response = requests.post('http://127.0.0.1:5173/api/v1/message/send', headers=headers, json=json_data)

print("response:", response.json())

Go
package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
	"strings"
)

func main() {
	client := &http.Client{}
	var data = strings.NewReader(`{
    "task_id": "T-JiXpO8EO7u",
    "title": "message title",
    "text": "Hello World!"
}`)
	req, err := http.NewRequest("POST", "http://127.0.0.1:5173/api/v1/message/send", data)
	if err != nil {
		log.Fatal(err)
	}
	req.Header.Set("Content-Type", "application/json")
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	bodyText, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s\n", bodyText)
}

Java
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpRequest.BodyPublishers;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newBuilder()
    .followRedirects(HttpClient.Redirect.NORMAL)
    .build();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("http://127.0.0.1:5173/api/v1/message/send"))
    .POST(BodyPublishers.ofString("{\n    \"task_id\": \"T-JiXpO8EO7u\",\n    \"title\": \"message title\",\n    \"text\": \"Hello World!\"\n}"))
    .setHeader("Content-Type", "application/json")
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

Node
var request = require('request');

var headers = {
    'Content-Type': 'application/json'
};

var dataString = "{\n    \"task_id\": \"T-JiXpO8EO7u\",\n    \"title\": \"message title\",\n    \"text\": \"Hello World!\"\n}";

var options = {
    url: 'http://127.0.0.1:5173/api/v1/message/send',
    method: 'POST',
    headers: headers,
    body: dataString
};

function callback(error, response, body) {
    if (!error && response.statusCode == 200) {
        console.log(body);
    }
}

request(options, callback);
PHP ```php

$response = curl_exec($ch);

curl_close($ch);

</details>


## 页面操作指引 🎞️

关于消息的添加和发送的整个步骤,是按照顶部菜单栏从右向左的顺序进行操作。

<details>
  <summary>1. 新增发信渠道(添加消息的具体渠道)</summary>

![image](https://yellow-cdn.veclightyear.com/835a84d5/fa78df58-57d0-457a-8c7e-86a324a57939.png)

请参考各个渠道标签页的说明进行设置和保存

请注意,目前的自定义webhook形式只支持`POST`请求,采用的是替换配置的消息体中的占位符`TEXT`来发送消息

</details>

<details>
  <summary>2. 新增发信任务</summary>

![image](https://yellow-cdn.veclightyear.com/835a84d5/3e8ea2ca-7155-4dbc-b203-9af2611a5df6.png)

1. 点击渠道输入框会弹出所有渠道选项
2. 选择一个渠道后会显示渠道的详细信息,并选择一种消息类型,进行暂存成为实例,点击确定才会进行最终的保存
3. 添加任务的页面实际上会分别添加任务,以及任务关联的渠道实例
4. 关于任务与实例的说明:

> 一个任务可以关联创建多个实例
>
> 选择不同的渠道,填写的实例信息也不一样
>
> 一个任务可以绑定一个实例,也可以绑定多个实例,多个实例意味着一个消息可以推送给多个消息渠道

5. 关于实例的消息类型说明:

> 消息的类型大体上可以分为text、html、markdown三种类型。每种渠道消息目前支持的类型有不同的限制。
>
> 在实际发送时,会优先选择发送api中传过来对应类型的消息,如果api中没有对应的类型,会直接取api中的text消息。
>
> api中text消息在发送时必须要传

</details>

<details>
  <summary>3. 消息发送</summary>

![image](https://yellow-cdn.veclightyear.com/835a84d5/82804277-70e9-47e1-b539-019180893be9.png)

请参考各种语言的接口进行调用

</details></details>

## 贡献 🤝

欢迎通过提交问题和提出改进建议来做出贡献。

## 致谢 🙏

该项目汲取了[go-gin-example](https://github.com/eddycjy/go-gin-example)项目的灵感,展示了Go和Gin在实际应用中的强大和多才多艺。

## Star历史 ⭐

[![Star历史图表](https://api.star-history.com/svg?repos=engigu/Message-Push-Nest&type=Date)](https://star-history.com/#engigu/Message-Push-Nest&Date)

## 许可证 📝

[LICENSE](LICENSE)
项目侧边栏1项目侧边栏2
推荐项目
Project Cover

豆包MarsCode

豆包 MarsCode 是一款革命性的编程助手,通过AI技术提供代码补全、单测生成、代码解释和智能问答等功能,支持100+编程语言,与主流编辑器无缝集成,显著提升开发效率和代码质量。

Project Cover

AI写歌

Suno AI是一个革命性的AI音乐创作平台,能在短短30秒内帮助用户创作出一首完整的歌曲。无论是寻找创作灵感还是需要快速制作音乐,Suno AI都是音乐爱好者和专业人士的理想选择。

Project Cover

有言AI

有言平台提供一站式AIGC视频创作解决方案,通过智能技术简化视频制作流程。无论是企业宣传还是个人分享,有言都能帮助用户快速、轻松地制作出专业级别的视频内容。

Project Cover

Kimi

Kimi AI助手提供多语言对话支持,能够阅读和理解用户上传的文件内容,解析网页信息,并结合搜索结果为用户提供详尽的答案。无论是日常咨询还是专业问题,Kimi都能以友好、专业的方式提供帮助。

Project Cover

阿里绘蛙

绘蛙是阿里巴巴集团推出的革命性AI电商营销平台。利用尖端人工智能技术,为商家提供一键生成商品图和营销文案的服务,显著提升内容创作效率和营销效果。适用于淘宝、天猫等电商平台,让商品第一时间被种草。

Project Cover

吐司

探索Tensor.Art平台的独特AI模型,免费访问各种图像生成与AI训练工具,从Stable Diffusion等基础模型开始,轻松实现创新图像生成。体验前沿的AI技术,推动个人和企业的创新发展。

Project Cover

SubCat字幕猫

SubCat字幕猫APP是一款创新的视频播放器,它将改变您观看视频的方式!SubCat结合了先进的人工智能技术,为您提供即时视频字幕翻译,无论是本地视频还是网络流媒体,让您轻松享受各种语言的内容。

Project Cover

美间AI

美间AI创意设计平台,利用前沿AI技术,为设计师和营销人员提供一站式设计解决方案。从智能海报到3D效果图,再到文案生成,美间让创意设计更简单、更高效。

Project Cover

AIWritePaper论文写作

AIWritePaper论文写作是一站式AI论文写作辅助工具,简化了选题、文献检索至论文撰写的整个过程。通过简单设定,平台可快速生成高质量论文大纲和全文,配合图表、参考文献等一应俱全,同时提供开题报告和答辩PPT等增值服务,保障数据安全,有效提升写作效率和论文质量。

投诉举报邮箱: service@vectorlightyear.com
@2024 懂AI·鲁ICP备2024100362号-6·鲁公网安备37021002001498号