Skip to content

Commit

Permalink
fix: תמיכה בבקשות POST (closes #5)
Browse files Browse the repository at this point in the history
ההגדרה api_url_post=yes. ראה פירוט בreadme וב-issue המקושר
  • Loading branch information
ShlomoCode committed Apr 28, 2023
1 parent 89d8488 commit 6efaad0
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 22 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ npm i yemot-router2

# **Changelog**
<details>
<summary>5.0.0 - 5.1.1</summary>
<summary>5.0.0 - 5.1.2</summary>

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

**5.1.1**
תוקן באג שבו ניתוק מחוץ לפונקציה (לדוגמה השמעת id_list_message, יציאה מהשלוחה ואז ניתוק) היה מפעיל את הפונקציה.

**5.1.2**
תוקנה התמיכה בבקשות POST (ההגדרה api_url_post=yes בשלוחה), שבהן הפרמטרים נשלחים בbody ולא בquery
נוסף פרוקסי שמיירט נסיון גישה לreq.query בבקשות POST או לreq.body בבקשות GET, ומציג הסבר מפורט לתיקון.
</details>

<details>
Expand Down
2 changes: 2 additions & 0 deletions exemple.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ router.get('/', async (call) => {
call.go_to_folder('/1');
});

app.use(express.urlencoded({ extended: true })); // A must if you want to use post requests (api_url_post=yes)

app.use('/', router);

const port = 3000;
Expand Down
23 changes: 14 additions & 9 deletions lib/call.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,16 @@ class Call {

await this.blockRunningUntilNextRequest();

if (!this.req.query[valName]) {
const values = this.req.method === 'POST' ? this.req.body : this.req.query;
if (!values[valName]) {
await sendResp();
}
};

await sendResp();

return this.req.query[valName] ?? false;
const values = this.req.method === 'POST' ? this.req.body : this.req.query;
return values[valName] ?? false;
}

go_to_folder (folder) {
Expand Down Expand Up @@ -131,17 +133,20 @@ class Call {
this.req = req;
this.res = res;
this.query = req.query;
this.body = req.body;
this.params = req.params;

this.did = this.query.ApiDID;
this.phone = this.query.ApiPhone;
this.callId = this.query.ApiCallId;
this.real_did = this.query.ApiRealDID;
this.extension = this.query.ApiExtension;
const values = this.req.method === 'POST' ? this.req.body : this.req.query;

const queryToCopy = Object.keys(this.query).filter((key) => key.startsWith('Api'));
this.did = values.ApiDID;
this.phone = values.ApiPhone;
this.callId = values.ApiCallId;
this.real_did = values.ApiRealDID;
this.extension = values.ApiExtension;

const queryToCopy = Object.keys(values).filter((key) => key.startsWith('Api'));
for (const key of queryToCopy) {
this[key] = this.query[key];
this[key] = values[key];
}
}

Expand Down
56 changes: 44 additions & 12 deletions lib/yemot_router.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const Router = require('express').Router;
const EventEmitter = require('events');
const colors = require('colors');

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

return new Proxy(Router(), {
get: function (target, prop) {
if (['get', 'post', 'all', 'add_fn'].includes(prop)) {
get: function (target, propName) {
if (['get', 'post', 'all', 'add_fn'].includes(propName)) {
return (path, fn) => {
target[prop === 'add_fn' ? 'all' : prop](path, (req, res, next) => {
if (prop === 'add_fn') {
target[propName === 'add_fn' ? 'all' : propName](path, (req, res, next) => {
if (propName === 'add_fn') {
console.warn('[warning] add_fn is deprecated, use get/post/all instead');
}

if (req.method === 'POST' && !req.body) {
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)');
}

const values = req.method === 'POST' ? req.body : req.query;
const requiredValues = ['ApiPhone', 'ApiDID', 'ApiExtension', 'ApiCallId'];
if (requiredValues.some((key) => !Object.prototype.hasOwnProperty.call(req.query, key))) {
if (requiredValues.some((key) => !Object.prototype.hasOwnProperty.call(values, key))) {
return res.json({ message: 'request is not valid yemot request' });
}

req.query = shiftDuplicatedFromQuery(req.query);
if (req.method === 'POST') {
req.body = shiftDuplicatedValues(req.body);
} else {
req.query = shiftDuplicatedValues(req.query);
}

const callId = req.query.ApiCallId;
const callId = values.ApiCallId;

let isNewCall = false;
let currentCall = activeCalls[callId];
if (!currentCall) {
isNewCall = true;
if (req.query.hangup === 'yes') {
if (values.hangup === 'yes') {
logger(callId, '👋 call is hangup (outside the function)');
return res.json({ message: 'hangup' });
}
currentCall = new Call(callId, eventsEmitter, ops);
activeCalls[callId] = currentCall;
logger(callId, `📞 new call - from ${req.query.ApiPhone}`);
logger(callId, `📞 new call - from ${values.ApiPhone}`);
}

currentCall.setReqValues(req, res);

if (req.method === 'POST') {
const _query = req.query;
const proxy = new Proxy(_query, {
get: function (target, propName) {
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.`);
return target[propName];
}
});
req.query = proxy;
currentCall.query = proxy;
} else {
const _body = req.body;
const proxy = new Proxy(_body, {
get: function (target, propName) {
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.`);
return target[propName];
}
});
req.body = proxy;
currentCall.body = proxy;
}

if (isNewCall) {
makeNewCall(fn, callId, currentCall);
} else {
eventsEmitter.emit(callId, req.query.hangup === 'yes');
eventsEmitter.emit(callId, values.hangup === 'yes');
}
});
};
} else {
return target[prop];
return target[propName];
}
}
});
Expand Down

0 comments on commit 6efaad0

Please sign in to comment.