shadowx-fca 2.5.0 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shadowx-fca",
3
- "version": "2.5.0",
3
+ "version": "2.7.0",
4
4
  "description": "Unofficial Facebook Chat API for Node.js with Auto-Update System - modify by Mueid Mursalin Rifat",
5
5
  "main": "index.js",
6
6
  "files": [
@@ -50,6 +50,6 @@
50
50
  "ws": "^8.18.1"
51
51
  },
52
52
  "engines": {
53
- "node": ">=14.0.0"
53
+ "node": ">=16.0.0"
54
54
  }
55
55
  }
package/src/GetBotInfo.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
- // sahilchat-fca — GetBotInfo
3
- // Author: S4hiilAns4ri (github.com/S4hiilAns4ri)
2
+ // shadowx-fca — GetBotInfo
3
+ // Author: Modified for shadowx-fca
4
4
 
5
5
  const utils = require('../utils');
6
6
 
@@ -12,7 +12,7 @@ module.exports = (defaultFuncs, api, ctx) => {
12
12
  */
13
13
  return function GetBotInfo(netData) {
14
14
  if (!netData || !Array.isArray(netData)) {
15
- utils.error("GetBotInfo", "netData is not a valid array.");
15
+ utils.log("GetBotInfo", "netData is not a valid array.");
16
16
  return null;
17
17
  }
18
18
 
@@ -20,10 +20,14 @@ module.exports = (defaultFuncs, api, ctx) => {
20
20
  for (const scriptData of netData) {
21
21
  if (!scriptData.require) continue;
22
22
  for (const req of scriptData.require) {
23
- if (Array.isArray(req) && req[0] === key && req[2]) return req[2];
24
- if (Array.isArray(req) && req[3]?.[0]?.__bbox?.define) {
23
+ if (Array.isArray(req) && req[0] === key && req[2]) {
24
+ return req[2];
25
+ }
26
+ if (Array.isArray(req) && req[3] && req[3][0] && req[3][0].__bbox && req[3][0].__bbox.define) {
25
27
  for (const def of req[3][0].__bbox.define) {
26
- if (Array.isArray(def) && def[0].endsWith(key) && def[2]) return def[2];
28
+ if (Array.isArray(def) && def[0] && def[0].endsWith(key) && def[2]) {
29
+ return def[2];
30
+ }
27
31
  }
28
32
  }
29
33
  }
@@ -33,25 +37,30 @@ module.exports = (defaultFuncs, api, ctx) => {
33
37
 
34
38
  const currentUserData = findConfig("CurrentUserInitialData");
35
39
  const dtsgInitialData = findConfig("DTSGInitialData");
36
- const dtsgInitData = findConfig("DTSGInitData");
37
- const lsdData = findConfig("LSD");
40
+ const dtsgInitData = findConfig("DTSGInitData");
41
+ const lsdData = findConfig("LSD");
38
42
 
39
43
  if (!currentUserData || !dtsgInitialData) {
40
- utils.error("GetBotInfo", "Could not find required data (CurrentUserInitialData or DTSGInitialData).");
44
+ utils.log("GetBotInfo", "Could not find required data (CurrentUserInitialData or DTSGInitialData).");
41
45
  return null;
42
46
  }
43
47
 
44
48
  return {
45
- name : currentUserData.NAME,
46
- firstName : currentUserData.SHORT_NAME,
47
- uid : currentUserData.USER_ID,
48
- appID : currentUserData.APP_ID,
49
- dtsgToken : dtsgInitialData.token,
50
- lsdToken : lsdData?.token,
51
- dtsgInit : dtsgInitData ? { token: dtsgInitData.token, async_get_token: dtsgInitData.async_get_token } : undefined,
52
- getCtx : (key) => ctx[key],
53
- getOptions : (key) => ctx.globalOptions[key],
54
- getRegion : () => ctx?.region,
49
+ name: currentUserData.NAME || null,
50
+ firstName: currentUserData.SHORT_NAME || null,
51
+ uid: currentUserData.USER_ID || null,
52
+ appID: currentUserData.APP_ID || null,
53
+ dtsgToken: dtsgInitialData.token || null,
54
+ lsdToken: lsdData?.token || null,
55
+ dtsgInit: dtsgInitData ? {
56
+ token: dtsgInitData.token,
57
+ async_get_token: dtsgInitData.async_get_token
58
+ } : undefined,
59
+ getCtx: (key) => ctx ? ctx[key] : null,
60
+ getOptions: (key) => ctx && ctx.globalOptions ? ctx.globalOptions[key] : null,
61
+ getRegion: () => ctx?.region || null,
62
+ getUserID: () => ctx?.userID || currentUserData?.USER_ID || null,
63
+ getJar: () => ctx?.jar || null
55
64
  };
56
65
  };
57
- };
66
+ };
package/src/OldMessage.js CHANGED
@@ -19,9 +19,10 @@ module.exports = function (defaultFuncs, api, ctx) {
19
19
  function uploadAttachment(attachments, callback) {
20
20
  var uploads = [];
21
21
 
22
- // create an array of promises
23
22
  for (var i = 0; i < attachments.length; i++) {
24
- if (!utils.isReadableStream(attachments[i])) throw { error: "Attachment should be a readable stream and not " + utils.getType(attachments[i]) + "." };
23
+ if (!utils.isReadableStream(attachments[i])) {
24
+ throw { error: "Attachment should be a readable stream and not " + utils.getType(attachments[i]) + "." };
25
+ }
25
26
  var form = {
26
27
  upload_1024: attachments[i],
27
28
  voice_clip: "true"
@@ -33,14 +34,11 @@ module.exports = function (defaultFuncs, api, ctx) {
33
34
  .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
34
35
  .then(function (resData) {
35
36
  if (resData.error) throw resData;
36
- // We have to return the data unformatted unless we want to change it
37
- // back in sendMessage.
38
37
  return resData.payload.metadata[0];
39
38
  })
40
39
  );
41
40
  }
42
41
 
43
- // resolve all promises
44
42
  bluebird
45
43
  .all(uploads)
46
44
  .then(resData => callback(null, resData))
@@ -72,26 +70,25 @@ module.exports = function (defaultFuncs, api, ctx) {
72
70
  }
73
71
 
74
72
  function sendContent(form, threadID, isSingleUser, messageAndOTID, callback) {
75
- // There are three cases here:
76
- // 1. threadID is of type array, where we're starting a new group chat with users
77
- // specified in the array.
78
- // 2. User is sending a message to a specific user.
79
- // 3. No additional form params and the message goes to an existing group chat.
80
73
  if (utils.getType(threadID) === "Array") {
81
- for (var i = 0; i < threadID.length; i++) form["specific_to_list[" + i + "]"] = "fbid:" + threadID[i];
74
+ for (var i = 0; i < threadID.length; i++) {
75
+ form["specific_to_list[" + i + "]"] = "fbid:" + threadID[i];
76
+ }
82
77
  form["specific_to_list[" + threadID.length + "]"] = "fbid:" + ctx.userID;
83
78
  form["client_thread_id"] = "root:" + messageAndOTID;
84
79
  log.info("sendMessage", "Sending message to multiple users: " + threadID);
85
- }
86
- else {
87
- // This means that threadID is the id of a user, and the chat
88
- // is a single person chat
89
- if (isSingleUser) {
80
+ } else {
81
+ // Auto-detect if it's a DM
82
+ const threadIDStr = threadID.toString();
83
+ const isDM = isSingleUser === true || threadIDStr.length === 15 || !threadIDStr.match(/^\d{16,}$/);
84
+
85
+ if (isDM) {
90
86
  form["specific_to_list[0]"] = "fbid:" + threadID;
91
87
  form["specific_to_list[1]"] = "fbid:" + ctx.userID;
92
88
  form["other_user_fbid"] = threadID;
89
+ } else {
90
+ form["thread_fbid"] = threadID;
93
91
  }
94
- else form["thread_fbid"] = threadID;
95
92
  }
96
93
 
97
94
  if (ctx.globalOptions.pageID) {
@@ -113,21 +110,18 @@ module.exports = function (defaultFuncs, api, ctx) {
113
110
  if (resData.error) {
114
111
  if (resData.error === 1545012) {
115
112
  log.warn("sendMessage", "Got error 1545012. This might mean that you're not part of the conversation " + threadID);
116
- }
117
- else {
113
+ } else {
118
114
  log.error("sendMessage", resData);
119
115
  }
120
116
  return callback(resData);
121
117
  }
122
118
 
123
119
  var messageInfo = resData.payload.actions.reduce(function (p, v) {
124
- return (
125
- {
126
- threadID: v.thread_fbid,
127
- messageID: v.message_id,
128
- timestamp: v.timestamp
129
- } || p
130
- );
120
+ return {
121
+ threadID: v.thread_fbid,
122
+ messageID: v.message_id,
123
+ timestamp: v.timestamp
124
+ } || p;
131
125
  }, null);
132
126
 
133
127
  return callback(null, messageInfo);
@@ -139,17 +133,6 @@ module.exports = function (defaultFuncs, api, ctx) {
139
133
  });
140
134
  }
141
135
 
142
- function send(form, threadID, messageAndOTID, callback, isGroup) {
143
- // We're doing a query to this to check if the given id is the id of
144
- // a user or of a group chat. The form will be different depending
145
- // on that.
146
- if (utils.getType(threadID) === "Array") sendContent(form, threadID, false, messageAndOTID, callback);
147
- else {
148
- if (utils.getType(isGroup) != "Boolean") sendContent(form, threadID, threadID.length === 15, messageAndOTID, callback);
149
- else sendContent(form, threadID, !isGroup, messageAndOTID, callback);
150
- }
151
- }
152
-
153
136
  function handleUrl(msg, form, callback, cb) {
154
137
  if (msg.url) {
155
138
  form["shareable_attachment[share_type]"] = "100";
@@ -158,13 +141,16 @@ module.exports = function (defaultFuncs, api, ctx) {
158
141
  form["shareable_attachment[share_params]"] = params;
159
142
  cb();
160
143
  });
144
+ } else {
145
+ cb();
161
146
  }
162
- else cb();
163
147
  }
164
148
 
165
149
  function handleLocation(msg, form, callback, cb) {
166
150
  if (msg.location) {
167
- if (msg.location.latitude == null || msg.location.longitude == null) return callback({ error: "location property needs both latitude and longitude" });
151
+ if (msg.location.latitude == null || msg.location.longitude == null) {
152
+ return callback({ error: "location property needs both latitude and longitude" });
153
+ }
168
154
  form["location_attachment[coordinates][latitude]"] = msg.location.latitude;
169
155
  form["location_attachment[coordinates][longitude]"] = msg.location.longitude;
170
156
  form["location_attachment[is_current_location]"] = !!msg.location.current;
@@ -178,11 +164,17 @@ module.exports = function (defaultFuncs, api, ctx) {
178
164
  }
179
165
 
180
166
  function handleEmoji(msg, form, callback, cb) {
181
- if (msg.emojiSize != null && msg.emoji == null) return callback({ error: "emoji property is empty" });
167
+ if (msg.emojiSize != null && msg.emoji == null) {
168
+ return callback({ error: "emoji property is empty" });
169
+ }
182
170
  if (msg.emoji) {
183
171
  if (msg.emojiSize == null) msg.emojiSize = "medium";
184
- if (msg.emojiSize != "small" && msg.emojiSize != "medium" && msg.emojiSize != "large") return callback({ error: "emojiSize property is invalid" });
185
- if (form["body"] != null && form["body"] != "") return callback({ error: "body is not empty" });
172
+ if (msg.emojiSize != "small" && msg.emojiSize != "medium" && msg.emojiSize != "large") {
173
+ return callback({ error: "emojiSize property is invalid" });
174
+ }
175
+ if (form["body"] != null && form["body"] != "") {
176
+ return callback({ error: "body is not empty" });
177
+ }
186
178
  form["body"] = msg.emoji;
187
179
  form["tags[0]"] = "hot_emoji_size:" + msg.emojiSize;
188
180
  }
@@ -197,23 +189,22 @@ module.exports = function (defaultFuncs, api, ctx) {
197
189
  form["video_ids"] = [];
198
190
  form["audio_ids"] = [];
199
191
 
200
- if (utils.getType(msg.attachment) !== "Array") msg.attachment = [msg.attachment];
201
- if (msg.attachment.every(e=>/_id$/.test(e[0]))) {
202
- //console.log(msg.attachment)
203
- msg.attachment.map(e=>form[`${e[0]}s`].push(e[1]));
204
- return cb();
205
- }
192
+ if (utils.getType(msg.attachment) !== "Array") {
193
+ msg.attachment = [msg.attachment];
194
+ }
195
+
206
196
  uploadAttachment(msg.attachment, function (err, files) {
207
197
  if (err) return callback(err);
208
198
  files.forEach(function (file) {
209
199
  var key = Object.keys(file);
210
- var type = key[0]; // image_id, file_id, etc
211
- form["" + type + "s"].push(file[type]); // push the id
200
+ var type = key[0];
201
+ form[type + "s"].push(file[type]);
212
202
  });
213
203
  cb();
214
204
  });
205
+ } else {
206
+ cb();
215
207
  }
216
- else cb();
217
208
  }
218
209
 
219
210
  function handleMention(msg, form, callback, cb) {
@@ -221,10 +212,16 @@ module.exports = function (defaultFuncs, api, ctx) {
221
212
  for (let i = 0; i < msg.mentions.length; i++) {
222
213
  const mention = msg.mentions[i];
223
214
  const tag = mention.tag;
224
- if (typeof tag !== "string") return callback({ error: "Mention tags must be strings." });
215
+ if (typeof tag !== "string") {
216
+ return callback({ error: "Mention tags must be strings." });
217
+ }
225
218
  const offset = msg.body.indexOf(tag, mention.fromIndex || 0);
226
- if (offset < 0) log.warn("handleMention", 'Mention for "' + tag + '" not found in message string.');
227
- if (mention.id == null) log.warn("handleMention", "Mention id should be non-null.");
219
+ if (offset < 0) {
220
+ log.warn("handleMention", 'Mention for "' + tag + '" not found in message string.');
221
+ }
222
+ if (mention.id == null) {
223
+ log.warn("handleMention", "Mention id should be non-null.");
224
+ }
228
225
 
229
226
  const id = mention.id || 0;
230
227
  const emptyChar = '\u200E';
@@ -239,44 +236,67 @@ module.exports = function (defaultFuncs, api, ctx) {
239
236
  }
240
237
 
241
238
  return function sendMessage(msg, threadID, callback, replyToMessage, isGroup) {
242
- typeof isGroup == "undefined" ? isGroup = null : "";
243
- if (!callback && (utils.getType(threadID) === "Function" || utils.getType(threadID) === "AsyncFunction")) return threadID({ error: "Pass a threadID as a second argument." });
244
- if (!replyToMessage && utils.getType(callback) === "String") {
239
+ // Handle parameter shifting
240
+ if (typeof callback === "string") {
241
+ isGroup = replyToMessage;
245
242
  replyToMessage = callback;
246
- callback = function () { };
243
+ callback = function () {};
244
+ } else if (typeof threadID === "function") {
245
+ callback = threadID;
246
+ threadID = null;
247
+ }
248
+
249
+ if (!callback || typeof callback !== "function") {
250
+ callback = function () {};
247
251
  }
248
252
 
249
- var resolveFunc = function () { };
250
- var rejectFunc = function () { };
253
+ var resolveFunc = function () {};
254
+ var rejectFunc = function () {};
251
255
  var returnPromise = new Promise(function (resolve, reject) {
252
256
  resolveFunc = resolve;
253
257
  rejectFunc = reject;
254
258
  });
255
259
 
256
- if (!callback) {
257
- callback = function (err, data) {
258
- if (err) return rejectFunc(err);
260
+ var originalCallback = callback;
261
+ callback = function (err, data) {
262
+ if (err) {
263
+ originalCallback(err);
264
+ rejectFunc(err);
265
+ } else {
266
+ originalCallback(null, data);
259
267
  resolveFunc(data);
260
- };
261
- }
268
+ }
269
+ };
262
270
 
263
271
  var msgType = utils.getType(msg);
264
272
  var threadIDType = utils.getType(threadID);
265
- var messageIDType = utils.getType(replyToMessage);
266
273
 
267
- if (msgType !== "String" && msgType !== "Object") return callback({ error: "Message should be of type string or object and not " + msgType + "." });
274
+ if (msgType !== "String" && msgType !== "Object") {
275
+ return callback({ error: "Message should be of type string or object and not " + msgType + "." });
276
+ }
277
+
278
+ if (threadIDType !== "Array" && threadIDType !== "Number" && threadIDType !== "String") {
279
+ return callback({ error: "ThreadID should be of type number, string, or array and not " + threadIDType + "." });
280
+ }
268
281
 
269
- // Changing this to accomodate an array of users
270
- if (threadIDType !== "Array" && threadIDType !== "Number" && threadIDType !== "String") return callback({ error: "ThreadID should be of type number, string, or array and not " + threadIDType + "." });
282
+ if (msgType === "String") {
283
+ msg = { body: msg };
284
+ }
271
285
 
272
- if (replyToMessage && messageIDType !== 'String') return callback({ error: "MessageID should be of type string and not " + threadIDType + "." });
286
+ // Determine isSingleUser
287
+ var isSingleUser = !isGroup;
288
+ if (isGroup === null || typeof isGroup === "undefined") {
289
+ const threadIDStr = threadID.toString();
290
+ isSingleUser = threadIDStr.length === 15 || !threadIDStr.match(/^\d{16,}$/);
291
+ }
273
292
 
274
- if (msgType === "String") msg = { body: msg };
275
293
  var disallowedProperties = Object.keys(msg).filter(prop => !allowedProperties[prop]);
276
- if (disallowedProperties.length > 0) return callback({ error: "Dissallowed props: `" + disallowedProperties.join(", ") + "`" });
294
+ if (disallowedProperties.length > 0) {
295
+ return callback({ error: "Dissallowed props: `" + disallowedProperties.join(", ") + "`" });
296
+ }
277
297
 
278
298
  var messageAndOTID = utils.generateOfflineThreadingID();
279
- // console.log(messageAndOTID)
299
+
280
300
  var form = {
281
301
  client: "mercury",
282
302
  action_type: "ma-type:user-generated-message",
@@ -307,51 +327,23 @@ module.exports = function (defaultFuncs, api, ctx) {
307
327
  manual_retry_cnt: "0",
308
328
  has_attachment: !!(msg.attachment || msg.url || msg.sticker),
309
329
  signatureID: utils.getSignatureID(),
310
- replied_to_message_id: replyToMessage
330
+ replied_to_message_id: replyToMessage || undefined
311
331
  };
312
- // console.log(form)
313
-
314
- const configSource = (global.GoatBot && global.GoatBot.config) ? global.GoatBot.config : ctx.config || {};
315
- const enableTypingIndicator = typeof configSource.enableTypingIndicator !== 'undefined' ? configSource.enableTypingIndicator : ctx.config?.enableTypingIndicator;
316
- const typingDuration = Number(configSource.typingDuration || ctx.config?.typingDuration || 4000);
317
-
318
- if (enableTypingIndicator) {
319
- api.sendTypingIndicator(true, threadID, () => {});
320
- const originalCallback = callback;
321
- callback = (err, data) => {
322
- api.sendTypingIndicator(false, threadID, () => {});
323
- originalCallback(err, data);
324
- };
325
- setTimeout(() => {
326
- handleLocation(msg, form, callback, () =>
327
- handleSticker(msg, form, callback, () =>
328
- handleAttachment(msg, form, callback, () =>
329
- handleUrl(msg, form, callback, () =>
330
- handleEmoji(msg, form, callback, () =>
331
- handleMention(msg, form, callback, () =>
332
- sendContent(form, threadID, isSingleUser, messageAndOTID, callback)
333
- )
334
- )
335
- )
336
- )
337
- )
338
- );
339
- }, typingDuration);
340
- } else {
341
- handleLocation(msg, form, callback, () =>
342
- handleSticker(msg, form, callback, () =>
343
- handleAttachment(msg, form, callback, () =>
344
- handleUrl(msg, form, callback, () =>
345
- handleEmoji(msg, form, callback, () =>
346
- handleMention(msg, form, callback, () =>
347
- sendContent(form, threadID, isSingleUser, messageAndOTID, callback)
348
- )
349
- )
332
+
333
+ handleLocation(msg, form, callback, () =>
334
+ handleSticker(msg, form, callback, () =>
335
+ handleAttachment(msg, form, callback, () =>
336
+ handleUrl(msg, form, callback, () =>
337
+ handleEmoji(msg, form, callback, () =>
338
+ handleMention(msg, form, callback, () =>
339
+ sendContent(form, threadID, isSingleUser, messageAndOTID, callback)
350
340
  )
351
341
  )
352
342
  )
353
- );
354
- }
343
+ )
344
+ )
345
+ );
346
+
355
347
  return returnPromise;
356
348
  };
357
349
  };
package/src/comment.js CHANGED
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  const utils = require('../utils');
4
+ const log = require('npmlog'); // Add npmlog for proper logging
4
5
 
5
6
  /**
6
7
  * Handles the upload of attachments (images/videos) for a comment.
@@ -45,7 +46,7 @@ async function handleUpload(defaultFuncs, ctx, msg, form) {
45
46
  * @param {object} form - The main form object.
46
47
  */
47
48
  function handleURL(msg, form) {
48
- if (typeof msg.url === 'string') {
49
+ if (typeof msg.url === 'string' && msg.url.trim()) {
49
50
  form.input.attachments.push({
50
51
  link: {
51
52
  external: {
@@ -62,21 +63,21 @@ function handleURL(msg, form) {
62
63
  * @param {object} form - The main form object.
63
64
  */
64
65
  function handleMentions(msg, form) {
65
- if (!msg.mentions) return;
66
+ if (!msg.mentions || !Array.isArray(msg.mentions)) return;
66
67
 
67
68
  for (const item of msg.mentions) {
68
69
  const { tag, id, fromIndex } = item;
69
70
  if (typeof tag !== 'string' || !id) {
70
- utils.warn('createCommentPost', 'Mentions must have a string "tag" and an "id".');
71
+ log.warn('createCommentPost', 'Mentions must have a string "tag" and an "id".');
71
72
  continue;
72
73
  }
73
74
  const offset = msg.body.indexOf(tag, fromIndex || 0);
74
75
  if (offset < 0) {
75
- utils.warn('createCommentPost', `Mention for "${tag}" not found in message string.`);
76
+ log.warn('createCommentPost', `Mention for "${tag}" not found in message string.`);
76
77
  continue;
77
78
  }
78
79
  form.input.message.ranges.push({
79
- entity: { id },
80
+ entity: { id: String(id) },
80
81
  length: tag.length,
81
82
  offset
82
83
  });
@@ -124,8 +125,8 @@ async function createContent(defaultFuncs, ctx, form) {
124
125
  // Try to extract comment info from response
125
126
  try {
126
127
  const commentEdge = res?.data?.comment_create?.feedback_comment_edge;
127
- const id = commentEdge?.node?.id || null;
128
- const url = commentEdge?.node?.feedback?.url || null;
128
+ const id = commentEdge?.node?.id || null;
129
+ const url = commentEdge?.node?.feedback?.url || null;
129
130
  const count = res?.data?.comment_create?.feedback?.total_comment_count || 0;
130
131
  return { id, url, count };
131
132
  } catch (_) {
@@ -146,7 +147,10 @@ module.exports = function(defaultFuncs, api, ctx) {
146
147
  return async function createCommentPost(msg, postID, replyCommentID, callback) {
147
148
  let cb;
148
149
  const returnPromise = new Promise((resolve, reject) => {
149
- cb = (error, info) => info ? resolve(info) : reject(error);
150
+ cb = (error, info) => {
151
+ if (error) reject(error);
152
+ else resolve(info);
153
+ };
150
154
  });
151
155
 
152
156
  if (typeof replyCommentID === 'function') {
@@ -154,17 +158,26 @@ module.exports = function(defaultFuncs, api, ctx) {
154
158
  replyCommentID = null;
155
159
  }
156
160
  if (typeof callback === 'function') {
157
- cb = callback;
161
+ const originalCb = cb;
162
+ cb = (error, info) => {
163
+ if (error) {
164
+ callback(error);
165
+ originalCb(error);
166
+ } else {
167
+ callback(null, info);
168
+ originalCb(null, info);
169
+ }
170
+ };
158
171
  }
159
172
 
160
173
  if (typeof msg !== 'string' && typeof msg !== 'object') {
161
174
  const error = 'Message must be a string or an object.';
162
- utils.error('createCommentPost', error);
175
+ log.error('createCommentPost', error);
163
176
  return cb(error);
164
177
  }
165
178
  if (typeof postID !== 'string') {
166
179
  const error = 'postID must be a string.';
167
- utils.error('createCommentPost', error);
180
+ log.error('createCommentPost', error);
168
181
  return cb(error);
169
182
  }
170
183
 
@@ -203,11 +216,11 @@ module.exports = function(defaultFuncs, api, ctx) {
203
216
  handleSticker(messageObject, form);
204
217
  const info = await createContent(defaultFuncs, ctx, form);
205
218
  cb(null, info);
219
+ return info;
206
220
  } catch (err) {
207
- utils.error('createCommentPost', err);
221
+ log.error('createCommentPost', err);
208
222
  cb(err);
223
+ throw err;
209
224
  }
210
-
211
- return returnPromise;
212
225
  };
213
- };
226
+ };