diff --git a/.gitignore b/.gitignore
index 68e55d7..8ab0022 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,7 @@
.idea
node_modules
package-lock.json
-.env
\ No newline at end of file
+.env
+data.db
+data.db-journal
+.vscode
\ No newline at end of file
diff --git a/app.js b/app.js
index e424146..ed27c56 100644
--- a/app.js
+++ b/app.js
@@ -5,8 +5,9 @@ const logger = require("morgan");
const http = require("http");
require("dotenv").config();
-const indexRouter = require("./routes");
-const requestToken = require("./utils").requestToken;
+const indexRouter = require("./routers/index");
+const messageRouter = require("./routers/message");
+const requestToken = require("./utils/wechat").requestToken;
const app = express();
@@ -26,6 +27,7 @@ app.use(cookieParser());
app.use(express.static(path.join(__dirname, "public")));
app.use("/", indexRouter);
+app.use("/message", messageRouter);
const server = http.createServer(app);
diff --git a/knexfile.js b/knexfile.js
new file mode 100644
index 0000000..04a01eb
--- /dev/null
+++ b/knexfile.js
@@ -0,0 +1,22 @@
+module.exports = {
+ development: {
+ client: "sqlite3",
+ connection: {
+ filename: "./data.db",
+ },
+ },
+
+ staging: {
+ client: "sqlite3",
+ connection: {
+ filename: "./data.db",
+ },
+ },
+
+ production: {
+ client: "sqlite3",
+ connection: {
+ filename: "./data.db",
+ },
+ },
+};
diff --git a/migrations/20200913222330_initialize_database.js b/migrations/20200913222330_initialize_database.js
new file mode 100644
index 0000000..f3e1ef4
--- /dev/null
+++ b/migrations/20200913222330_initialize_database.js
@@ -0,0 +1,13 @@
+exports.up = function (knex) {
+ return knex.schema.createTable("messages", (tableBuilder) => {
+ tableBuilder.uuid("id").primary();
+ tableBuilder.string("title");
+ tableBuilder.string("status");
+ tableBuilder.string("created_by");
+ tableBuilder.string("created_time");
+ tableBuilder.string("description");
+ tableBuilder.text("content");
+ });
+};
+
+exports.down = function (knex) {};
diff --git a/models/message.js b/models/message.js
new file mode 100644
index 0000000..1a573d0
--- /dev/null
+++ b/models/message.js
@@ -0,0 +1,19 @@
+const db = require("../utils/database").db;
+const { v4: uuid } = require("uuid");
+
+class Message {
+ create(message) {
+ message.id = uuid();
+ return db("messages").insert(message);
+ }
+
+ getById(id) {
+ return db("messages").where("id", id);
+ }
+
+ deleteById(id) {
+ return db("messages").where("id", id).del();
+ }
+}
+
+module.exports.Message = new Message();
diff --git a/package.json b/package.json
index d942950..bca64de 100644
--- a/package.json
+++ b/package.json
@@ -12,7 +12,11 @@
"dotenv": "^8.2.0",
"ejs": "^3.1.5",
"express": "~4.16.1",
- "morgan": "~1.9.1"
+ "knex": "^0.21.5",
+ "marked": "^1.1.1",
+ "morgan": "~1.9.1",
+ "sqlite3": "^5.0.0",
+ "uuid": "^8.3.0"
},
"devDependencies": {
"prettier": "^2.1.1"
diff --git a/routes.js b/routers/index.js
similarity index 71%
rename from routes.js
rename to routers/index.js
index 799021a..adb1302 100644
--- a/routes.js
+++ b/routers/index.js
@@ -2,20 +2,14 @@ const express = require("express");
const router = express.Router();
const crypto = require("crypto");
const fs = require("fs");
-const pushMessage = require("./utils").pushMessage;
router.all("/", (req, res, next) => {
fs.promises
.access("./.env")
.then(() => {
- res.render("message", {
- message: "服务已在运行,本次访问已被记录。",
+ res.render("info", {
+ message: "服务已在运行。",
});
- pushMessage(
- req,
- res,
- `请注意,ip 地址为 ${req.ip} 的用户访问了你的消息通知服务,如果非你本人,则你的私有消息通知服务可能已被泄露,当前版本无法阻止其他用户通过本系统向你发送消息。`
- );
})
.catch(() => {
res.render("configure");
@@ -47,7 +41,7 @@ router.post("/configure", (req, res, next) => {
process.exit();
})
.catch((e) => {
- res.render("message", {
+ res.render("info", {
message: "在尝试写入 .env 文件时发生错误:" + e,
});
});
@@ -68,14 +62,4 @@ router.all("/verify", (req, res, next) => {
}
});
-router.all("/push", (req, res, next) => {
- let content = req.query.content || req.body.content;
- pushMessage(req, res, content);
-});
-
-router.all("/:content", (req, res, next) => {
- let content = req.params.content;
- pushMessage(req, res, content);
-});
-
module.exports = router;
diff --git a/routers/message.js b/routers/message.js
new file mode 100644
index 0000000..5d56f88
--- /dev/null
+++ b/routers/message.js
@@ -0,0 +1,59 @@
+const express = require("express");
+const lexer = require("marked").lexer;
+const parser = require("marked").parser;
+const Message = require("../models/message").Message;
+const pushWeChatMessage = require("../utils/wechat").pushWeChatMessage;
+const formatTime = require("../utils/utils").formatTime;
+
+const router = express.Router();
+
+function md2html(markdown) {
+ return parser(lexer(markdown));
+}
+
+router.get("/:description", (req, res, next) => {
+ req.query.description = req.params.description;
+ next();
+});
+
+router.all("/", (req, res) => {
+ let message = {
+ title: req.query.title || req.body.title || "无标题",
+ status: 1,
+ created_by: "系统", // TODO
+ created_time: formatTime(),
+ description: req.query.description || req.body.description,
+ content: md2html(req.query.content || req.body.content),
+ };
+
+ Message.create(message)
+ .then((value) => {
+ console.log(value);
+ pushWeChatMessage(message.description, message.link)
+ .then((response) => {
+ res.json(response);
+ })
+ .catch((reason) => {
+ res.json(reason);
+ });
+ })
+ .catch((reason) => {
+ res.json(reason);
+ });
+});
+
+router.get("/detail/:id", (req, res) => {
+ const id = req.params.id;
+ Message.getById(id)
+ .then((value) => {
+ console.log(value);
+ res.render("message", value[0]);
+ })
+ .catch((reason) => {
+ res.render("info", {
+ message: "获取该消息时发生了错误:" + reason,
+ });
+ });
+});
+
+module.exports = router;
diff --git a/utils/database.js b/utils/database.js
new file mode 100644
index 0000000..59911ce
--- /dev/null
+++ b/utils/database.js
@@ -0,0 +1,9 @@
+const knex = require("knex");
+const environment = process.env.NODE_ENV || "development";
+const configuration = require("../knexfile")[environment];
+
+const db = knex(configuration);
+
+module.exports = {
+ db: db,
+};
diff --git a/utils/utils.js b/utils/utils.js
new file mode 100644
index 0000000..04093f1
--- /dev/null
+++ b/utils/utils.js
@@ -0,0 +1,33 @@
+function formatTime(format) {
+ if (format === undefined) format = "yyyy-MM-dd hh:mm:ss";
+ const date = new Date();
+ const o = {
+ "M+": date.getMonth() + 1,
+ "d+": date.getDate(),
+ "h+": date.getHours(),
+ "m+": date.getMinutes(),
+ "s+": date.getSeconds(),
+ S: date.getMilliseconds(),
+ };
+
+ if (/(y+)/.test(format)) {
+ format = format.replace(
+ RegExp.$1,
+ (date.getFullYear() + "").substr(4 - RegExp.$1.length)
+ );
+ }
+
+ for (let k in o) {
+ if (new RegExp("(" + k + ")").test(format)) {
+ format = format.replace(
+ RegExp.$1,
+ RegExp.$1.length === 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length)
+ );
+ }
+ }
+ return format;
+}
+
+module.exports = {
+ formatTime,
+};
diff --git a/utils.js b/utils/wechat.js
similarity index 58%
rename from utils.js
rename to utils/wechat.js
index 33e70fb..e08be9d 100644
--- a/utils.js
+++ b/utils/wechat.js
@@ -12,6 +12,7 @@ module.exports = {
console.log("Token requested.");
token = res.data.access_token;
app.locals.access_token = token;
+ process.env.access_token = token;
} else {
console.error(res.data);
}
@@ -19,27 +20,17 @@ module.exports = {
return token;
},
- pushMessage: function (req, res, content) {
+ pushWeChatMessage: function (description, link) {
// Reference: https://mp.weixin.qq.com/debug/cgi-bin/readtmpl?t=tmplmsg/faq_tmpl
- let access_token = req.app.locals.access_token;
+ let access_token = process.env.access_token;
let request_data = {
touser: process.env.OPEN_ID,
template_id: process.env.TEMPLATE_ID,
};
- request_data.data = { text: { value: content } };
- axios
- .post(
- `https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=${access_token}`,
- request_data
- )
- .then((response) => {
- if (response.data && response.data.errcode === "40001") {
- requestToken(req.app);
- }
- res.json(response.data);
- })
- .catch((error) => {
- res.json(error);
- });
+ request_data.data = { text: { value: description } };
+ return axios.post(
+ `https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=${access_token}`,
+ request_data
+ );
},
};
diff --git a/views/info.ejs b/views/info.ejs
new file mode 100644
index 0000000..6051709
--- /dev/null
+++ b/views/info.ejs
@@ -0,0 +1,10 @@
+<%- include('./header') %>
+
+
+
+ <%= message %>
+
+
+<%- include('./footer') %>
\ No newline at end of file
diff --git a/views/message.ejs b/views/message.ejs
index 6051709..e2ba5ea 100644
--- a/views/message.ejs
+++ b/views/message.ejs
@@ -1,10 +1,10 @@
<%- include('./header') %>
-
+
- <%= message %>
+
<%- include('./footer') %>
\ No newline at end of file