Bangun layanan push pesan Anda sendiri, dukung beberapa metode push pesan, dukung penurunan harga, hanya satu file yang dapat dieksekusi, siap digunakan langsung dari kotaknya
Pengunduhan program·Tutorial penerapan·Tutorial penggunaan·Umpan Balik·Demonstrasi online
Catatan : Situs penerapan resmi https://msgpusher.com sekarang online dan pendaftaran sedang dibuka. Jika Anda menerima tanggapan positif, Anda dapat mempertimbangkan untuk beralih ke server dengan latensi lebih rendah di masa mendatang.
Peringatan : Memutakhirkan dari
v0.3
kev0.4
memerlukan migrasi database secara manual.
Penerapan: 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
Jika tidak bisa ditarik, silakan ganti justsong/message-pusher
dengan ghcr.io/songquanpeng/message-pusher
.
Pembaruan: docker run --rm -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower -cR
Nomor port yang terbuka adalah 3000. Kemudian gunakan Nginx untuk mengonfigurasi nama domain, pembuatan terbalik, dan sertifikat SSL. Silakan merujuk ke tutorial penerapan terperinci untuk detailnya.
Data akan disimpan di direktori /home/ubuntu/data/message-pusher
pada mesin host (hanya ada satu file database SQLite). Harap pastikan bahwa direktori tersebut ada dan memiliki izin menulis, atau ubah ke direktori yang sesuai .
Konfigurasi referensi 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;
}
}
Kemudian gunakan certbot Let's Encrypt untuk mengonfigurasi 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
dan kata sandinya adalah 123456
.Jika layanan perlu berjalan dalam waktu lama, memulainya saja tidak cukup.
Jika Anda perlu menggunakan fungsi push klien WebSocket, proxy_read_timeout
dan proxy_send_timeout
dalam file konfigurasi Nginx harus disetel ke lebih dari 1 menit.
Pengaturan yang disarankan:
proxy_read_timeout 300s;
proxy_send_timeout 300s;
Sistemnya sendiri hanya perlu mengunduh file yang dapat dieksekusi untuk mulai menggunakannya, tanpa ketergantungan lainnya.
Anda dapat mengonfigurasinya dengan mengatur variabel lingkungan atau parameter baris perintah.
Setelah sistem dimulai, gunakan pengguna root
untuk masuk ke sistem dan melakukan konfigurasi lebih lanjut. Kata sandi default adalah 123456
.
REDIS_CONN_STRING
: Setelah pengaturan, Redis akan digunakan sebagai penyimpanan untuk batas frekuensi permintaan alih-alih menggunakan penyimpanan memori.REDIS_CONN_STRING=redis://default:redispw@localhost:49153
SESSION_SECRET
: Setelah pengaturan, kunci sesi tetap akan digunakan, sehingga cookie pengguna yang login akan tetap valid setelah sistem di-restart.SESSION_SECRET=random_string
SQL_DSN
: Setelah pengaturan, database yang ditentukan akan digunakan sebagai pengganti SQLite.SQL_DSN=root:123456@tcp(localhost:3306)/message-pusher
Catatan: Saat menerapkan Docker, harap gunakan -e key=value
untuk mengatur variabel lingkungan.
Contoh: docker run -e SESSION_SECRET=random_string ...
--port <port_number>
: Tentukan nomor port yang didengarkan server, defaultnya adalah 3000
.--port 3000
--log-dir <log_dir>
: Tentukan folder log. Jika tidak disetel, log tidak akan disimpan.--log-dir ./logs
--version
: Cetak nomor versi sistem dan keluar.允许新用户注册
.更新用户信息
untuk mengubah nama pengguna dan kata sandi default.绑定邮箱地址
untuk mengikat email guna mengaktifkan push pesan email.默认推送方式
. Defaultnya adalah push melalui email.推送token
untuk autentikasi panggilan API push. Biarkan kosong jika tidak diperlukan.测试
yang sesuai untuk menguji apakah konfigurasi berhasil.https://<domain>/push/<username>
<domain>
dan <username>
di atas dengan nilai sebenarnya, misalnya: https://push.mydomain.cn/push/admin
GET
metode permintaan: https://<domain>/push/<username>?title=<标题>&description=<描述>&content=<Markdown 文本>&channel=<推送方式>&token=<推送token>
title
: Opsional, dibatasi oleh metode push pesan tertentu, mungkin diabaikan.description
: wajib, bisa diganti dengan desp
.content
: Opsional, dibatasi oleh metode push pesan tertentu, dukungan sintaks penurunan harga berbeda.channel
: Opsional, jika tidak diisi, sistem akan menggunakan saluran push default yang Anda atur di latar belakang. Perhatikan bahwa nama saluran pesan diisi di sini, bukan jenisnya. Jenis saluran dorong opsional adalah:email
: Dorong dengan mengirimkan email (gunakan kolom title
atau description
untuk mengatur subjek email, gunakan kolom content
untuk mengatur isi, dan mendukung sintaks penurunan harga yang lengkap).test
: Mendorong akun pengujian WeChat (gunakan kolom description
untuk mengatur konten pesan template, Penurunan harga tidak didukung).corp_app
: Masuk ke akun aplikasi WeChat perusahaan (hanya saat menggunakan APP WeChat perusahaan, jika bidang content
disetel, bidang title
dan description
akan diabaikan; hal ini normal saat menggunakan plug-in WeChat perusahaan di WeChat).lark_app
: Mendorong aplikasi buatan Feishu.corp
: Didorong melalui robot grup WeChat perusahaan (mengatur bidang content
akan menampilkan pesan Penurunan Harga, mendukung subset Penurunan Harga; menyetel bidang description
akan menampilkan pesan teks biasa).lark
: dorong melalui robot Feishuqun (catatannya sama seperti di atas).ding
: push melalui robot grup DingTalk (catatannya sama seperti di atas).bark
: mendorong melalui Kulit (mendukung bidang title
dan description
).client
: push melalui klien WebSocket (mendukung bidang title
dan description
).telegram
: push melalui robot Telegram (pilih salah satu kolom description
atau content
, mendukung subset Penurunan Harga).discord
: Dorong bot grup Discord (catatannya sama seperti di atas).one_api
: Kirim pesan ke QQ melalui protokol OneAPI.group
: Mendorong melalui grup saluran dorong pesan yang telah dikonfigurasi sebelumnya.custom
: Dorong melalui saluran push khusus yang telah dikonfigurasi sebelumnya.tencent_alarm
: Didorong melalui alarm pemantauan Tencent Cloud, hanya kolom description
yang didukung.none
: Hanya simpan ke database, jangan dipush.token
: Jika Anda menyetel token push di latar belakang, item ini diperlukan. Ini juga dapat diatur dengan mengatur header Authorization
HTTP.url
: Opsional, jika tidak diisi, sistem akan secara otomatis membuat URL untuk pesan tersebut, dan isinya akan menjadi detail pesan.to
: Opsional, dorong ke pengguna yang ditentukan. Jika tidak diisi, itu akan dikirim ke diri Anda sendiri secara default. Ini dibatasi oleh metode dorong pesan tertentu, dan beberapa metode dorong tidak mendukung ini.@all
: Dorong ke semua pengguna.user1|user2|user3
: Dorong ke beberapa pengguna, dipisahkan oleh |
.async
: Opsional, jika disetel ke true
, push pesan akan dilakukan secara asinkron di latar belakang, dan hasil pengembalian berisi bidang uuid
, yang dapat digunakan untuk [Dapatkan status pengiriman pesan] berikutnya (./docs/API.md#Get status pengiriman pesan melalui pesan UUID).render_mode
: opsional,code
, isi pesan akan secara otomatis disarangkan dalam blok kode untuk dirender;raw
, penguraian penurunan harga tidak akan dilakukan;markdown
, yang berarti penguraian penurunan harga.POST
: Bidang konsisten dengan metode permintaan GET
di atas.Content-Type
Header HTTP harus disetel ke application/json
, jika tidak maka akan diproses sebagai Formulir.token
dalam mode permintaan POST juga dapat diatur melalui parameter kueri URL.Tingkat dukungan untuk berbagai saluran:
Jenis saluran | title | description | content | url | to | Dukungan penurunan harga |
---|---|---|---|---|---|---|
email | ✅ | ✅ | ✅ | ✅️ | ✅️ | |
test | ✅ | ✅ | ✅ | ✅️ | ✅️ | ✅ |
corp_app | ✅ | ✅ | ✅ | ✅️ | ✅ | ✅ |
corp | ✅ | ✅ | ✅️ | ✅️ | ✅ | |
lark | ✅ | ✅ | ✅ | ✅ | ||
lark_app | ✅ | ✅ | ️ | ✅ | ✅ | |
ding | ✅ | ✅ | ✅ | ✅️ | ✅ | ✅ |
bark | ✅ | ✅ | ✅ | ✅️ | ✅ | |
client | ✅ | ✅ | ||||
telegram | ✅ | ✅ | ✅ | |||
discord | ✅ | ✅ | ||||
tencent_alarm | ✅ |
Melihat:
description
dan content
tidak bisa ada secara bersamaan. Jika Anda hanya memerlukan pesan teks, silakan gunakan kolom description
. Jika Anda perlu mengirim pesan penurunan harga, silakan gunakan kolom content
.Contoh:
#! /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 '
Versi lain:
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 "
}
Kemudian Anda dapat melakukan sesuatu seperti ini:
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 ) ;
} )
PR dipersilakan untuk menambahkan contoh dalam lebih banyak bahasa.
SQLite digunakan sebagai contoh di sini. Silakan modifikasi sendiri database lainnya. Saya telah meminta ChatGPT untuk menerjemahkannya ke versi SQL yang sesuai, lihat folder bin
untuk referensi.
v0.3
ke v0.4
v0.4
terbaru, mulai program, dan program akan secara otomatis memigrasikan struktur tabel database../bin/migrate_v3_to_v4.py
untuk memigrasikan data. Perhatikan bahwa sebelum eksekusi, harap pastikan bahwa urutan bidang dalam tabel users
di database konsisten dengan yang ada di skrip, jika tidak maka akan terjadi kebingungan data.
v0.3
didasarkan pada Node.js. Anda dapat beralih ke cabang nodejs
untuk melihatnya.v0.3
dan versi selanjutnya dikembangkan berdasarkan Gin Template v0.2.1
.pattern web/build: no matching files found
.