@dongdev/fca-unofficial 2.0.7 → 2.0.10

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.
Files changed (80) hide show
  1. package/DOCS.md +1699 -1434
  2. package/README.md +250 -168
  3. package/package.json +54 -28
  4. package/src/api/action/addExternalModule.js +5 -5
  5. package/src/api/action/changeAvatar.js +11 -10
  6. package/src/api/action/changeBio.js +7 -8
  7. package/src/api/action/getCurrentUserID.js +1 -1
  8. package/src/api/action/handleFriendRequest.js +5 -5
  9. package/src/api/action/logout.js +9 -8
  10. package/src/api/action/refreshFb_dtsg.js +17 -12
  11. package/src/api/action/setPostReaction.js +10 -11
  12. package/src/api/action/unfriend.js +3 -4
  13. package/src/api/http/httpGet.js +7 -8
  14. package/src/api/http/httpPost.js +7 -8
  15. package/src/api/http/postFormData.js +6 -5
  16. package/src/api/messaging/addUserToGroup.js +0 -1
  17. package/src/api/messaging/changeAdminStatus.js +108 -89
  18. package/src/api/messaging/changeArchivedStatus.js +6 -6
  19. package/src/api/messaging/changeBlockedStatus.js +3 -4
  20. package/src/api/messaging/changeGroupImage.js +72 -117
  21. package/src/api/messaging/changeNickname.js +59 -48
  22. package/src/api/messaging/changeThreadColor.js +61 -47
  23. package/src/api/messaging/changeThreadEmoji.js +106 -0
  24. package/src/api/messaging/createNewGroup.js +5 -5
  25. package/src/api/messaging/createPoll.js +36 -63
  26. package/src/api/messaging/deleteMessage.js +4 -4
  27. package/src/api/messaging/deleteThread.js +4 -4
  28. package/src/api/messaging/forwardAttachment.js +38 -47
  29. package/src/api/messaging/getFriendsList.js +5 -6
  30. package/src/api/messaging/getMessage.js +4 -9
  31. package/src/api/messaging/handleMessageRequest.js +5 -5
  32. package/src/api/messaging/markAsDelivered.js +5 -5
  33. package/src/api/messaging/markAsRead.js +7 -7
  34. package/src/api/messaging/markAsReadAll.js +3 -4
  35. package/src/api/messaging/markAsSeen.js +7 -7
  36. package/src/api/messaging/muteThread.js +3 -4
  37. package/src/api/messaging/removeUserFromGroup.js +82 -56
  38. package/src/api/messaging/resolvePhotoUrl.js +2 -3
  39. package/src/api/messaging/searchForThread.js +2 -3
  40. package/src/api/messaging/sendMessage.js +171 -101
  41. package/src/api/messaging/sendMessageMqtt.js +14 -12
  42. package/src/api/messaging/sendTypingIndicator.js +11 -11
  43. package/src/api/messaging/setMessageReaction.js +68 -82
  44. package/src/api/messaging/setTitle.js +77 -48
  45. package/src/api/messaging/shareContact.js +2 -4
  46. package/src/api/messaging/threadColors.js +0 -3
  47. package/src/api/messaging/unsendMessage.js +74 -37
  48. package/src/api/messaging/uploadAttachment.js +11 -9
  49. package/src/api/socket/core/connectMqtt.js +180 -0
  50. package/src/api/socket/core/getSeqID.js +25 -0
  51. package/src/api/socket/core/getTaskResponseData.js +22 -0
  52. package/src/api/socket/core/markDelivery.js +12 -0
  53. package/src/api/socket/core/parseDelta.js +351 -0
  54. package/src/api/socket/detail/buildStream.js +176 -68
  55. package/src/api/socket/detail/constants.js +24 -0
  56. package/src/api/socket/listenMqtt.js +80 -1005
  57. package/src/api/{messaging → threads}/getThreadHistory.js +5 -22
  58. package/src/api/threads/getThreadInfo.js +35 -248
  59. package/src/api/threads/getThreadList.js +20 -20
  60. package/src/api/threads/getThreadPictures.js +3 -4
  61. package/src/api/users/getUserID.js +5 -6
  62. package/src/api/users/getUserInfo.js +305 -73
  63. package/src/api/users/getUserInfoV2.js +134 -0
  64. package/src/database/models/user.js +32 -0
  65. package/src/database/userData.js +89 -0
  66. package/src/utils/constants.js +12 -2
  67. package/src/utils/format.js +1051 -0
  68. package/src/utils/request.js +75 -7
  69. package/CHANGELOG.md +0 -52
  70. package/LICENSE-MIT +0 -21
  71. package/func/checkUpdate.js +0 -58
  72. package/func/logger.js +0 -112
  73. package/func/login.js +0 -0
  74. package/index.d.ts +0 -618
  75. package/module/config.js +0 -34
  76. package/module/login.js +0 -47
  77. package/module/loginHelper.js +0 -635
  78. package/module/options.js +0 -49
  79. package/src/api/threads/changeThreadEmoji.js +0 -55
  80. package/src/utils/index.js +0 -1497
