สร้างบริการพุชข้อความของคุณเอง รองรับวิธีพุชข้อความได้หลากหลาย รองรับ Markdown ไฟล์ปฏิบัติการเพียงไฟล์เดียว พร้อมใช้งานทันที
ดาวน์โหลดโปรแกรม · บทช่วยสอนการใช้งาน · บทช่วยสอนการใช้งาน · คำติชม · การสาธิตออนไลน์
หมายเหตุ : ไซต์การปรับใช้อย่างเป็นทางการ https://msgpusher.com ขณะนี้ออนไลน์และเปิดให้ลงทะเบียนแล้ว ยินดีต้อนรับใช้งาน หากคุณได้รับการตอบรับเชิงบวก คุณอาจพิจารณาเปลี่ยนไปใช้เซิร์ฟเวอร์ที่มีเวลาแฝงต่ำกว่าในอนาคต
คำเตือน : การอัปเกรดจาก
v0.3
เป็นv0.4
จำเป็นต้องมีการย้ายฐานข้อมูลด้วยตนเอง สำหรับรายละเอียด โปรดดูการย้ายฐานข้อมูล
การปรับใช้: docker run -d --restart always --name message-pusher -p 3000:3000 -e TZ=Asia/Shanghai -v /home/ubuntu/data/message-pusher:/data justsong/message-pusher
หากไม่สามารถดึงได้ โปรดแทนที่ justsong/message-pusher
ด้วย ghcr.io/songquanpeng/message-pusher
อัปเดต: docker run --rm -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower -cR
หมายเลขพอร์ตที่เปิดคือ 3000 จากนั้นใช้ Nginx เพื่อกำหนดค่าชื่อโดเมน การสร้างแบบย้อนกลับ และใบรับรอง SSL โปรดดูรายละเอียดในบทช่วยสอนการใช้งานโดยละเอียด
ข้อมูลจะถูกบันทึกไว้ในไดเร็กทอรี /home/ubuntu/data/message-pusher
ของเครื่องโฮสต์ (มีไฟล์ฐานข้อมูล SQLite เพียงไฟล์เดียว) โปรดตรวจสอบให้แน่ใจว่ามีไดเร็กทอรีอยู่และมีสิทธิ์ในการเขียน หรือเปลี่ยนเป็นไดเร็กทอรีที่เหมาะสม .
การกำหนดค่าอ้างอิงของ Nginx:
server{
server_name msgpusher.com; # 请根据实际情况修改你的域名
location / {
client_max_body_size 64m;
proxy_http_version 1.1;
proxy_pass http://localhost:3000; # 请根据实际情况修改你的端口
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_cache_bypass $http_upgrade;
proxy_set_header Accept-Encoding gzip;
}
}
จากนั้นใช้ Certbot ของ Let's Encrypt เพื่อกำหนดค่า HTTPS:
# Ubuntu 安装 certbot:
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
# 生成证书 & 修改 Nginx 配置
sudo certbot --nginx
# 根据指示进行操作
# 重启 Nginx
sudo service nginx restart
git clone https://github.com/songquanpeng/message-pusher.git
cd message-pusher/web
npm install
npm run build
cd ..
go mod download
go build -ldflags " -s -w " -o message-pusher
chmod u+x message-pusher
./message-pusher --port 3000 --log-dir ./logs
root
และรหัสผ่านคือ 123456
หากบริการจำเป็นต้องทำงานเป็นเวลานาน การเริ่มต้นใช้งานเพียงอย่างเดียวยังไม่เพียงพอ
หากคุณต้องการใช้ฟังก์ชันพุชไคลเอ็นต์ WebSocket ต้องตั้ง proxy_read_timeout
และ proxy_send_timeout
ในไฟล์การกำหนดค่า Nginx มากกว่า 1 นาที
การตั้งค่าที่แนะนำ:
proxy_read_timeout 300s;
proxy_send_timeout 300s;
ตัวระบบจำเป็นต้องดาวน์โหลดไฟล์ปฏิบัติการเพื่อเริ่มใช้งานเท่านั้น โดยไม่มีการอ้างอิงอื่นใด
คุณสามารถกำหนดค่าได้โดยการตั้งค่าตัวแปรสภาพแวดล้อมหรือพารามิเตอร์บรรทัดคำสั่ง
หลังจากที่ระบบเริ่มทำงาน ให้ใช้ผู้ใช้ root
เพื่อล็อกอินเข้าสู่ระบบและทำการกำหนดค่าเพิ่มเติม รหัสผ่านดีฟอลต์คือ 123456
REDIS_CONN_STRING
: หลังจากการตั้งค่า Redis จะถูกใช้เป็นที่เก็บข้อมูลสำหรับการจำกัดความถี่คำขอแทนที่จะใช้ที่เก็บข้อมูลหน่วยความจำREDIS_CONN_STRING=redis://default:redispw@localhost:49153
SESSION_SECRET
: หลังจากตั้งค่าแล้ว คีย์เซสชันคงที่จะถูกใช้ เพื่อให้คุกกี้ของผู้ใช้ที่เข้าสู่ระบบยังคงใช้งานได้หลังจากที่ระบบรีสตาร์ทแล้วSESSION_SECRET=random_string
SQL_DSN
: หลังจากตั้งค่าแล้ว ฐานข้อมูลที่ระบุจะถูกใช้แทน SQLiteSQL_DSN=root:123456@tcp(localhost:3306)/message-pusher
หมายเหตุ: เมื่อปรับใช้กับ Docker โปรดใช้ -e key=value
เพื่อตั้งค่าตัวแปรสภาพแวดล้อม
ตัวอย่าง: docker run -e SESSION_SECRET=random_string ...
--port <port_number>
: ระบุหมายเลขพอร์ตที่เซิร์ฟเวอร์รับฟัง ค่าเริ่มต้นคือ 3000
--port 3000
--log-dir <log_dir>
: ระบุโฟลเดอร์บันทึก หากไม่ได้ตั้งค่า บันทึกจะไม่ถูกบันทึก--log-dir ./logs
--version
: พิมพ์หมายเลขเวอร์ชันของระบบแล้วออก允许新用户注册
更新用户信息
เพื่อเปลี่ยนชื่อผู้ใช้และรหัสผ่านเริ่มต้น绑定邮箱地址
เพื่อผูกอีเมลเพื่อเปิดใช้งานการพุชข้อความอีเมล默认推送方式
เริ่มต้นคือการพุชผ่านอีเมล推送token
สำหรับการตรวจสอบสิทธิ์การเรียก API แบบพุช ปล่อยว่างไว้หากไม่จำเป็น测试
ที่เกี่ยวข้องเพื่อทดสอบว่าการกำหนดค่าสำเร็จหรือไม่https://<domain>/push/<username>
<domain>
และ <username>
ด้านบนด้วยค่าจริง เช่น https://push.mydomain.cn/push/admin
GET
วิธีการร้องขอ: https://<domain>/push/<username>?title=<标题>&description=<描述>&content=<Markdown 文本>&channel=<推送方式>&token=<推送token>
title
: เป็นทางเลือก ซึ่งจำกัดโดยวิธีพุชข้อความเฉพาะ ซึ่งอาจถูกละเว้นdescription
: จำเป็น สามารถถูกแทนที่ด้วย desp
content
: ไม่บังคับ ถูกจำกัดโดยวิธีการพุชข้อความเฉพาะ การสนับสนุนไวยากรณ์ Markdown จะแตกต่างออกไปchannel
: ทางเลือก หากไม่ได้กรอก ระบบจะใช้ช่องพุชเริ่มต้นที่คุณตั้งไว้ในเบื้องหลัง โปรดทราบว่ามีการกรอกชื่อของช่องข้อความที่นี่ ไม่ใช่ประเภท ประเภทช่องสัญญาณพุชเสริมคือ:email
: พุชโดยการส่งอีเมล (ใช้ช่อง title
หรือ description
เพื่อตั้งชื่อหัวเรื่องอีเมล ใช้ช่อง content
เพื่อตั้งค่าเนื้อหา และรองรับไวยากรณ์ Markdown ที่สมบูรณ์)test
: พุชผ่านบัญชีทดสอบ WeChat (ใช้ช่อง description
เพื่อตั้งค่าเนื้อหาข้อความเทมเพลต ไม่รองรับ Markdown)corp_app
: พุชผ่านบัญชีแอปพลิเคชัน WeChat ระดับองค์กร (เฉพาะเมื่อใช้แอป WeChat ระดับองค์กรเท่านั้น หากตั้งค่าช่อง content
title
และ description
จะถูกละเว้น ซึ่งเป็นเรื่องปกติเมื่อใช้ปลั๊กอิน WeChat ระดับองค์กรใน WeChat)lark_app
: ผลักดันผ่านแอปพลิเคชันที่สร้างขึ้นเองของ Feishucorp
: ผลักดันผ่านหุ่นยนต์กลุ่ม WeChat ขององค์กร (การตั้งค่าฟิลด์ content
จะแสดงข้อความ Markdown ซึ่งสนับสนุนชุดย่อยของ Markdown การตั้งค่า description
จะแสดงข้อความธรรมดา)lark
: ผลักผ่านหุ่นยนต์ Feishuqun (หมายเหตุเหมือนกับข้างบน)ding
: กดผ่านโรบอตกลุ่ม DingTalk (หมายเหตุเหมือนกับข้างบน)bark
: ดันผ่าน Bark (รองรับช่อง title
และ description
)client
: พุชผ่านไคลเอนต์ WebSocket (รองรับฟิลด์ title
และ description
)telegram
: พุชผ่านหุ่นยนต์โทรเลข (เลือกหนึ่งในฟิลด์ description
หรือ content
รองรับชุดย่อยของ Markdown)discord
: ดันผ่านบอทกลุ่ม Discord (หมายเหตุเหมือนกับข้างบน)one_api
: พุชข้อความไปยัง QQ ผ่านโปรโตคอล OneAPIgroup
: พุชผ่านกลุ่มช่องพุชข้อความที่กำหนดค่าไว้ล่วงหน้าcustom
: พุชผ่านช่องทางพุชแบบกำหนดเองที่กำหนดค่าไว้ล่วงหน้าtencent_alarm
: ส่งผ่านการแจ้งเตือนการตรวจสอบ Tencent Cloud รองรับเฉพาะช่อง description
เท่านั้นnone
: บันทึกลงฐานข้อมูลเท่านั้น ห้ามกดtoken
: หากคุณตั้งค่าโทเค็นการพุชในพื้นหลัง รายการนี้จำเป็นต้องมี นอกจากนี้ยังสามารถตั้งค่าได้โดยการตั้งค่าส่วนหัว Authorization
HTTPurl
: ไม่บังคับ หากไม่ได้กรอก ระบบจะสร้าง URL สำหรับข้อความโดยอัตโนมัติ และเนื้อหาจะเป็นรายละเอียดของข้อความto
: ไม่บังคับ ให้พุชไปยังผู้ใช้ที่ระบุ หากไม่ได้กรอก ระบบจะพุชไปที่ตัวคุณเองตามค่าเริ่มต้น มันถูกจำกัดโดยวิธีการพุชข้อความเฉพาะ และวิธีการพุชบางวิธีไม่รองรับสิ่งนี้@all
: พุชไปยังผู้ใช้ทั้งหมดuser1|user2|user3
: พุชไปยังผู้ใช้หลายราย คั่นด้วย |
async
: ไม่บังคับ หากตั้งค่าเป็น true
การพุชข้อความจะดำเนินการแบบอะซิงโครนัสในพื้นหลัง และผลลัพธ์ที่ส่งคืนจะมีฟิลด์ uuid
ซึ่งสามารถใช้สำหรับ [รับสถานะการส่งข้อความ] ในภายหลัง (./docs/API.md#Get สถานะการส่งข้อความผ่านข้อความ UUID)render_mode
: ไม่จำเป็นcode
เนื้อหาข้อความจะซ้อนอยู่ในบล็อคโค้ดโดยอัตโนมัติเพื่อแสดงผลraw
การแยกวิเคราะห์ Markdown จะไม่ถูกดำเนินการmarkdown
ซึ่งหมายถึงการแยกวิเคราะห์ MarkdownPOST
: ช่องต่างๆ สอดคล้องกับวิธีการขอ GET
ด้านบนContent-Type
เป็น application/json
ไม่เช่นนั้นจะถูกประมวลผลเป็นรูปแบบtoken
ในโหมดคำขอ POST สามารถตั้งค่าผ่านพารามิเตอร์การสืบค้น URL ได้ระดับการสนับสนุนช่องทางต่างๆ:
ประเภทช่อง | title | description | content | url | to | การสนับสนุนมาร์กดาวน์ |
---|---|---|---|---|---|---|
email | ||||||
test | ||||||
corp_app | ||||||
corp | ||||||
lark | ||||||
lark_app | ||||||
ding | ||||||
bark | ||||||
client | ||||||
telegram | ||||||
discord | ||||||
tencent_alarm |
สังเกต:
description
และ content
ไม่สามารถอยู่พร้อมกันได้ หากคุณต้องการเพียงข้อความตัวอักษร โปรดใช้ช่อง description
หากคุณต้องการส่งข้อความ Markdown โปรดใช้ช่อง content
ตัวอย่าง:
#! /bin/bash
MESSAGE_PUSHER_SERVER= " https://msgpusher.com "
MESSAGE_PUSHER_USERNAME= " test "
MESSAGE_PUSHER_TOKEN= " 666 "
function send_message {
# POST Form
curl -s -X POST " $MESSAGE_PUSHER_SERVER /push/ $MESSAGE_PUSHER_USERNAME "
-d " title= $1 &description= $2 &content= $3 &token= $MESSAGE_PUSHER_TOKEN "
> /dev/null
}
function send_message_with_json {
# POST JSON
curl -s -X POST " $MESSAGE_PUSHER_SERVER /push/ $MESSAGE_PUSHER_USERNAME "
-H ' Content-Type: application/json '
-d ' {"title":" ' " $1 " ' ","desp":" ' " $2 " ' ", "content":" ' " $3 " ' ", "token":" ' " $MESSAGE_PUSHER_TOKEN " ' "} '
> /dev/null
}
send_message ' title ' ' description ' ' content '
รุ่นอื่น:
MESSAGE_PUSHER_SERVER= " https://msgpusher.com "
MESSAGE_PUSHER_USERNAME= " test "
MESSAGE_PUSHER_TOKEN= " 666 "
MESSAGE_PUSHER_CHANNEL= " lark "
sendmsg () {
if [ -t 0 ] ; then
local param= " $* "
else
local param= $( < /dev/stdin )
fi
curl -s -o /dev/null --get --data-urlencode " content= ${param} " " $MESSAGE_PUSHER_SERVER /push/ $MESSAGE_PUSHER_USERNAME ?channel= $MESSAGE_PUSHER_CHANNEL &token= $MESSAGE_PUSHER_TOKEN "
}
จากนั้นคุณสามารถทำสิ่งนี้:
uname -ra | sendmsg
import requests
SERVER = "https://msgpusher.com"
USERNAME = "test"
TOKEN = "666"
def send_message ( title , description , content ):
# GET 方式
# res = requests.get(f"{SERVER}/push/{USERNAME}?title={title}"
# f"&description={description}&content={content}&token={TOKEN}")
# POST 方式
res = requests . post ( f" { SERVER } /push/ { USERNAME } " , json = {
"title" : title ,
"description" : description ,
"content" : content ,
"token" : TOKEN
})
res = res . json ()
if res [ "success" ]:
return None
else :
return res [ "message" ]
error = send_message ( "标题" , "描述" , "**Markdown 内容**" )
if error :
print ( error )
package main
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"net/http"
"net/url"
)
var serverAddress = "https://msgpusher.com"
var username = "test"
var token = "666"
type request struct {
Title string `json:"title"`
Description string `json:"description"`
Content string `json:"content"`
URL string `json:"url"`
Channel string `json:"channel"`
Token string `json:"token"`
}
type response struct {
Success bool `json:"success"`
Message string `json:"message"`
}
func SendMessage ( title string , description string , content string ) error {
req := request {
Title : title ,
Description : description ,
Content : content ,
Token : token ,
}
data , err := json . Marshal ( req )
if err != nil {
return err
}
resp , err := http . Post ( fmt . Sprintf ( "%s/push/%s" , serverAddress , username ),
"application/json" , bytes . NewBuffer ( data ))
if err != nil {
return err
}
var res response
err = json . NewDecoder ( resp . Body ). Decode ( & res )
if err != nil {
return err
}
if ! res . Success {
return errors . New ( res . Message )
}
return nil
}
func SendMessageWithForm ( title string , description string , content string ) error {
resp , err := http . PostForm ( fmt . Sprintf ( "%s/push/%s" , serverAddress , username ),
url. Values { "title" : { title }, "description" : { description }, "content" : { content }, "token" : { token }})
if err != nil {
return err
}
var res response
err = json . NewDecoder ( resp . Body ). Decode ( & res )
if err != nil {
return err
}
if ! res . Success {
return errors . New ( res . Message )
}
return nil
}
func main () {
//err := SendMessage("标题", "描述", "**Markdown 内容**")
err := SendMessageWithForm ( "标题" , "描述" , "**Markdown 内容**" )
if err != nil {
fmt . Println ( "推送失败:" + err . Error ())
} else {
fmt . Println ( "推送成功!" )
}
}
using Newtonsoft . Json ;
using RestSharp ;
namespace Demo
{
public class Program
{
public static void Main ( string [ ] args )
{
//推送消息
var sendMsg = MessagePusherTool . SendMessage ( "标题" , "描述" , "**Markdown 内容**" ) ;
if ( sendMsg . Success )
{
Console . WriteLine ( $ "推送成功!" ) ;
}
else
{
Console . WriteLine ( $ "推送失败: { sendMsg . Message } " ) ;
}
}
}
/// <summary>
/// 消息推送工具
///
/// <para>开源地址:https://github.com/songquanpeng/message-pusher</para>
/// <para>支持:Framework、Net3.1、Net5、Net6</para>
/// <para>引用包:</para>
/// <para>dotnet add package Newtonsoft.Json -v 13.0.2</para>
/// <para>dotnet add package RestSharp -v 108.0.3</para>
/// </summary>
public class MessagePusherTool
{
/// <summary>
/// ServerAddress
/// </summary>
public const string ServerAddress = "https://msgpusher.com" ;
/// <summary>
/// UserName
/// </summary>
public const string UserName = "test" ;
/// <summary>
/// Token
/// </summary>
public const string Token = "666" ;
/// <summary>
/// SendMessage
/// </summary>
/// <param name="title">title</param>
/// <param name="description">description</param>
/// <param name="content">content</param>
public static Response SendMessage ( string title , string description , string content )
{
var requestData = new Request ( )
{
Title = title ,
Description = description ,
Content = content ,
Token = Token ,
} ;
var url = $ " { ServerAddress } " ;
var client = new RestClient ( url ) ;
var request = new RestRequest ( $ "push/ { UserName } " , Method . Post ) ;
request . AddJsonBody ( requestData ) ;
var response = client . Execute ( request ) ;
var responseData = response . Content ;
var responseJson = JsonConvert . DeserializeObject < Response > ( responseData ) ;
return responseJson ;
}
/// <summary>
/// Request
/// </summary>
public class Request
{
/// <summary>
/// Title
/// </summary>
[ JsonProperty ( PropertyName = "title" ) ]
public string Title { get ; set ; }
/// <summary>
/// Description
/// </summary>
[ JsonProperty ( PropertyName = "description" ) ]
public string Description { get ; set ; }
/// <summary>
/// Content
/// </summary>
[ JsonProperty ( PropertyName = "content" ) ]
public string Content { get ; set ; }
/// <summary>
/// URL
/// </summary>
[ JsonProperty ( PropertyName = "url" ) ]
public string URL { get ; set ; }
/// <summary>
/// Channel
/// </summary>
[ JsonProperty ( PropertyName = "channel" ) ]
public string Channel { get ; set ; }
/// <summary>
/// Token
/// </summary>
[ JsonProperty ( PropertyName = "token" ) ]
public string Token { get ; set ; }
}
/// <summary>
/// Response
/// </summary>
public class Response
{
/// <summary>
/// Success
/// </summary>
[ JsonProperty ( PropertyName = "success" ) ]
public bool Success { get ; set ; }
/// <summary>
/// Message
/// </summary>
[ JsonProperty ( PropertyName = "message" ) ]
public string Message { get ; set ; }
}
}
}
const axios = require ( 'axios' ) ;
const querystring = require ( 'querystring' ) ;
const MESSAGE_PUSHER_SERVER = 'https://msgpusher.com'
const MESSAGE_PUSHER_USERNAME = 'test'
const MESSAGE_PUSHER_TOKEN = '666'
async function send_message ( title , description , content ) {
try {
const postData = querystring . stringify ( {
title : title ,
desp : description ,
content : content ,
token : MESSAGE_PUSHER_TOKEN ,
} )
const response = await axios . post ( ` ${ MESSAGE_PUSHER_SERVER } /push/ ${ MESSAGE_PUSHER_USERNAME } ` , postData , {
headers : {
'Content-Type' : 'application/x-www-form-urlencoded' ,
} ,
} )
if ( response . data . success ) {
return response . data
}
} catch ( error ) {
if ( error . response ) {
return error . response . data
} else {
throw error
}
}
}
send_message ( '标题' , '描述' , '**Markdown 内容**' )
. then ( ( response ) => {
if ( response . success ) {
console . log ( '推送成功:' , response )
} else {
console . log ( '推送失败:' , response )
}
} , ( error ) => {
console . log ( error . message ) ;
} )
ฝ่ายประชาสัมพันธ์สามารถเพิ่มตัวอย่างในภาษาต่างๆ ได้มากขึ้น
SQLite ถูกใช้เป็นตัวอย่างที่นี่ โปรดแก้ไขฐานข้อมูลอื่น ๆ ด้วยตัวเอง ฉันได้ขอให้ ChatGPT แปลเป็นเวอร์ชัน SQL ที่เกี่ยวข้อง โปรดดูโฟลเดอร์ bin
เพื่อใช้อ้างอิง
v0.3
เป็น v0.4
v0.4
เริ่มโปรแกรม จากนั้นโปรแกรมจะย้ายโครงสร้างตารางฐานข้อมูลโดยอัตโนมัติ./bin/migrate_v3_to_v4.py
เพื่อย้ายข้อมูล โปรดทราบว่าก่อนดำเนินการ โปรดตรวจสอบให้แน่ใจว่าลำดับของฟิลด์ในตาราง users
ในฐานข้อมูลสอดคล้องกับลำดับในสคริปต์ ไม่เช่นนั้นข้อมูลจะสับสนเกิดขึ้น
v0.3
จะขึ้นอยู่กับ Node.js คุณสามารถสลับไปที่สาขา nodejs
เพื่อดูได้v0.3
และเวอร์ชันถัดๆ ไปได้รับการพัฒนาโดยใช้ Gin Template v0.2.1
pattern web/build: no matching files found