🚧 refactoring is ongoing
This commit is contained in:
@@ -1,36 +1,39 @@
|
|||||||
const express = require("express");
|
const express = require('express');
|
||||||
const path = require("path");
|
const path = require('path');
|
||||||
const cookieParser = require("cookie-parser");
|
const cookieParser = require('cookie-parser');
|
||||||
const logger = require("morgan");
|
const logger = require('morgan');
|
||||||
const http = require("http");
|
const http = require('http');
|
||||||
require("dotenv").config();
|
const config = require('./config');
|
||||||
|
|
||||||
const indexRouter = require("./routers/index");
|
const indexRouter = require('./routers/index');
|
||||||
const messageRouter = require("./routers/message");
|
const messageRouter = require('./routers/message');
|
||||||
const requestToken = require("./utils/wechat").requestToken;
|
const { refreshToken } = require('./common/wechat');
|
||||||
|
const { initializeTokenStore } = require('./common/token');
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
|
|
||||||
requestToken(app);
|
setTimeout(async () => {
|
||||||
setInterval(() => requestToken(app), 100 * 60 * 1000);
|
// TODO: Here we need an improvement! I have tried EventEmitter but it's not working. :(
|
||||||
|
await initializeTokenStore();
|
||||||
|
await refreshToken(app);
|
||||||
|
setInterval(async () => refreshToken(), 100 * 60 * 1000);
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
const port = parseInt(process.env.PORT || "3000");
|
app.set('views', path.join(__dirname, 'views'));
|
||||||
app.set("port", port);
|
app.set('view engine', 'ejs');
|
||||||
app.set("views", path.join(__dirname, "views"));
|
app.set('trust proxy', true);
|
||||||
app.set("view engine", "ejs");
|
|
||||||
app.set("trust proxy", true);
|
|
||||||
|
|
||||||
app.use(logger("dev"));
|
app.use(logger('dev'));
|
||||||
app.use(express.json());
|
app.use(express.json());
|
||||||
app.use(express.urlencoded({ extended: false }));
|
app.use(express.urlencoded({ extended: false }));
|
||||||
app.use(cookieParser());
|
app.use(cookieParser());
|
||||||
app.use(express.static(path.join(__dirname, "public")));
|
app.use(express.static(path.join(__dirname, 'public')));
|
||||||
|
|
||||||
app.use("/", indexRouter);
|
app.use('/', indexRouter);
|
||||||
app.use("/message", messageRouter);
|
app.use('/message', messageRouter);
|
||||||
|
|
||||||
const server = http.createServer(app);
|
const server = http.createServer(app);
|
||||||
|
|
||||||
server.listen(port);
|
server.listen(config.port);
|
||||||
|
|
||||||
module.exports = app;
|
module.exports = app;
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
const { Sequelize } = require('sequelize');
|
||||||
|
|
||||||
|
const sequelize = new Sequelize({
|
||||||
|
dialect: 'sqlite',
|
||||||
|
storage: 'data.db',
|
||||||
|
logging: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = sequelize;
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
const { pushWechatMessage } = require('./wechat');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
async processMessage(userPrefix, message) {
|
||||||
|
let result = {
|
||||||
|
success: false,
|
||||||
|
message: `unsupported message type ${message.type}`,
|
||||||
|
};
|
||||||
|
switch (message.type) {
|
||||||
|
case '0': // WeChat message
|
||||||
|
result = await pushWechatMessage(userPrefix, message);
|
||||||
|
break;
|
||||||
|
case '1': // Email message
|
||||||
|
// TODO: Email message
|
||||||
|
break;
|
||||||
|
case '2': // HTTP GET request
|
||||||
|
// TODO: HTTP GET request
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
const { User } = require('../models');
|
||||||
|
|
||||||
|
const tokenStore = new Map();
|
||||||
|
|
||||||
|
async function initializeTokenStore() {
|
||||||
|
const users = await User.findAll();
|
||||||
|
users.forEach((user) => {
|
||||||
|
if (user.wechatAppId) {
|
||||||
|
tokenStore.set(user.prefix, {
|
||||||
|
appId: user.wechatAppId,
|
||||||
|
appSecret: user.wechatAppSecret,
|
||||||
|
templateId: user.wechatTemplateId,
|
||||||
|
openId: user.wechatOpenId,
|
||||||
|
token: '',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.debug(tokenStore);
|
||||||
|
console.log('Token store initialized.');
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
initializeTokenStore,
|
||||||
|
tokenStore,
|
||||||
|
};
|
||||||
@@ -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,
|
||||||
|
};
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
const axios = require('axios');
|
||||||
|
const { tokenStore } = require('./token');
|
||||||
|
const config = require('../config');
|
||||||
|
|
||||||
|
async function refreshToken() {
|
||||||
|
for (const item of tokenStore) {
|
||||||
|
item.token = await this.requestToken();
|
||||||
|
}
|
||||||
|
console.log('Token refreshed.');
|
||||||
|
}
|
||||||
|
|
||||||
|
async function requestToken(appId, appSecret) {
|
||||||
|
let token = '';
|
||||||
|
try {
|
||||||
|
let res = await axios.get(
|
||||||
|
`https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appId}&secret=${appSecret}`
|
||||||
|
);
|
||||||
|
console.log(res);
|
||||||
|
if (res && res.data && res.data.access_token) {
|
||||||
|
token = res.data.access_token;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function pushWeChatMessage(userPrefix, message) {
|
||||||
|
// Reference: https://mp.weixin.qq.com/debug/cgi-bin/readtmpl?t=tmplmsg/faq_tmpl
|
||||||
|
let user = tokenStore.get(userPrefix);
|
||||||
|
let access_token = user.token;
|
||||||
|
let request_data = {
|
||||||
|
touser: user.wechatOpenId,
|
||||||
|
template_id: user.wechatTemplateId,
|
||||||
|
};
|
||||||
|
if (message.content) {
|
||||||
|
// TODO
|
||||||
|
// Generate html, save message to database and then return the id
|
||||||
|
let id = 'TODO';
|
||||||
|
request_data.url = `${config.href}${userPrefix}/${id}`;
|
||||||
|
}
|
||||||
|
request_data.data = { text: { value: message.description } };
|
||||||
|
let requestUrl = `https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=${access_token}`;
|
||||||
|
try {
|
||||||
|
let response = await axios.post(requestUrl, request_data);
|
||||||
|
if (response && response.data && response.data.errcode === '40001') {
|
||||||
|
await requestToken(user.wechatAppId, user.wechatAppSecret);
|
||||||
|
await axios.post(requestUrl, request_data);
|
||||||
|
}
|
||||||
|
console.log(response.data);
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
message: '',
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
message: e.message,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
refreshToken,
|
||||||
|
requestToken,
|
||||||
|
pushWeChatMessage,
|
||||||
|
};
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
const config = {
|
||||||
|
port: process.env.PORT || 3000,
|
||||||
|
database: 'data.db',
|
||||||
|
href: 'https://github.com/',
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = config;
|
||||||
-22
@@ -1,22 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
development: {
|
|
||||||
client: "sqlite3",
|
|
||||||
connection: {
|
|
||||||
filename: "./data.db",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
staging: {
|
|
||||||
client: "sqlite3",
|
|
||||||
connection: {
|
|
||||||
filename: "./data.db",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
production: {
|
|
||||||
client: "sqlite3",
|
|
||||||
connection: {
|
|
||||||
filename: "./data.db",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
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) {};
|
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
const User = require('./user');
|
||||||
|
const Message = require('./message');
|
||||||
|
const sequelize = require('../common/database');
|
||||||
|
|
||||||
|
Message.belongsTo(User);
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
await sequelize.sync({ alter: true });
|
||||||
|
console.log('Database initialized.');
|
||||||
|
const isNoAdminExisted =
|
||||||
|
(await User.findOne({ where: { isAdmin: true } })) === null;
|
||||||
|
if (isNoAdminExisted) {
|
||||||
|
console.log('No admin user existed! Creating one for you.');
|
||||||
|
await User.create({
|
||||||
|
username: 'admin',
|
||||||
|
password: '123456',
|
||||||
|
isAdmin: true,
|
||||||
|
prefix: 'admin',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
exports.User = User;
|
||||||
|
exports.Message = Message;
|
||||||
+21
-16
@@ -1,19 +1,24 @@
|
|||||||
const db = require("../utils/database").db;
|
const { DataTypes, Model } = require('sequelize');
|
||||||
const { v4: uuid } = require("uuid");
|
const sequelize = require('../common/database');
|
||||||
|
|
||||||
class Message {
|
class Message extends Model {}
|
||||||
create(message) {
|
|
||||||
message.id = uuid();
|
|
||||||
return db("messages").insert(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
getById(id) {
|
Message.init(
|
||||||
return db("messages").where("id", id);
|
{
|
||||||
}
|
id: {
|
||||||
|
type: DataTypes.UUID,
|
||||||
|
defaultValue: DataTypes.UUIDV4,
|
||||||
|
primaryKey: true,
|
||||||
|
},
|
||||||
|
title: DataTypes.STRING,
|
||||||
|
description: DataTypes.TEXT,
|
||||||
|
content: DataTypes.TEXT,
|
||||||
|
type: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
defaultValue: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ sequelize }
|
||||||
|
);
|
||||||
|
|
||||||
deleteById(id) {
|
module.exports = Message;
|
||||||
return db("messages").where("id", id).del();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.Message = new Message();
|
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
const { DataTypes, Model } = require('sequelize');
|
||||||
|
const sequelize = require('../common/database');
|
||||||
|
|
||||||
|
class User extends Model {}
|
||||||
|
|
||||||
|
User.init(
|
||||||
|
{
|
||||||
|
id: {
|
||||||
|
type: DataTypes.UUID,
|
||||||
|
defaultValue: DataTypes.UUIDV4,
|
||||||
|
primaryKey: true,
|
||||||
|
},
|
||||||
|
username: {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
unique: true,
|
||||||
|
},
|
||||||
|
password: {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
allowNull: false,
|
||||||
|
},
|
||||||
|
accessToken: {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
defaultValue: '',
|
||||||
|
},
|
||||||
|
email: {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
},
|
||||||
|
prefix: {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
unique: true,
|
||||||
|
},
|
||||||
|
isAdmin: {
|
||||||
|
type: DataTypes.BOOLEAN,
|
||||||
|
defaultValue: false,
|
||||||
|
},
|
||||||
|
isBlocked: {
|
||||||
|
type: DataTypes.BOOLEAN,
|
||||||
|
defaultValue: false,
|
||||||
|
},
|
||||||
|
wechatAppId: DataTypes.STRING,
|
||||||
|
wechatAppSecret: DataTypes.STRING,
|
||||||
|
wechatTemplateId: DataTypes.STRING,
|
||||||
|
wechatOpenId: DataTypes.STRING,
|
||||||
|
},
|
||||||
|
{ sequelize }
|
||||||
|
);
|
||||||
|
|
||||||
|
module.exports = User;
|
||||||
+6
-5
@@ -10,17 +10,18 @@
|
|||||||
"axios": "^0.21.1",
|
"axios": "^0.21.1",
|
||||||
"cookie-parser": "~1.4.4",
|
"cookie-parser": "~1.4.4",
|
||||||
"debug": "~2.6.9",
|
"debug": "~2.6.9",
|
||||||
"dotenv": "^8.2.0",
|
|
||||||
"ejs": "^3.1.5",
|
"ejs": "^3.1.5",
|
||||||
"express": "~4.16.1",
|
"express": "~4.16.1",
|
||||||
"knex": "^0.21.5",
|
"marked": "^1.2.7",
|
||||||
"marked": "^1.1.1",
|
|
||||||
"morgan": "~1.9.1",
|
"morgan": "~1.9.1",
|
||||||
"sqlite3": "^5.0.0",
|
"sequelize": "^6.3.5",
|
||||||
"uuid": "^8.3.0"
|
"sqlite3": "^5.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"nodemon": "^2.0.6",
|
"nodemon": "^2.0.6",
|
||||||
"prettier": "^2.1.1"
|
"prettier": "^2.1.1"
|
||||||
|
},
|
||||||
|
"prettier": {
|
||||||
|
"singleQuote": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+24
-30
@@ -1,35 +1,32 @@
|
|||||||
const express = require("express");
|
const express = require('express');
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
const crypto = require("crypto");
|
const crypto = require('crypto');
|
||||||
const fs = require("fs");
|
const fs = require('fs');
|
||||||
|
|
||||||
router.all("/", (req, res, next) => {
|
router.all('/', (req, res, next) => {
|
||||||
fs.promises
|
fs.promises
|
||||||
.access("./.env")
|
.access('./.env')
|
||||||
.then(() => {
|
.then(() => {
|
||||||
res.render("info", {
|
res.render('info', {
|
||||||
message: "服务已在运行。",
|
message: '服务已在运行。',
|
||||||
});
|
});
|
||||||
<<<<<<< HEAD:routers/index.js
|
|
||||||
=======
|
|
||||||
// pushMessage(
|
// pushMessage(
|
||||||
// req,
|
// req,
|
||||||
// res,
|
// res,
|
||||||
// `请注意,ip 地址为 ${req.ip} 的用户访问了你的消息通知服务,如果非你本人,则你的私有消息通知服务可能已被泄露,当前版本无法阻止其他用户通过本系统向你发送消息。`
|
// `请注意,ip 地址为 ${req.ip} 的用户访问了你的消息通知服务,如果非你本人,则你的私有消息通知服务可能已被泄露,当前版本无法阻止其他用户通过本系统向你发送消息。`
|
||||||
// );
|
// );
|
||||||
>>>>>>> master:routes.js
|
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
res.render("configure");
|
res.render('configure');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
router.post("/configure", (req, res, next) => {
|
router.post('/configure', (req, res, next) => {
|
||||||
fs.promises
|
fs.promises
|
||||||
.access("./.env")
|
.access('./.env')
|
||||||
.then(() => {
|
.then(() => {
|
||||||
res.render("message", {
|
res.render('message', {
|
||||||
message: ".env 文件已经存在,请手动删除该文件后重试!",
|
message: '.env 文件已经存在,请手动删除该文件后重试!',
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
@@ -40,51 +37,48 @@ router.post("/configure", (req, res, next) => {
|
|||||||
`TEMPLATE_ID=${req.body.TEMPLATE_ID}\n` +
|
`TEMPLATE_ID=${req.body.TEMPLATE_ID}\n` +
|
||||||
`OPEN_ID=${req.body.OPEN_ID}`;
|
`OPEN_ID=${req.body.OPEN_ID}`;
|
||||||
fs.promises
|
fs.promises
|
||||||
.writeFile("./.env", content, "utf8")
|
.writeFile('./.env', content, 'utf8')
|
||||||
.then(() => {
|
.then(() => {
|
||||||
res.render("message", {
|
res.render('message', {
|
||||||
message:
|
message:
|
||||||
".env 文件写入成功,程序即将自动关闭以应用写入的新的环境变量,需要进程守护程序自动重启应用或者手动重启。",
|
'.env 文件写入成功,程序即将自动关闭以应用写入的新的环境变量,需要进程守护程序自动重启应用或者手动重启。',
|
||||||
});
|
});
|
||||||
process.exit();
|
process.exit();
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
res.render("info", {
|
res.render('info', {
|
||||||
message: "在尝试写入 .env 文件时发生错误:" + e,
|
message: '在尝试写入 .env 文件时发生错误:' + e,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
router.all("/verify", (req, res, next) => {
|
router.all('/verify', (req, res, next) => {
|
||||||
// 验证消息来自微信服务器:https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Access_Overview.html
|
// 验证消息来自微信服务器:https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Access_Overview.html
|
||||||
const { signature, timestamp, nonce, echostr } = req.query;
|
const { signature, timestamp, nonce, echostr } = req.query;
|
||||||
const token = process.env.TOKEN;
|
const token = process.env.TOKEN;
|
||||||
let tmp_array = [token, timestamp, nonce].sort();
|
let tmp_array = [token, timestamp, nonce].sort();
|
||||||
let tmp_string = tmp_array.join("");
|
let tmp_string = tmp_array.join('');
|
||||||
tmp_string = crypto.createHash("sha1").update(tmp_string).digest("hex");
|
tmp_string = crypto.createHash('sha1').update(tmp_string).digest('hex');
|
||||||
if (tmp_string === signature) {
|
if (tmp_string === signature) {
|
||||||
res.send(echostr);
|
res.send(echostr);
|
||||||
} else {
|
} else {
|
||||||
res.send("verification failed");
|
res.send('verification failed');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
<<<<<<< HEAD:routers/index.js
|
router.all('/push', (req, res, next) => {
|
||||||
=======
|
|
||||||
router.all("/push", (req, res, next) => {
|
|
||||||
let content = req.query.content || req.body.content;
|
let content = req.query.content || req.body.content;
|
||||||
pushMessage(req, res, content);
|
pushMessage(req, res, content);
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get("/favicon.ico", (req, res, next) => {
|
router.get('/favicon.ico', (req, res, next) => {
|
||||||
res.sendStatus(404);
|
res.sendStatus(404);
|
||||||
});
|
});
|
||||||
|
|
||||||
router.all("/:content", (req, res, next) => {
|
router.all('/:content', (req, res, next) => {
|
||||||
let content = req.params.content;
|
let content = req.params.content;
|
||||||
pushMessage(req, res, content);
|
pushMessage(req, res, content);
|
||||||
});
|
});
|
||||||
|
|
||||||
>>>>>>> master:routes.js
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
|||||||
+14
-14
@@ -1,9 +1,9 @@
|
|||||||
const express = require("express");
|
const express = require('express');
|
||||||
const lexer = require("marked").lexer;
|
const lexer = require('marked').lexer;
|
||||||
const parser = require("marked").parser;
|
const parser = require('marked').parser;
|
||||||
const Message = require("../models/message").Message;
|
const Message = require('../models/message').Message;
|
||||||
const pushWeChatMessage = require("../utils/wechat").pushWeChatMessage;
|
const pushWeChatMessage = require('../common/wechat').pushWeChatMessage;
|
||||||
const formatTime = require("../utils/utils").formatTime;
|
const formatTime = require('../common/utils').formatTime;
|
||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
@@ -11,16 +11,16 @@ function md2html(markdown) {
|
|||||||
return parser(lexer(markdown));
|
return parser(lexer(markdown));
|
||||||
}
|
}
|
||||||
|
|
||||||
router.get("/:description", (req, res, next) => {
|
router.get('/:description', (req, res, next) => {
|
||||||
req.query.description = req.params.description;
|
req.query.description = req.params.description;
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
|
|
||||||
router.all("/", (req, res) => {
|
router.all('/', (req, res) => {
|
||||||
let message = {
|
let message = {
|
||||||
title: req.query.title || req.body.title || "无标题",
|
title: req.query.title || req.body.title || '无标题',
|
||||||
status: 1,
|
status: 1,
|
||||||
created_by: "系统", // TODO
|
created_by: '系统', // TODO
|
||||||
created_time: formatTime(),
|
created_time: formatTime(),
|
||||||
description: req.query.description || req.body.description,
|
description: req.query.description || req.body.description,
|
||||||
content: md2html(req.query.content || req.body.content),
|
content: md2html(req.query.content || req.body.content),
|
||||||
@@ -42,16 +42,16 @@ router.all("/", (req, res) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get("/detail/:id", (req, res) => {
|
router.get('/detail/:id', (req, res) => {
|
||||||
const id = req.params.id;
|
const id = req.params.id;
|
||||||
Message.getById(id)
|
Message.getById(id)
|
||||||
.then((value) => {
|
.then((value) => {
|
||||||
console.log(value);
|
console.log(value);
|
||||||
res.render("message", value[0]);
|
res.render('message', value[0]);
|
||||||
})
|
})
|
||||||
.catch((reason) => {
|
.catch((reason) => {
|
||||||
res.render("info", {
|
res.render('info', {
|
||||||
message: "获取该消息时发生了错误:" + reason,
|
message: '获取该消息时发生了错误:' + reason,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
const knex = require("knex");
|
|
||||||
const environment = process.env.NODE_ENV || "development";
|
|
||||||
const configuration = require("../knexfile")[environment];
|
|
||||||
|
|
||||||
const db = knex(configuration);
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
db: db,
|
|
||||||
};
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
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,
|
|
||||||
};
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
const axios = require("axios");
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
requestToken: function (app) {
|
|
||||||
let token = "";
|
|
||||||
axios
|
|
||||||
.get(
|
|
||||||
`https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${process.env.APP_ID}&secret=${process.env.APP_SECRET}`
|
|
||||||
)
|
|
||||||
.then((res) => {
|
|
||||||
if (res.data && res.data.access_token) {
|
|
||||||
console.log("Token requested.");
|
|
||||||
token = res.data.access_token;
|
|
||||||
app.locals.access_token = token;
|
|
||||||
process.env.access_token = token;
|
|
||||||
} else {
|
|
||||||
console.error(res.data);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return token;
|
|
||||||
},
|
|
||||||
|
|
||||||
pushWeChatMessage: function (description, link) {
|
|
||||||
// Reference: https://mp.weixin.qq.com/debug/cgi-bin/readtmpl?t=tmplmsg/faq_tmpl
|
|
||||||
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: description } };
|
|
||||||
return axios.post(
|
|
||||||
`https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=${access_token}`,
|
|
||||||
request_data
|
|
||||||
);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
Reference in New Issue
Block a user