@@ -1,119 +1,105 @@
1
1
  "use strict";
2
2
 
3
- const utils = require("../../utils");
4
- var log = require("npmlog");
5
- const { generateOfflineThreadingID } = require("../../utils");
3
+ const log = require("npmlog");
4
+ const { generateOfflineThreadingID, getCurrentTimestamp } = require("../../utils/format");
5
+ const { parseAndCheckLogin } = require("../../utils/client");
6
6
 
7
- module.exports = function(defaultFuncs, api, ctx) {
8
- function setMessageReactionNoMqtt(reaction, messageID, callback) {
9
- var resolveFunc = function() {};
10
- var rejectFunc = function() {};
11
- var returnPromise = new Promise(function(resolve, reject) {
7
+ module.exports = function (defaultFuncs, api, ctx) {
8
+ function setMessageReactionNoMqtt(reaction, messageID, threadID, callback) {
9
+ let resolveFunc = function () { };
10
+ let rejectFunc = function () { };
11
+ const returnPromise = new Promise(function (resolve, reject) {
12
12
  resolveFunc = resolve;
13
13
  rejectFunc = reject;
14
14
  });
15
15
  if (!callback) {
16
- callback = function(err, friendList) {
17
- if (err) {
18
- return rejectFunc(err);
19
- }
20
- resolveFunc(friendList);
16
+ callback = function (err) {
17
+ if (err) return rejectFunc(err);
18
+ resolveFunc();
21
19
  };
22
20
  }
23
- var variables = {
21
+ const variables = {
24
22
  data: {
25
23
  client_mutation_id: ctx.clientMutationId++,
26
24
  actor_id: ctx.userID,
27
- action: reaction == "" ? "REMOVE_REACTION" : "ADD_REACTION",
25
+ action: reaction === "" ? "REMOVE_REACTION" : "ADD_REACTION",
28
26
  message_id: messageID,
29
27
  reaction: reaction
30
28
  }
31
29
  };
32
- var qs = {
30
+ const qs = {
33
31
  doc_id: "1491398900900362",
34
32
  variables: JSON.stringify(variables),
35
33
  dpr: 1
36
34
  };
37
35
  defaultFuncs
38
- .postFormData(
39
- "https://www.facebook.com/webgraphql/mutation/",
40
- ctx.jar,
41
- {},
42
- qs
43
- )
44
- .then(utils.parseAndCheckLogin(ctx.jar, defaultFuncs))
45
- .then(function(resData) {
46
- if (!resData) {
47
- throw { error: "setReaction returned empty object." };
48
- }
49
- if (resData.error) {
50
- throw resData;
51
- }
36
+ .postFormData("https://www.facebook.com/webgraphql/mutation/", ctx.jar, {}, qs)
37
+ .then(parseAndCheckLogin(ctx.jar, defaultFuncs))
38
+ .then(function (resData) {
39
+ if (!resData) throw { error: "setReaction returned empty object." };
40
+ if (resData.error) throw resData;
52
41
  callback(null);
53
42
  })
54
- .catch(function(err) {
43
+ .catch(function (err) {
55
44
  log.error("setReaction", err);
56
45
  return callback(err);
57
46
  });
58
-
59
47
  return returnPromise;
60
48
  }
61
49
 
62
50
  function setMessageReactionMqtt(reaction, messageID, threadID, callback) {
63
- if (!ctx.mqttClient) {
64
- throw new Error("Not connected to MQTT");
65
- }
66
- ctx.wsReqNumber += 1;
67
- let taskNumber = ++ctx.wsTaskNumber;
68
- const taskPayload = {
69
- thread_key: threadID,
70
- timestamp_ms: getCurrentTimestamp(),
71
- message_id: messageID,
72
- reaction: reaction,
73
- actor_id: ctx.userID,
74
- reaction_style: null,
75
- sync_group: 1,
76
- send_attribution: Math.random() < 0.5 ? 65537 : 524289
77
- };
78
- const task = {
79
- failure_count: null,
80
- label: "29",
81
- payload: JSON.stringify(taskPayload),
82
- queue_name: JSON.stringify(["reaction", messageID]),
83
- task_id: taskNumber
84
- };
85
- const content = {
86
- app_id: "2220391788200892",
87
- payload: JSON.stringify({
88
- data_trace_id: null,
89
- epoch_id: parseInt(generateOfflineThreadingID()),
90
- tasks: [task],
91
- version_id: "7158486590867448"
92
- }),
93
- request_id: ctx.wsReqNumber,
94
- type: 3
95
- };
96
- if (typeof callback === "function") {
97
- ctx["tasks"].set(taskNumber, {
98
- type: "set_message_reaction",
99
- callback: callback
100
- });
101
- }
102
- ctx.mqttClient.publish("/ls_req", JSON.stringify(content), {
103
- qos: 1,
104
- retain: false
51
+ if (!ctx.mqttClient) return setMessageReactionNoMqtt(reaction, messageID, callback);
52
+ return new Promise((resolve, reject) => {
53
+ try {
54
+ ctx.wsReqNumber += 1;
55
+ const taskNumber = ++ctx.wsTaskNumber;
56
+ const taskPayload = {
57
+ thread_key: threadID,
58
+ timestamp_ms: getCurrentTimestamp(),
59
+ message_id: messageID,
60
+ reaction: reaction,
61
+ actor_id: ctx.userID,
62
+ reaction_style: null,
63
+ sync_group: 1,
64
+ send_attribution: Math.random() < 0.5 ? 65537 : 524289
65
+ };
66
+ const task = {
67
+ failure_count: null,
68
+ label: "29",
69
+ payload: JSON.stringify(taskPayload),
70
+ queue_name: JSON.stringify(["reaction", messageID]),
71
+ task_id: taskNumber
72
+ };
73
+ const content = {
74
+ app_id: "2220391788200892",
75
+ payload: JSON.stringify({
76
+ data_trace_id: null,
77
+ epoch_id: parseInt(generateOfflineThreadingID()),
78
+ tasks: [task],
79
+ version_id: "7158486590867448"
80
+ }),
81
+ request_id: ctx.wsReqNumber,
82
+ type: 3
83
+ };
84
+ const internalCb = (err) => {
85
+ if (typeof callback === "function") callback(err);
86
+ if (err) return reject(err);
87
+ return resolve();
88
+ };
89
+ ctx.tasks.set(taskNumber, { type: "set_message_reaction", callback: internalCb });
90
+ ctx.mqttClient.publish("/ls_req", JSON.stringify(content), { qos: 1, retain: false });
91
+ if (typeof callback !== "function") resolve();
92
+ } catch (e) {
93
+ if (typeof callback === "function") callback(e);
94
+ reject(e);
95
+ }
105
96
  });
106
97
  }
98
+
107
99
  return function setMessageReaction(reaction, messageID, threadID, callback) {
108
100
  if (ctx.mqttClient) {
109
- try {
110
- setMessageReactionMqtt(reaction, messageID, threadID, callback);
111
- callback();
112
- } catch (e) {
113
- setMessageReactionNoMqtt(reaction, messageID, callback);
114
- }
115
- } else {
116
- setMessageReactionNoMqtt(reaction, messageID, callback);
101
+ return setMessageReactionMqtt(reaction, messageID, threadID, callback);
117
102
  }
103
+ return setMessageReactionNoMqtt(reaction, messageID, threadID, callback);
118
104
  };
119
105
  };
@@ -1,44 +1,34 @@
1
1
  "use strict";
2
2
 
3
- const utils = require("../../utils");
3
+ const { getType, generateOfflineThreadingID, generateTimestampRelative, generateThreadingID, getCurrentTimestamp } = require("../../utils/format");
4
+ const { parseAndCheckLogin } = require("../../utils/client");
4
5
  const log = require("npmlog");
5
6
 
6
- module.exports = function(defaultFuncs, api, ctx) {
7
- return function setTitle(newTitle, threadID, callback) {
8
- if (
9
- !callback &&
10
- (utils.getType(threadID) === "Function" ||
11
- utils.getType(threadID) === "AsyncFunction")
12
- ) {
13
- throw { error: "please pass a threadID as a second argument." };
14
- }
15
-
16
- let resolveFunc = function() {};
17
- let rejectFunc = function() {};
18
- const returnPromise = new Promise(function(resolve, reject) {
7
+ module.exports = function (defaultFuncs, api, ctx) {
8
+ function setTitleNoMqtt(newTitle, threadID, callback) {
9
+ if (!callback && (getType(threadID) === "Function" || getType(threadID) === "AsyncFunction")) throw { error: "please pass a threadID as a second argument." };
10
+ var resolveFunc = function () { };
11
+ var rejectFunc = function () { };
12
+ var returnPromise = new Promise(function (resolve, reject) {
19
13
  resolveFunc = resolve;
20
14
  rejectFunc = reject;
21
15
  });
22
-
23
16
  if (!callback) {
24
- callback = function(err, friendList) {
25
- if (err) {
26
- return rejectFunc(err);
27
- }
28
- resolveFunc(friendList);
17
+ callback = function (err, data) {
18
+ if (err) return rejectFunc(err);
19
+ resolveFunc(data);
29
20
  };
30
21
  }
31
-
32
- const messageAndOTID = utils.generateOfflineThreadingID();
33
- const form = {
22
+ var messageAndOTID = generateOfflineThreadingID();
23
+ var form = {
34
24
  client: "mercury",
35
25
  action_type: "ma-type:log-message",
36
- author: "fbid:" + (ctx.i_userID || ctx.userID),
26
+ author: "fbid:" + ctx.userID,
37
27
  author_email: "",
38
28
  coordinates: "",
39
29
  timestamp: Date.now(),
40
30
  timestamp_absolute: "Today",
41
- timestamp_relative: utils.generateTimestampRelative(),
31
+ timestamp_relative: generateTimestampRelative(),
42
32
  timestamp_time_passed: "0",
43
33
  is_unread: false,
44
34
  is_cleared: false,
@@ -50,41 +40,80 @@ module.exports = function(defaultFuncs, api, ctx) {
50
40
  status: "0",
51
41
  offline_threading_id: messageAndOTID,
52
42
  message_id: messageAndOTID,
53
- threading_id: utils.generateThreadingID(ctx.clientID),
43
+ threading_id: generateThreadingID(ctx.clientID),
54
44
  manual_retry_cnt: "0",
55
45
  thread_fbid: threadID,
56
46
  thread_name: newTitle,
57
47
  thread_id: threadID,
58
48
  log_message_type: "log:thread-name"
59
49
  };
60
-
61
50
  defaultFuncs
62
- .post(
63
- "https://www.facebook.com/messaging/set_thread_name/",
64
- ctx.jar,
65
- form
66
- )
67
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
68
- .then(function(resData) {
69
- if (resData.error && resData.error === 1545012) {
70
- throw { error: "Cannot change chat title: Not member of chat." };
71
- }
72
-
73
- if (resData.error && resData.error === 1545003) {
74
- throw { error: "Cannot set title of single-user chat." };
75
- }
76
-
77
- if (resData.error) {
78
- throw resData;
79
- }
80
-
51
+ .post("https://www.facebook.com/messaging/set_thread_name/", ctx.jar, form)
52
+ .then(parseAndCheckLogin(ctx, defaultFuncs))
53
+ .then(function (resData) {
54
+ if (resData.error && resData.error === 1545012) throw { error: "Cannot change chat title: Not member of chat." };
55
+ if (resData.error && resData.error === 1545003) throw { error: "Cannot set title of single-user chat." };
56
+ if (resData.error) throw resData;
81
57
  return callback();
82
58
  })
83
- .catch(function(err) {
59
+ .catch(function (err) {
84
60
  log.error("setTitle", err);
85
61
  return callback(err);
86
62
  });
87
-
88
63
  return returnPromise;
89
64
  };
65
+ function setTitleMqtt(newTitle, threadID, callback) {
66
+ if (!ctx.mqttClient) {
67
+ throw new Error("Not connected to MQTT");
68
+ }
69
+ var resolveFunc = function () { };
70
+ var rejectFunc = function () { };
71
+ var returnPromise = new Promise(function (resolve, reject) {
72
+ resolveFunc = resolve;
73
+ rejectFunc = reject;
74
+ });
75
+ if (!callback) {
76
+ callback = function (err, data) {
77
+ if (err) return rejectFunc(err);
78
+ resolveFunc(data);
79
+ data
80
+ };
81
+ }
82
+ let count_req = 0
83
+ var form = JSON.stringify({
84
+ "app_id": "2220391788200892",
85
+ "payload": JSON.stringify({
86
+ epoch_id: generateOfflineThreadingID(),
87
+ tasks: [
88
+ {
89
+ failure_count: null,
90
+ label: '32',
91
+ payload: JSON.stringify({
92
+ "thread_key": threadID,
93
+ "thread_name": newTitle,
94
+ "sync_group": 1
95
+ }),
96
+ queue_name: threadID,
97
+ task_id: Math.random() * 1001 << 0
98
+ }
99
+ ],
100
+ version_id: '8798795233522156'
101
+ }),
102
+ "request_id": ++count_req,
103
+ "type": 3
104
+ });
105
+ mqttClient.publish('/ls_req', form);
106
+ return returnPromise;
107
+ };
108
+ return function setTitle(newTitle, threadID, callback) {
109
+ if (ctx.mqttClient) {
110
+ try {
111
+ setTitleMqtt(newTitle, threadID, callback);
112
+ } catch (e) {
113
+ setTitleNoMqtt(newTitle, threadID, callback);
114
+ }
115
+ } else {
116
+ setTitleNoMqtt(newTitle, threadID, callback);
117
+ }
118
+ };
90
119
  };
@@ -1,8 +1,6 @@
1
1
  "use strict";
2
2
 
3
- const utils = require("../../utils");
4
- var log = require("npmlog");
5
-
3
+ const { generateOfflineThreadingID } = require("../../utils/format");
6
4
  module.exports = function(defaultFuncs, api, ctx) {
7
5
  return function shareContact(text, senderID, threadID, callback) {
8
6
  if (!text) {
@@ -39,7 +37,7 @@ module.exports = function(defaultFuncs, api, ctx) {
39
37
  failure_count: null
40
38
  }
41
39
  ],
42
- epoch_id: utils.generateOfflineThreadingID(),
40
+ epoch_id: generateOfflineThreadingID(),
43
41
  version_id: "7214102258676893"
44
42
  }),
45
43
  request_id: ++count_req,
@@ -33,9 +33,6 @@ module.exports = function(_defaultFuncs, _api, _ctx) {
33
33
  MediumSlateBlue: "234137870477637", //BrightPurple
34
34
  DeepSkyBlue: "2442142322678320", //AquaBlue
35
35
  BrilliantRose: "169463077092846", //HotPink
36
- //i've tried my best, everything else can't be mapped. (or is it?) -UIRI 2020
37
- //#endregion
38
-
39
36
  DefaultBlue: "196241301102133",
40
37
  HotPink: "169463077092846",
41
38
  AquaBlue: "2442142322678320",
@@ -1,44 +1,81 @@
1
1
  "use strict";
2
- const utils = require("../../utils");
3
- const log = require("npmlog");
4
2
 
5
- module.exports = function(defaultFuncs, api, ctx) {
6
- return function unsendMessage(messageID, callback) {
7
- let resolveFunc = function() {};
8
- let rejectFunc = function() {};
9
- const returnPromise = new Promise(function(resolve, reject) {
10
- resolveFunc = resolve;
11
- rejectFunc = reject;
12
- });
3
+ const { generateOfflineThreadingID } = require("../../utils/format.js");
4
+ const log = require("npmlog");
13
5
 
14
- if (!callback) {
15
- callback = function(err, friendList) {
16
- if (err) {
17
- return rejectFunc(err);
18
- }
19
- resolveFunc(friendList);
6
+ module.exports = function (defaultFuncs, api, ctx) {
7
+ return function unsendMessage(messageID, threadID, callback) {
8
+ return new Promise((resolve, reject) => {
9
+ if (!ctx.mqttClient) {
10
+ const err = new Error("Not connected to MQTT");
11
+ callback?.(err);
12
+ return reject(err);
13
+ }
14
+ const reqID = ++ctx.wsReqNumber;
15
+ const taskID = ++ctx.wsTaskNumber;
16
+ const taskPayload = {
17
+ message_id: messageID,
18
+ thread_key: threadID,
19
+ sync_group: 1,
20
20
  };
21
- }
22
-
23
- const form = {
24
- message_id: messageID
25
- };
26
-
27
- defaultFuncs
28
- .post("https://www.facebook.com/messaging/unsend_message/", ctx.jar, form)
29
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
30
- .then(function(resData) {
31
- if (resData.error) {
32
- throw resData;
21
+ const task = {
22
+ failure_count: null,
23
+ label: "33",
24
+ payload: JSON.stringify(taskPayload),
25
+ queue_name: "unsend_message",
26
+ task_id: taskID,
27
+ };
28
+ const content = {
29
+ app_id: "2220391788200892",
30
+ payload: JSON.stringify({
31
+ tasks: [task],
32
+ epoch_id: parseInt(generateOfflineThreadingID()),
33
+ version_id: "25393437286970779",
34
+ }),
35
+ request_id: reqID,
36
+ type: 3,
37
+ };
38
+ try {
39
+ ctx.mqttClient.publish("/ls_req", JSON.stringify(content), {
40
+ qos: 1,
41
+ retain: false
42
+ });
43
+ } catch (err) {
44
+ log.error("unsendMessage (MQTT publish failed)", err);
45
+ callback?.(err);
46
+ return reject(err);
47
+ }
48
+ const handleRes = (topic, message) => {
49
+ if (topic !== "/ls_resp") return;
50
+ let jsonMsg;
51
+ try {
52
+ jsonMsg = JSON.parse(message.toString());
53
+ jsonMsg.payload = JSON.parse(jsonMsg.payload);
54
+ } catch (err) {
55
+ return;
33
56
  }
34
-
35
- return callback();
36
- })
37
- .catch(function(err) {
38
- log.error("unsendMessage", err);
39
- return callback(err);
40
- });
41
-
42
- return returnPromise;
57
+ if (jsonMsg.request_id !== reqID) return;
58
+ ctx.mqttClient.removeListener("message", handleRes);
59
+ try {
60
+ const msgID = jsonMsg.payload.step?.[1]?.[2]?.[2]?.[1]?.[2];
61
+ const msgReplace = jsonMsg.payload.step?.[1]?.[2]?.[2]?.[1]?.[4];
62
+ if (msgID && msgReplace) {
63
+ const bodies = {
64
+ body: msgReplace,
65
+ messageID: msgID
66
+ };
67
+ callback?.(null, bodies);
68
+ return resolve(bodies);
69
+ } else {
70
+ callback?.(null, { success: true });
71
+ return resolve({ success: true });
72
+ }
73
+ } catch (err) {
74
+ callback?.(null, { success: true });
75
+ return resolve({ success: true });
76
+ }
77
+ };
78
+ ctx.mqttClient.on("message", handleRes);
79
+ });
43
80
  };
44
81
  };
@@ -1,6 +1,8 @@
1
- const utils = require("../../utils");
1
+ "use strict";
2
2
  const log = require("npmlog");
3
-
3
+ const { parseAndCheckLogin } = require("../../utils/client");
4
+ const { getType } = require("../../utils/format");
5
+ const { isReadableStream } = require("../../utils/constants");
4
6
  module.exports = function(defaultFuncs, api, ctx) {
5
7
  function upload(attachments, callback) {
6
8
  callback = callback || function() {};
@@ -8,11 +10,11 @@ module.exports = function(defaultFuncs, api, ctx) {
8
10
 
9
11
  // create an array of promises
10
12
  for (let i = 0; i < attachments.length; i++) {
11
- if (!utils.isReadableStream(attachments[i])) {
13
+ if (!isReadableStream(attachments[i])) {
12
14
  throw {
13
15
  error:
14
16
  "Attachment should be a readable stream and not " +
15
- utils.getType(attachments[i]) +
17
+ getType(attachments[i]) +
16
18
  "."
17
19
  };
18
20
  }
@@ -30,7 +32,7 @@ module.exports = function(defaultFuncs, api, ctx) {
30
32
  form,
31
33
  {}
32
34
  )
33
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
35
+ .then(parseAndCheckLogin(ctx, defaultFuncs))
34
36
  .then(function(resData) {
35
37
  if (resData.error) {
36
38
  throw resData;
@@ -57,9 +59,9 @@ module.exports = function(defaultFuncs, api, ctx) {
57
59
  return function uploadAttachment(attachments, callback) {
58
60
  if (
59
61
  !attachments &&
60
- !utils.isReadableStream(attachments) &&
61
- !utils.getType(attachments) === "Array" &&
62
- utils.getType(attachments) === "Array" && !attachments.length
62
+ !isReadableStream(attachments) &&
63
+ !getType(attachments) === "Array" &&
64
+ getType(attachments) === "Array" && !attachments.length
63
65
  )
64
66
  throw { error: "Please pass an attachment or an array of attachments." };
65
67
 
@@ -79,7 +81,7 @@ module.exports = function(defaultFuncs, api, ctx) {
79
81
  };
80
82
  }
81
83
 
82
- if (utils.getType(attachments) !== "Array") attachments = [attachments];
84
+ if (getType(attachments) !== "Array") attachments = [attachments];
83
85
 
84
86
  upload(attachments, (err, info) => {
85
87
  if (err) {