🆕 add ui

This commit is contained in:
Song
2020-09-01 19:27:16 +08:00
parent 0cb75f9913
commit 564628cdd4
9 changed files with 140 additions and 22 deletions
+4 -14
View File
@@ -9,24 +9,14 @@
3. 安装依赖:`npm i`
4. 安装 pm2`npm i -g pm2`
5. 使用 Nginx 反代我们的 Node.js 服务,默认端口 3000。
6. 使用 pm2 启动应用:`pm2 start ./app.js --name wechat-message-push-service`
### 微信公众平台端配置
1. 首先前往[此页面](https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index) 拿到 APP_ID 以及 APP_SECRET。
1. 首先前往[此页面](https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index)拿到 APP_ID 以及 APP_SECRET。
2. 填写接口配置信息,URL 填 `https://你的域名/verify`TOKEN 随意,之后点击验证。
3. 使用微信扫描下方的测试号二维码,拿到你的 OPEN_ID。
4. 新增模板消息模板,模板标题随意,模板内容填 `{{text.DATA}}`,提交后可以拿到 TEMPLATE_ID。
### 启动服务
1. 至此,我们已经拿到所有我们需要的信息,接下来设置环境变量,方法很多,例如可以通过在应用的根目录创建 .env 文件,设置以下环境变量:
```
APP_ID=wx*****
APP_SECRET=*****
TOKEN=你的 TOKEN
TEMPLATE_ID=****
OPEN_ID=****
PORT=3000
```
2. 使用 `pm2 restart wechat-message-push-service` 重启服务。
3. 之后访问 `https://你的域名/push?content=Hi`,如果微信能够收到消息一条内容为 Hi 的模板消息,则配置成功。
1. 使用 pm2 启动应用:`pm2 start ./app.js --name wechat-message-push-service`
2. 访问首页填写配置项并提交。
2. 之后访问 `https://你的域名/push?content=Hi`,如果微信能够收到消息一条内容为 Hi 的模板消息,则配置成功。
+5 -2
View File
@@ -13,6 +13,11 @@ const app = express();
requestToken(app);
setInterval(() => requestToken(app), 100 * 60 * 1000);
const port = parseInt(process.env.PORT || "3000");
app.set("port", port);
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "ejs");
app.use(logger("dev"));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
@@ -21,8 +26,6 @@ app.use(express.static(path.join(__dirname, "public")));
app.use("/", indexRouter);
const port = parseInt(process.env.PORT || "3000");
app.set("port", port);
const server = http.createServer(app);
server.listen(port);
+1
View File
@@ -10,6 +10,7 @@
"cookie-parser": "~1.4.4",
"debug": "~2.6.9",
"dotenv": "^8.2.0",
"ejs": "^3.1.5",
"express": "~4.16.1",
"morgan": "~1.9.1"
},
+50 -5
View File
@@ -2,12 +2,55 @@ const express = require("express");
const router = express.Router();
const crypto = require("crypto");
const axios = require("axios");
const fs = require("fs");
const requestToken = require("./utils").requestToken;
router.get("/", (req, res, next) => {
res.send("OK");
router.all("/", (req, res, next) => {
fs.promises
.access("./.env")
.then(() => {
res.render("message", {
message: "服务已在运行。",
});
})
.catch(() => {
res.render("configure");
});
});
router.get("/verify", (req, res, next) => {
router.post("/configure", (req, res, next) => {
fs.promises
.access("./.env")
.then(() => {
res.render("message", {
message: ".env 文件已经存在,请手动删除该文件后重试!",
});
})
.catch(() => {
let content =
`APP_ID=${req.body.APP_ID}\n` +
`APP_SECRET=${req.body.APP_SECRET}\n` +
`TOKEN=${req.body.TOKEN}\n` +
`TEMPLATE_ID=${req.body.TEMPLATE_ID}\n` +
`OPEN_ID=${req.body.OPEN_ID}`;
fs.promises
.writeFile("./.env", content, "utf8")
.then(() => {
res.render("message", {
message:
".env 文件写入成功,程序即将自动关闭以应用写入的新的环境变量,需要进程守护程序自动重启应用或者手动重启。",
});
process.exit();
})
.catch((e) => {
res.render("message", {
message: "在尝试写入 .env 文件时发生错误:" + e,
});
});
});
});
router.all("/verify", (req, res, next) => {
// 验证消息来自微信服务器:https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Access_Overview.html
const { signature, timestamp, nonce, echostr } = req.query;
const token = process.env.TOKEN;
@@ -21,10 +64,9 @@ router.get("/verify", (req, res, next) => {
}
});
router.get("/push", (req, res, next) => {
router.all("/push", (req, res, next) => {
// Reference: https://mp.weixin.qq.com/debug/cgi-bin/readtmpl?t=tmplmsg/faq_tmpl
let content = req.query.content || req.body.content;
console.log(`Get content: ${content}`);
let access_token = req.app.access_token;
let request_data = {
touser: process.env.OPEN_ID,
@@ -37,6 +79,9 @@ router.get("/push", (req, res, next) => {
request_data
)
.then((response) => {
if (response.data && response.data.errcode === "40001") {
requestToken(req.app);
}
res.json(response.data);
})
.catch((error) => {
+1 -1
View File
@@ -9,7 +9,7 @@ module.exports = {
)
.then((res) => {
if (res.data && res.data.access_token) {
console.log("Get token: ", res.data.access_token);
console.log("Token requested.");
token = res.data.access_token;
app.access_token = token;
} else {
+56
View File
@@ -0,0 +1,56 @@
<%- include('./header') %>
<h2 class="subtitle">配置页面</h2>
<article class="message is-warning">
<div class="message-header">
<p>警告</p>
</div>
<div class="message-body">
提交后将在程序的根目录创建一个 .env 文件,之后程序将自动关闭,请确保你已经使用了诸如 pm2 的进程守护程序来自动重启本程序。提交之后如果想要对配置内容进行修改,则你必须手动删除 .env 文件。
</div>
</article>
<form action="/configure" method="post">
<div class="field">
<label class="label">APP ID</label>
<div class="control">
<input class="input" name="APP_ID" type="text" required placeholder="请输入 APP ID">
</div>
</div>
<div class="field">
<label class="label">APP SECRET</label>
<div class="control">
<input class="input" name="APP_SECRET" type="text" required placeholder="请输入 APP SECRET">
</div>
</div>
<div class="field">
<label class="label">OPEN ID</label>
<div class="control">
<input class="input" name="OPEN_ID" type="text" required placeholder="请输入你的 OPEN ID">
</div>
</div>
<div class="field">
<label class="label">TEMPLATE ID</label>
<div class="control">
<input class="input" name="TEMPLATE_ID" type="text" required placeholder="请输入一个模板文章 ID">
</div>
</div>
<div class="field">
<label class="label">TOKEN</label>
<div class="control">
<input class="input" name="TOKEN" type="text" required placeholder="请输入你的 TOKEN">
</div>
</div>
<div class="field is-grouped is-grouped-right">
<div class="control">
<input type="submit" class="button is-link" value="提交">
</div>
<div class="control">
<input type="reset" class="button is-link is-light" value="重置">
</div>
</div>
</form>
<%- include('./footer') %>
+2
View File
@@ -0,0 +1,2 @@
</div>
</body>
+11
View File
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.0/css/bulma.min.css">
<title>WeChat Message Push Service</title>
</head>
<body style="width: 100%;">
<div style="margin: auto; max-width: 960px">
<h1 class="title" style="margin-top: 16px"><a style="color: black; text-decoration: none">微信消息通知服务</a></h1>
+10
View File
@@ -0,0 +1,10 @@
<%- include('./header') %>
<article class="message is-primary">
<div class="message-header">
<p>注意</p>
</div>
<div class="message-body">
<%= message %>
</div>
</article>
<%- include('./footer') %>