Skip to content

Commit

Permalink
Merge pull request #539 from hanshino:feature/customer-order
Browse files Browse the repository at this point in the history
Add Substitution field to CustomerOrder and optimize command insertion
  • Loading branch information
hanshino authored Nov 1, 2024
2 parents 76fb490 + 8b1712a commit 3f32720
Show file tree
Hide file tree
Showing 6 changed files with 171 additions and 100 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.up = function (knex) {
return knex.schema.table("CustomerOrder", table => {
table.json("Substitution").nullable().defaultTo(null).after("Reply");
});
};

/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.down = function (knex) {
return knex.schema.table("CustomerOrder", table => {
table.dropColumn("substitution");
});
};
6 changes: 3 additions & 3 deletions app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@
"migrate": "knex migrate:latest"
},
"dependencies": {
"@sentry/node": "^8.35.0",
"@sentry/node": "^8.36.0",
"ajv": "^8.17.1",
"ajv-formats": "^3.0.1",
"axios": "1.7.7",
"bottender": "1.5.5",
"brotli": "^1.3.3",
"cheerio": "^1.0.0",
"config": "^3.3.12",
"cron": "^3.1.7",
"cron": "^3.1.8",
"date-format": "^4.0.14",
"express": "^4.21.1",
"express-rate-limit": "^7.4.1",
Expand All @@ -36,7 +36,7 @@
"moment": "^2.30.1",
"mysql2": "^3.11.3",
"redis": "^4.7.0",
"socket.io": "^4.8.0",
"socket.io": "^4.8.1",
"sqlite3": "^5.1.7",
"table": "^6.8.2",
"uuid-random": "^1.3.2"
Expand Down
8 changes: 2 additions & 6 deletions app/src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -286,12 +286,8 @@ function CustomerOrder(context) {

return [
text(/^[#.]?(指令列表|orderlist)$/, showOrderManager),
text(/^[#.]?新增指令/, (context, props) =>
customerOrder.insertCustomerOrder(context, props, 1)
),
text(/^[#.]?新增關鍵字指令/, (context, props) =>
customerOrder.insertCustomerOrder(context, props, 2)
),
text(/^[#.]?新增指令/, withProps(customerOrder.insertCustomerOrder, { touchType: 1 })),
text(/^[#.]?新增關鍵字指令/, withProps(customerOrder.insertCustomerOrder, { touchType: 2 })),
text(
/^[#.]?[移刪]除指令(\s*(?<order>\S+))?(\s*(?<orderKey>\S+))?$/,
customerOrder.deleteCustomerOrder
Expand Down
63 changes: 44 additions & 19 deletions app/src/controller/application/CustomerOrder.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const random = require("math-random");
const CustomerOrderTemplate = require("../../templates/application/CustomerOrder");
const { send } = require("../../templates/application/Order");
const { recordSign } = require("../../util/traffic");
const { get } = require("lodash");

function CusOrderException(message, code = 0) {
this.message = message;
Expand All @@ -18,7 +19,7 @@ function CusOrderException(message, code = 0) {
* @return {Object}
*/
function initialReply(strReply) {
var replyDatas = strReply
let replyDatas = strReply
.split(/\|/)
.filter(reply => reply.trim() !== "")
.map(reply => {
Expand Down Expand Up @@ -80,16 +81,17 @@ function handleSender(param) {
* 新增自訂指令
* @param {Context} context
* @param {Object} props
* @param {Number} touchType 觸發類型,1:完全符合,2:部分符合
* @param {Number} props.touchType 觸發類型,1:完全符合,2:部分符合
*/
exports.insertCustomerOrder = async (context, props, touchType = 1) => {
exports.insertCustomerOrder = async (context, props) => {
try {
recordSign("insertCustomerOrder");
const param = minimist(context.event.message.text.split(/\s+/));
const { touchType } = props;

var [prefix, order] = param._;
var reply = context.event.message.text.replace(prefix, "").replace(order, "").trim();
var [sourceId, userId] = getSourceId(context);
let [prefix, order] = param._;
let reply = context.event.message.text.replace(prefix, "").replace(order, "").trim();
let [sourceId, userId] = getSourceId(context);

if (order === undefined || reply === undefined) {
CustomerOrderTemplate[context.platform].showInsertManual(context);
Expand All @@ -98,8 +100,30 @@ exports.insertCustomerOrder = async (context, props, touchType = 1) => {

reply = reply.toString();

var replyDatas = initialReply(reply);
var { name, iconUrl } = handleSender(param);
const mentionees = get(context, "event.message.mention.mentionees", []);
let substitution = {};
// 如果 reply 內容有 mention,需轉換為替代字元
mentionees.forEach((mentionee, idx) => {
const name = get(context, "event.message.text", "").substring(
mentionee.index,
mentionee.index + mentionee.length
);

// @all 不處理
if (mentionee.type === "all") return;

substitution[`user${idx}`] = {
type: "mention",
mentionee: {
type: "user",
userId: mentionee.userId,
},
};
reply = reply.replace(name, `{user${idx}}`);
});

let replyDatas = initialReply(reply);
let { name, iconUrl } = handleSender(param);
let orderKey = uuid();

let params = replyDatas.map((data, index) => ({
Expand All @@ -110,6 +134,7 @@ exports.insertCustomerOrder = async (context, props, touchType = 1) => {
touchType,
MessageType: data.type,
Reply: data.data,
Substitution: substitution,
CreateDTM: new Date(),
CreateUser: userId,
ModifyUser: userId,
Expand Down Expand Up @@ -155,13 +180,13 @@ function getSourceId(context) {
* @param {Context} context
*/
exports.CustomerOrderDetect = async context => {
var [sourceId] = getSourceId(context);
var orderDatas = await CustomerOrderModel.queryOrderBySourceId(sourceId, 1);
let [sourceId] = getSourceId(context);
let orderDatas = await CustomerOrderModel.queryOrderBySourceId(sourceId, 1);

// 尚未建立任何指令
if (orderDatas.length === 0) return false;

var chosenOrderKey = chooseOrder(orderDatas);
let chosenOrderKey = chooseOrder(orderDatas);

if (chosenOrderKey === false) return false;
recordSign("CustomerOrderDetect");
Expand Down Expand Up @@ -245,12 +270,12 @@ exports.deleteCustomerOrder = async (context, { match }) => {
return;
}

var [sourceId, userId] = getSourceId(context);
let [sourceId, userId] = getSourceId(context);

var deleteOrders = await CustomerOrderModel.queryOrderToDelete(order, sourceId);
let deleteOrders = await CustomerOrderModel.queryOrderToDelete(order, sourceId);

if (deleteOrders.length === 0) throw new CusOrderException(`未搜尋到"${order}"的指令`);
var { orderKey: key } = autoComplete(orderKey, deleteOrders);
let { orderKey: key } = autoComplete(orderKey, deleteOrders);
// 剛好只有一筆符合刪除條件
if (deleteOrders.length === 1 || key !== undefined) {
await CustomerOrderModel.setStatus(
Expand Down Expand Up @@ -289,7 +314,7 @@ exports.api = {};

exports.api.fetchCustomerOrders = async (req, res) => {
const { sourceId } = req.params;
var orderDatas = await CustomerOrderModel.queryOrderBySourceId(sourceId);
let orderDatas = await CustomerOrderModel.queryOrderBySourceId(sourceId);

let userIds = [];
orderDatas.forEach(data => {
Expand All @@ -311,7 +336,7 @@ exports.api.updateOrder = async (req, res) => {
const { userId } = req.profile;

try {
var updateResult = await CustomerOrderModel.updateOrder(sourceId, req.body, userId);
let updateResult = await CustomerOrderModel.updateOrder(sourceId, req.body, userId);
if (updateResult === false) throw new CusOrderException("Update Failed", 2);

res.json({});
Expand All @@ -331,8 +356,8 @@ exports.api.insertOrder = async (req, res) => {
const { body: orderDatas, profile } = req;

try {
var { order, senderName, senderIcon, touchType } = orderDatas;
var orderKey = uuid();
let { order, senderName, senderIcon, touchType } = orderDatas;
let orderKey = uuid();

if ([order, touchType].includes("")) throw new CusOrderException("Bad Request.");
if ([order, touchType].includes(null)) throw new CusOrderException("Bad Request.");
Expand All @@ -346,7 +371,7 @@ exports.api.insertOrder = async (req, res) => {
throw new CusOrderException("Bad Request.");
});

var params = orderDatas.replyDatas.map((data, index) => ({
let params = orderDatas.replyDatas.map((data, index) => ({
No: index,
sourceId,
orderKey,
Expand Down
20 changes: 16 additions & 4 deletions app/src/templates/application/Order.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const CharacterModel = require("../../model/princess/character");

/**
* 發送訊息整合,整合多平台發送方式
* @param {Context} context
* @param {import("bottender").LineContext} context
* @param {Array.<Object>} replyData
* @param {String|Number} replyData.no
* @param {String} replyData.messageType
Expand All @@ -21,13 +21,25 @@ exports.send = (context, replyDatas, sender = { name: null, iconUrl: null }) =>
replyDatas
.sort((a, b) => a.no - b.no)
.forEach(data => {
let content = handleText(data.reply, context);
switch (data.messageType) {
const { reply, messageType, substitution } = data;
let content = handleText(reply, context);
switch (messageType) {
case "image":
_sendImage(context, content, sender);
return;
case "text":
context.replyText(content, { sender });
if (substitution !== null) {
context.reply([
{
type: "textV2",
text: content,
sender,
substitution,
},
]);
} else {
context.replyText(content, { sender });
}
return;
}
});
Expand Down
Loading

0 comments on commit 3f32720

Please sign in to comment.