Skip to content

Commit 6efaad0

Browse files
committed
fix: תמיכה בבקשות POST (closes #5)
ההגדרה api_url_post=yes. ראה פירוט בreadme וב-issue המקושר
1 parent 89d8488 commit 6efaad0

File tree

4 files changed

+65
-22
lines changed

4 files changed

+65
-22
lines changed

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ npm i yemot-router2
2525

2626
# **Changelog**
2727
<details>
28-
<summary>5.0.0 - 5.1.1</summary>
28+
<summary>5.0.0 - 5.1.2</summary>
2929

3030
**5.0.0**
3131
גרסה 5 כוללת שינויים רבים, כולל שינויים שוברים, ושכתוב משמעותי של הAPI הפנימי.
@@ -50,6 +50,10 @@ npm i yemot-router2
5050

5151
**5.1.1**
5252
תוקן באג שבו ניתוק מחוץ לפונקציה (לדוגמה השמעת id_list_message, יציאה מהשלוחה ואז ניתוק) היה מפעיל את הפונקציה.
53+
54+
**5.1.2**
55+
תוקנה התמיכה בבקשות POST (ההגדרה api_url_post=yes בשלוחה), שבהן הפרמטרים נשלחים בbody ולא בquery
56+
נוסף פרוקסי שמיירט נסיון גישה לreq.query בבקשות POST או לreq.body בבקשות GET, ומציג הסבר מפורט לתיקון.
5357
</details>
5458

5559
<details>

exemple.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ router.get('/', async (call) => {
5151
call.go_to_folder('/1');
5252
});
5353

54+
app.use(express.urlencoded({ extended: true })); // A must if you want to use post requests (api_url_post=yes)
55+
5456
app.use('/', router);
5557

5658
const port = 3000;

lib/call.js

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,16 @@ class Call {
5252

5353
await this.blockRunningUntilNextRequest();
5454

55-
if (!this.req.query[valName]) {
55+
const values = this.req.method === 'POST' ? this.req.body : this.req.query;
56+
if (!values[valName]) {
5657
await sendResp();
5758
}
5859
};
5960

6061
await sendResp();
6162

62-
return this.req.query[valName] ?? false;
63+
const values = this.req.method === 'POST' ? this.req.body : this.req.query;
64+
return values[valName] ?? false;
6365
}
6466

6567
go_to_folder (folder) {
@@ -131,17 +133,20 @@ class Call {
131133
this.req = req;
132134
this.res = res;
133135
this.query = req.query;
136+
this.body = req.body;
134137
this.params = req.params;
135138

136-
this.did = this.query.ApiDID;
137-
this.phone = this.query.ApiPhone;
138-
this.callId = this.query.ApiCallId;
139-
this.real_did = this.query.ApiRealDID;
140-
this.extension = this.query.ApiExtension;
139+
const values = this.req.method === 'POST' ? this.req.body : this.req.query;
141140

142-
const queryToCopy = Object.keys(this.query).filter((key) => key.startsWith('Api'));
141+
this.did = values.ApiDID;
142+
this.phone = values.ApiPhone;
143+
this.callId = values.ApiCallId;
144+
this.real_did = values.ApiRealDID;
145+
this.extension = values.ApiExtension;
146+
147+
const queryToCopy = Object.keys(values).filter((key) => key.startsWith('Api'));
143148
for (const key of queryToCopy) {
144-
this[key] = this.query[key];
149+
this[key] = values[key];
145150
}
146151
}
147152

lib/yemot_router.js

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const Router = require('express').Router;
44
const EventEmitter = require('events');
55
const colors = require('colors');
66

7-
function shiftDuplicatedFromQuery (query) {
7+
function shiftDuplicatedValues (query) {
88
/** אם ערך מסויים יש כמה פעמים, שייקבע רק האחרון **/
99
for (const key of Object.keys(query)) {
1010
const iterator = query[key];
@@ -75,46 +75,78 @@ function YemotRouter (options = {}) {
7575
}
7676

7777
return new Proxy(Router(), {
78-
get: function (target, prop) {
79-
if (['get', 'post', 'all', 'add_fn'].includes(prop)) {
78+
get: function (target, propName) {
79+
if (['get', 'post', 'all', 'add_fn'].includes(propName)) {
8080
return (path, fn) => {
81-
target[prop === 'add_fn' ? 'all' : prop](path, (req, res, next) => {
82-
if (prop === 'add_fn') {
81+
target[propName === 'add_fn' ? 'all' : propName](path, (req, res, next) => {
82+
if (propName === 'add_fn') {
8383
console.warn('[warning] add_fn is deprecated, use get/post/all instead');
8484
}
85+
86+
if (req.method === 'POST' && !req.body) {
87+
throw new Error('YemotRouter: it look you use api_url_post=yes, but you didn\'t include express.urlencoded({ extended: true }) middleware! (https://expressjs.com/en/4x/api.html#express.urlencoded)');
88+
}
89+
90+
const values = req.method === 'POST' ? req.body : req.query;
8591
const requiredValues = ['ApiPhone', 'ApiDID', 'ApiExtension', 'ApiCallId'];
86-
if (requiredValues.some((key) => !Object.prototype.hasOwnProperty.call(req.query, key))) {
92+
if (requiredValues.some((key) => !Object.prototype.hasOwnProperty.call(values, key))) {
8793
return res.json({ message: 'request is not valid yemot request' });
8894
}
8995

90-
req.query = shiftDuplicatedFromQuery(req.query);
96+
if (req.method === 'POST') {
97+
req.body = shiftDuplicatedValues(req.body);
98+
} else {
99+
req.query = shiftDuplicatedValues(req.query);
100+
}
91101

92-
const callId = req.query.ApiCallId;
102+
const callId = values.ApiCallId;
93103

94104
let isNewCall = false;
95105
let currentCall = activeCalls[callId];
96106
if (!currentCall) {
97107
isNewCall = true;
98-
if (req.query.hangup === 'yes') {
108+
if (values.hangup === 'yes') {
99109
logger(callId, '👋 call is hangup (outside the function)');
100110
return res.json({ message: 'hangup' });
101111
}
102112
currentCall = new Call(callId, eventsEmitter, ops);
103113
activeCalls[callId] = currentCall;
104-
logger(callId, `📞 new call - from ${req.query.ApiPhone}`);
114+
logger(callId, `📞 new call - from ${values.ApiPhone}`);
105115
}
106116

107117
currentCall.setReqValues(req, res);
108118

119+
if (req.method === 'POST') {
120+
const _query = req.query;
121+
const proxy = new Proxy(_query, {
122+
get: function (target, propName) {
123+
console.warn(`[${req.path}] You are trying to access the '${propName}' property on the request query string object, but you have set the 'api_url_post=yes' option. This means that the yemot values will be in the request body object, not the request query object.\nPlease update your code accordingly - instead of call.req.query.propName, use call.req.body.propName.`);
124+
return target[propName];
125+
}
126+
});
127+
req.query = proxy;
128+
currentCall.query = proxy;
129+
} else {
130+
const _body = req.body;
131+
const proxy = new Proxy(_body, {
132+
get: function (target, propName) {
133+
if (!target[propName]) console.warn(`[${req.path}] If you do not use the api_url_post=yes option, the values will be in the call.req.query object, not the call.req.body object.\nPlease update your code accordingly - instead of call.req.body.propName, use call.req.query.propName, or use the api_url_post=yes option.`);
134+
return target[propName];
135+
}
136+
});
137+
req.body = proxy;
138+
currentCall.body = proxy;
139+
}
140+
109141
if (isNewCall) {
110142
makeNewCall(fn, callId, currentCall);
111143
} else {
112-
eventsEmitter.emit(callId, req.query.hangup === 'yes');
144+
eventsEmitter.emit(callId, values.hangup === 'yes');
113145
}
114146
});
115147
};
116148
} else {
117-
return target[prop];
149+
return target[propName];
118150
}
119151
}
120152
});

0 commit comments

Comments
 (0)