@mookielianhd/n8n-nodes-instagram 2.5.3 → 2.6.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.
@@ -799,11 +799,17 @@ class Instagram {
799
799
  };
800
800
  }
801
801
  async execute() {
802
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6;
802
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10;
803
803
  const items = this.getInputData();
804
804
  const returnItems = [];
805
805
  const hostUrl = 'graph.facebook.com';
806
806
  const waitForContainerReady = async ({ creationId, hostUrl, graphApiVersion, itemIndex, pollIntervalMs, maxPollAttempts, }) => {
807
+ if (!creationId || typeof creationId !== 'string') {
808
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid creation ID provided: ${creationId}. Creation ID must be a non-empty string.`, { itemIndex });
809
+ }
810
+ if (!graphApiVersion || typeof graphApiVersion !== 'string') {
811
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid Graph API version provided: ${graphApiVersion}. Graph API version must be a non-empty string.`, { itemIndex });
812
+ }
807
813
  const statusUri = `https://${hostUrl}/${graphApiVersion}/${creationId}`;
808
814
  const statusFields = ['status_code', 'status'];
809
815
  const pollRequestOptions = {
@@ -818,24 +824,80 @@ class Instagram {
818
824
  json: true,
819
825
  };
820
826
  let lastStatus;
827
+ let lastError;
828
+ let consecutiveErrors = 0;
829
+ const maxConsecutiveErrors = 3;
830
+ const startTime = Date.now();
831
+ const maxTotalTimeMs = 90000;
821
832
  for (let attempt = 1; attempt <= maxPollAttempts; attempt++) {
822
- const statusResponse = (await this.helpers.httpRequestWithAuthentication.call(this, 'instagramApi', pollRequestOptions));
823
- const statuses = statusFields
824
- .map((field) => statusResponse[field])
825
- .filter((value) => typeof value === 'string')
826
- .map((value) => value.toUpperCase());
827
- if (statuses.length > 0) {
828
- lastStatus = statuses[0];
833
+ const elapsedTime = Date.now() - startTime;
834
+ if (elapsedTime > maxTotalTimeMs) {
835
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Polling timeout: Exceeded maximum polling time of ${maxTotalTimeMs / 1000} seconds. Container ID: ${creationId}, Last known status: ${lastStatus !== null && lastStatus !== void 0 ? lastStatus : 'unknown'}, Attempts: ${attempt}/${maxPollAttempts}.`, { itemIndex });
829
836
  }
830
- if (statuses.some((status) => READY_STATUSES.has(status))) {
831
- return;
837
+ try {
838
+ const statusResponse = (await this.helpers.httpRequestWithAuthentication.call(this, 'instagramApi', pollRequestOptions));
839
+ if (!statusResponse || typeof statusResponse !== 'object') {
840
+ consecutiveErrors++;
841
+ if (consecutiveErrors >= maxConsecutiveErrors) {
842
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid response format received while polling container status (${consecutiveErrors} consecutive errors). Expected object, got: ${typeof statusResponse}. Response: ${JSON.stringify(statusResponse)}. Container ID: ${creationId}.`, { itemIndex });
843
+ }
844
+ const errorInterval = Math.min(pollIntervalMs, 1000);
845
+ await (0, n8n_workflow_1.sleep)(errorInterval);
846
+ continue;
847
+ }
848
+ consecutiveErrors = 0;
849
+ const statuses = statusFields
850
+ .map((field) => statusResponse[field])
851
+ .filter((value) => typeof value === 'string')
852
+ .map((value) => value.toUpperCase());
853
+ if (statuses.length > 0) {
854
+ lastStatus = statuses[0];
855
+ }
856
+ if (statuses.some((status) => READY_STATUSES.has(status))) {
857
+ return;
858
+ }
859
+ if (statuses.some((status) => ERROR_STATUSES.has(status))) {
860
+ const errorMessage = statusResponse.error_message;
861
+ const errorDetails = errorMessage
862
+ ? ` Error details: ${errorMessage}`
863
+ : '';
864
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Media container reported error status (${statuses.join(', ')}) while waiting to publish. Container ID: ${creationId}, Attempt: ${attempt}/${maxPollAttempts}.${errorDetails}`, { itemIndex });
865
+ }
866
+ let effectiveInterval;
867
+ if (attempt <= 10) {
868
+ effectiveInterval = 500;
869
+ }
870
+ else if (attempt <= 20) {
871
+ effectiveInterval = 1000;
872
+ }
873
+ else {
874
+ effectiveInterval = pollIntervalMs;
875
+ }
876
+ await (0, n8n_workflow_1.sleep)(effectiveInterval);
832
877
  }
833
- if (statuses.some((status) => ERROR_STATUSES.has(status))) {
834
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Media container reported error status (${statuses.join(', ')}) while waiting to publish.`, { itemIndex });
878
+ catch (error) {
879
+ lastError = error;
880
+ consecutiveErrors++;
881
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
882
+ throw error;
883
+ }
884
+ const errorMessage = error instanceof Error ? error.message.toLowerCase() : String(error).toLowerCase();
885
+ if (errorMessage.includes('invalid') ||
886
+ errorMessage.includes('not found') ||
887
+ errorMessage.includes('404') ||
888
+ errorMessage.includes('does not exist') ||
889
+ (consecutiveErrors >= maxConsecutiveErrors)) {
890
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to poll container status after ${attempt} attempts (${consecutiveErrors} consecutive errors). Container may be invalid or failed. Last error: ${error instanceof Error ? error.message : String(error)}. Container ID: ${creationId}, Last known status: ${lastStatus !== null && lastStatus !== void 0 ? lastStatus : 'unknown'}.`, { itemIndex });
891
+ }
892
+ if (attempt < maxPollAttempts) {
893
+ const errorInterval = Math.min(pollIntervalMs, 1000);
894
+ await (0, n8n_workflow_1.sleep)(errorInterval);
895
+ continue;
896
+ }
897
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to poll container status after ${maxPollAttempts} attempts. Last error: ${error instanceof Error ? error.message : String(error)}. Container ID: ${creationId}, Last known status: ${lastStatus !== null && lastStatus !== void 0 ? lastStatus : 'unknown'}.`, { itemIndex });
835
898
  }
836
- await (0, n8n_workflow_1.sleep)(pollIntervalMs);
837
899
  }
838
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Timed out waiting for container to become ready. Last known status: ${lastStatus !== null && lastStatus !== void 0 ? lastStatus : 'unknown'}.`, { itemIndex });
900
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Timed out waiting for container to become ready after ${maxPollAttempts} attempts. Last known status: ${lastStatus !== null && lastStatus !== void 0 ? lastStatus : 'unknown'}. Container ID: ${creationId}. Last error: ${lastError instanceof Error ? lastError.message : lastError ? String(lastError) : 'none'}.`, { itemIndex });
839
901
  };
840
902
  const isMediaNotReadyError = (error) => {
841
903
  var _a, _b, _c, _d;
@@ -854,15 +916,87 @@ class Instagram {
854
916
  };
855
917
  for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
856
918
  try {
857
- const resource = this.getNodeParameter('resource', itemIndex);
858
- const operation = this.getNodeParameter('operation', itemIndex);
919
+ let resource;
920
+ let operation;
921
+ try {
922
+ resource = this.getNodeParameter('resource', itemIndex);
923
+ if (!resource || typeof resource !== 'string') {
924
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid or missing resource parameter at item index ${itemIndex}. Resource must be a non-empty string.`, { itemIndex });
925
+ }
926
+ }
927
+ catch (error) {
928
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
929
+ throw error;
930
+ }
931
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get resource parameter at item index ${itemIndex}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
932
+ }
933
+ try {
934
+ operation = this.getNodeParameter('operation', itemIndex);
935
+ if (!operation || typeof operation !== 'string') {
936
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid or missing operation parameter at item index ${itemIndex}. Operation must be a non-empty string.`, { itemIndex });
937
+ }
938
+ }
939
+ catch (error) {
940
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
941
+ throw error;
942
+ }
943
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get operation parameter at item index ${itemIndex}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
944
+ }
859
945
  if (resource === 'messaging') {
860
- const graphApiVersion = this.getNodeParameter('graphApiVersion', itemIndex);
861
- const accountId = this.getNodeParameter('node', itemIndex);
946
+ let graphApiVersion;
947
+ let accountId;
948
+ try {
949
+ graphApiVersion = this.getNodeParameter('graphApiVersion', itemIndex);
950
+ if (!graphApiVersion || typeof graphApiVersion !== 'string') {
951
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid or missing Graph API version parameter at item index ${itemIndex}. Graph API version must be a non-empty string (e.g., 'v22.0').`, { itemIndex });
952
+ }
953
+ }
954
+ catch (error) {
955
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
956
+ throw error;
957
+ }
958
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get Graph API version parameter at item index ${itemIndex}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
959
+ }
960
+ try {
961
+ accountId = this.getNodeParameter('node', itemIndex);
962
+ if (!accountId || typeof accountId !== 'string') {
963
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid or missing account ID (node) parameter at item index ${itemIndex}. Account ID must be a non-empty string.`, { itemIndex });
964
+ }
965
+ }
966
+ catch (error) {
967
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
968
+ throw error;
969
+ }
970
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get account ID (node) parameter at item index ${itemIndex}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
971
+ }
862
972
  try {
863
973
  if (operation === 'sendMessage') {
864
- const recipientId = this.getNodeParameter('recipientId', itemIndex);
865
- const text = this.getNodeParameter('messageText', itemIndex);
974
+ let recipientId;
975
+ let text;
976
+ try {
977
+ recipientId = this.getNodeParameter('recipientId', itemIndex);
978
+ if (!recipientId || typeof recipientId !== 'string') {
979
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid or missing recipient ID parameter at item index ${itemIndex}. Recipient ID must be a non-empty string.`, { itemIndex });
980
+ }
981
+ }
982
+ catch (error) {
983
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
984
+ throw error;
985
+ }
986
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get recipient ID parameter at item index ${itemIndex}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
987
+ }
988
+ try {
989
+ text = this.getNodeParameter('messageText', itemIndex);
990
+ if (!text || typeof text !== 'string') {
991
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid or missing message text parameter at item index ${itemIndex}. Message text must be a non-empty string.`, { itemIndex });
992
+ }
993
+ }
994
+ catch (error) {
995
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
996
+ throw error;
997
+ }
998
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get message text parameter at item index ${itemIndex}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
999
+ }
866
1000
  const url = `https://${hostUrl}/${graphApiVersion}/${accountId}/messages`;
867
1001
  const requestOptions = {
868
1002
  headers: {
@@ -881,7 +1015,19 @@ class Instagram {
881
1015
  },
882
1016
  json: true,
883
1017
  };
884
- const response = (await this.helpers.httpRequestWithAuthentication.call(this, 'instagramApi', requestOptions));
1018
+ let response;
1019
+ try {
1020
+ response = (await this.helpers.httpRequestWithAuthentication.call(this, 'instagramApi', requestOptions));
1021
+ if (!response || typeof response !== 'object') {
1022
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid response format received from send message API. Expected object, got: ${typeof response}. Response: ${JSON.stringify(response)}`, { itemIndex });
1023
+ }
1024
+ }
1025
+ catch (error) {
1026
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
1027
+ throw error;
1028
+ }
1029
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to send message via Instagram Messaging API. Account ID: ${accountId}, Recipient ID: ${recipientId}. Error: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
1030
+ }
885
1031
  returnItems.push({ json: response, pairedItem: { item: itemIndex } });
886
1032
  continue;
887
1033
  }
@@ -913,11 +1059,20 @@ class Instagram {
913
1059
  if (operation === 'refreshAccessToken') {
914
1060
  let token = (_c = this.getNodeParameter('accessToken', itemIndex, '')) !== null && _c !== void 0 ? _c : '';
915
1061
  if (!token) {
916
- const credentials = (await this.getCredentials('instagramApi'));
1062
+ let credentials;
1063
+ try {
1064
+ credentials = (await this.getCredentials('instagramApi'));
1065
+ }
1066
+ catch (error) {
1067
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to retrieve Instagram API credentials: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
1068
+ }
1069
+ if (!credentials) {
1070
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Instagram API credentials not found. Please configure the Instagram API credential.', { itemIndex });
1071
+ }
917
1072
  token = (_d = credentials === null || credentials === void 0 ? void 0 : credentials.accessToken) !== null && _d !== void 0 ? _d : '';
918
1073
  }
919
- if (!token) {
920
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'No access token provided and no access token found in the Instagram API credential.', { itemIndex });
1074
+ if (!token || typeof token !== 'string') {
1075
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'No access token provided and no access token found in the Instagram API credential. Please provide an access token or configure it in the credential.', { itemIndex });
921
1076
  }
922
1077
  const url = 'https://graph.instagram.com/refresh_access_token';
923
1078
  const requestOptions = {
@@ -932,13 +1087,49 @@ class Instagram {
932
1087
  },
933
1088
  json: true,
934
1089
  };
935
- const response = (await this.helpers.httpRequest.call(this, requestOptions));
1090
+ let response;
1091
+ try {
1092
+ response = (await this.helpers.httpRequest.call(this, requestOptions));
1093
+ if (!response || typeof response !== 'object') {
1094
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid response format received from refresh access token API. Expected object, got: ${typeof response}. Response: ${JSON.stringify(response)}`, { itemIndex });
1095
+ }
1096
+ }
1097
+ catch (error) {
1098
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
1099
+ throw error;
1100
+ }
1101
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to refresh access token: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
1102
+ }
936
1103
  returnItems.push({ json: response, pairedItem: { item: itemIndex } });
937
1104
  continue;
938
1105
  }
939
1106
  if (operation === 'exchangeAccessToken') {
940
- const shortLivedToken = this.getNodeParameter('shortLivedAccessToken', itemIndex);
941
- const appSecret = this.getNodeParameter('appSecret', itemIndex);
1107
+ let shortLivedToken;
1108
+ let appSecret;
1109
+ try {
1110
+ shortLivedToken = this.getNodeParameter('shortLivedAccessToken', itemIndex);
1111
+ if (!shortLivedToken || typeof shortLivedToken !== 'string') {
1112
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid or missing short-lived access token parameter at item index ${itemIndex}. Short-lived access token must be a non-empty string.`, { itemIndex });
1113
+ }
1114
+ }
1115
+ catch (error) {
1116
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
1117
+ throw error;
1118
+ }
1119
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get short-lived access token parameter at item index ${itemIndex}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
1120
+ }
1121
+ try {
1122
+ appSecret = this.getNodeParameter('appSecret', itemIndex);
1123
+ if (!appSecret || typeof appSecret !== 'string') {
1124
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid or missing app secret parameter at item index ${itemIndex}. App secret must be a non-empty string.`, { itemIndex });
1125
+ }
1126
+ }
1127
+ catch (error) {
1128
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
1129
+ throw error;
1130
+ }
1131
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get app secret parameter at item index ${itemIndex}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
1132
+ }
942
1133
  const url = 'https://graph.instagram.com/access_token';
943
1134
  const requestOptions = {
944
1135
  headers: {
@@ -953,7 +1144,19 @@ class Instagram {
953
1144
  },
954
1145
  json: true,
955
1146
  };
956
- const response = (await this.helpers.httpRequest.call(this, requestOptions));
1147
+ let response;
1148
+ try {
1149
+ response = (await this.helpers.httpRequest.call(this, requestOptions));
1150
+ if (!response || typeof response !== 'object') {
1151
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid response format received from exchange access token API. Expected object, got: ${typeof response}. Response: ${JSON.stringify(response)}`, { itemIndex });
1152
+ }
1153
+ }
1154
+ catch (error) {
1155
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
1156
+ throw error;
1157
+ }
1158
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to exchange access token: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
1159
+ }
957
1160
  returnItems.push({ json: response, pairedItem: { item: itemIndex } });
958
1161
  continue;
959
1162
  }
@@ -967,7 +1170,19 @@ class Instagram {
967
1170
  url,
968
1171
  json: true,
969
1172
  };
970
- const response = (await this.helpers.httpRequestWithAuthentication.call(this, 'instagramApi', requestOptions));
1173
+ let response;
1174
+ try {
1175
+ response = (await this.helpers.httpRequestWithAuthentication.call(this, 'instagramApi', requestOptions));
1176
+ if (!response || typeof response !== 'object') {
1177
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid response format received from /me endpoint. Expected object, got: ${typeof response}. Response: ${JSON.stringify(response)}`, { itemIndex });
1178
+ }
1179
+ }
1180
+ catch (error) {
1181
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
1182
+ throw error;
1183
+ }
1184
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get user profile from /me endpoint: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
1185
+ }
971
1186
  returnItems.push({ json: response, pairedItem: { item: itemIndex } });
972
1187
  continue;
973
1188
  }
@@ -1002,13 +1217,64 @@ class Instagram {
1002
1217
  return typeof apiMsg === 'string' ? apiMsg : (_d = e === null || e === void 0 ? void 0 : e.message) !== null && _d !== void 0 ? _d : String(error);
1003
1218
  };
1004
1219
  try {
1005
- const node = this.getNodeParameter('node', itemIndex);
1006
- const graphApiVersion = this.getNodeParameter('graphApiVersion', itemIndex);
1007
- const caption = this.getNodeParameter('caption', itemIndex);
1008
- const carouselMedia = this.getNodeParameter('carouselMedia', itemIndex, { mediaItem: [] });
1220
+ let node;
1221
+ let graphApiVersion;
1222
+ let caption;
1223
+ let carouselMedia;
1224
+ try {
1225
+ node = this.getNodeParameter('node', itemIndex);
1226
+ if (!node || typeof node !== 'string') {
1227
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid or missing node (account ID) parameter at item index ${itemIndex}. Node must be a non-empty string.`, { itemIndex });
1228
+ }
1229
+ }
1230
+ catch (error) {
1231
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
1232
+ throw error;
1233
+ }
1234
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get node parameter at item index ${itemIndex}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
1235
+ }
1236
+ try {
1237
+ graphApiVersion = this.getNodeParameter('graphApiVersion', itemIndex);
1238
+ if (!graphApiVersion || typeof graphApiVersion !== 'string') {
1239
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid or missing Graph API version parameter at item index ${itemIndex}. Graph API version must be a non-empty string (e.g., 'v22.0').`, { itemIndex });
1240
+ }
1241
+ }
1242
+ catch (error) {
1243
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
1244
+ throw error;
1245
+ }
1246
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get Graph API version parameter at item index ${itemIndex}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
1247
+ }
1248
+ try {
1249
+ caption = this.getNodeParameter('caption', itemIndex);
1250
+ if (typeof caption !== 'string') {
1251
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid caption parameter at item index ${itemIndex}. Caption must be a string.`, { itemIndex });
1252
+ }
1253
+ }
1254
+ catch (error) {
1255
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
1256
+ throw error;
1257
+ }
1258
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get caption parameter at item index ${itemIndex}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
1259
+ }
1260
+ try {
1261
+ carouselMedia = this.getNodeParameter('carouselMedia', itemIndex, { mediaItem: [] });
1262
+ if (!carouselMedia || typeof carouselMedia !== 'object') {
1263
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid carousel media parameter at item index ${itemIndex}. Carousel media must be an object.`, { itemIndex });
1264
+ }
1265
+ }
1266
+ catch (error) {
1267
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
1268
+ throw error;
1269
+ }
1270
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get carousel media parameter at item index ${itemIndex}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
1271
+ }
1009
1272
  const mediaItems = (_g = carouselMedia === null || carouselMedia === void 0 ? void 0 : carouselMedia.mediaItem) !== null && _g !== void 0 ? _g : [];
1273
+ if (!Array.isArray(mediaItems)) {
1274
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid carousel media items format at item index ${itemIndex}. Media items must be an array.`, { itemIndex });
1275
+ }
1010
1276
  if (mediaItems.length < 2 || mediaItems.length > 10) {
1011
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Carousel must have between 2 and 10 media items.', { itemIndex });
1277
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Carousel must have between 2 and 10 media items. Found ${mediaItems.length} items at item index ${itemIndex}.`, { itemIndex });
1012
1278
  }
1013
1279
  const pollIntervalMs = 1500;
1014
1280
  const maxPollAttempts = 20;
@@ -1016,11 +1282,20 @@ class Instagram {
1016
1282
  const mediaUri = `https://${hostUrl}/${graphApiVersion}/${node}/media`;
1017
1283
  for (let i = 0; i < mediaItems.length; i++) {
1018
1284
  const item = mediaItems[i];
1285
+ if (!item || typeof item !== 'object') {
1286
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid carousel media item at index ${i} (item ${i + 1} of ${mediaItems.length}) at item index ${itemIndex}. Media item must be an object.`, { itemIndex });
1287
+ }
1019
1288
  const isVideo = item.mediaType === 'video';
1020
1289
  const mediaLabel = `Carousel item ${i + 1} (${isVideo ? 'video' : 'image'})`;
1290
+ if (!item.mediaType || typeof item.mediaType !== 'string') {
1291
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `${mediaLabel}: Media type is required and must be either 'image' or 'video'.`, { itemIndex });
1292
+ }
1293
+ if (item.mediaType !== 'image' && item.mediaType !== 'video') {
1294
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `${mediaLabel}: Invalid media type '${item.mediaType}'. Media type must be either 'image' or 'video'.`, { itemIndex });
1295
+ }
1021
1296
  const url = isVideo ? ((_h = item.videoUrl) !== null && _h !== void 0 ? _h : '').trim() : ((_j = item.imageUrl) !== null && _j !== void 0 ? _j : '').trim();
1022
- if (!url) {
1023
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `${mediaLabel}: ${isVideo ? 'Video URL' : 'Image URL'} is required.`, { itemIndex });
1297
+ if (!url || typeof url !== 'string') {
1298
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `${mediaLabel}: ${isVideo ? 'Video URL' : 'Image URL'} is required and must be a non-empty string.`, { itemIndex });
1024
1299
  }
1025
1300
  const childQs = isVideo
1026
1301
  ? { media_type: 'VIDEO', video_url: url, is_carousel_item: true }
@@ -1040,8 +1315,8 @@ class Instagram {
1040
1315
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), `${mediaLabel}: container creation failed — ${getCarouselErrorMessage(err)}`, { itemIndex });
1041
1316
  }
1042
1317
  const childId = childResponse.id;
1043
- if (!childId) {
1044
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `${mediaLabel}: container creation did not return an id.`, { itemIndex });
1318
+ if (!childId || typeof childId !== 'string') {
1319
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `${mediaLabel}: Container creation did not return a valid ID. Response: ${JSON.stringify(childResponse)}`, { itemIndex });
1045
1320
  }
1046
1321
  try {
1047
1322
  await waitForContainerReady({
@@ -1078,8 +1353,8 @@ class Instagram {
1078
1353
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Carousel container (create): ${getCarouselErrorMessage(err)}`, { itemIndex });
1079
1354
  }
1080
1355
  const carouselContainerId = carouselResponse.id;
1081
- if (!carouselContainerId) {
1082
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Carousel container creation did not return an id.', { itemIndex });
1356
+ if (!carouselContainerId || typeof carouselContainerId !== 'string') {
1357
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Carousel container creation did not return a valid ID. Response: ${JSON.stringify(carouselResponse)}`, { itemIndex });
1083
1358
  }
1084
1359
  try {
1085
1360
  await waitForContainerReady({
@@ -1133,11 +1408,47 @@ class Instagram {
1133
1408
  }
1134
1409
  }
1135
1410
  if (resource === 'igHashtag') {
1136
- const graphApiVersion = this.getNodeParameter('graphApiVersion', itemIndex);
1137
- const accountId = this.getNodeParameter('node', itemIndex);
1411
+ let graphApiVersion;
1412
+ let accountId;
1413
+ try {
1414
+ graphApiVersion = this.getNodeParameter('graphApiVersion', itemIndex);
1415
+ if (!graphApiVersion || typeof graphApiVersion !== 'string') {
1416
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid or missing Graph API version parameter at item index ${itemIndex}. Graph API version must be a non-empty string (e.g., 'v22.0').`, { itemIndex });
1417
+ }
1418
+ }
1419
+ catch (error) {
1420
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
1421
+ throw error;
1422
+ }
1423
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get Graph API version parameter at item index ${itemIndex}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
1424
+ }
1425
+ try {
1426
+ accountId = this.getNodeParameter('node', itemIndex);
1427
+ if (!accountId || typeof accountId !== 'string') {
1428
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid or missing account ID (node) parameter at item index ${itemIndex}. Account ID must be a non-empty string.`, { itemIndex });
1429
+ }
1430
+ }
1431
+ catch (error) {
1432
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
1433
+ throw error;
1434
+ }
1435
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get account ID (node) parameter at item index ${itemIndex}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
1436
+ }
1138
1437
  try {
1139
1438
  if (operation === 'search') {
1140
- const hashtagName = this.getNodeParameter('hashtagName', itemIndex);
1439
+ let hashtagName;
1440
+ try {
1441
+ hashtagName = this.getNodeParameter('hashtagName', itemIndex);
1442
+ if (!hashtagName || typeof hashtagName !== 'string') {
1443
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid or missing hashtag name parameter at item index ${itemIndex}. Hashtag name must be a non-empty string (without the # symbol).`, { itemIndex });
1444
+ }
1445
+ }
1446
+ catch (error) {
1447
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
1448
+ throw error;
1449
+ }
1450
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get hashtag name parameter at item index ${itemIndex}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
1451
+ }
1141
1452
  const url = `https://${hostUrl}/${graphApiVersion}/ig_hashtag_search`;
1142
1453
  const requestOptions = {
1143
1454
  headers: {
@@ -1151,14 +1462,62 @@ class Instagram {
1151
1462
  },
1152
1463
  json: true,
1153
1464
  };
1154
- const response = (await this.helpers.httpRequestWithAuthentication.call(this, 'instagramApi', requestOptions));
1465
+ let response;
1466
+ try {
1467
+ response = (await this.helpers.httpRequestWithAuthentication.call(this, 'instagramApi', requestOptions));
1468
+ if (!response || typeof response !== 'object') {
1469
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid response format received from hashtag search API. Expected object, got: ${typeof response}. Response: ${JSON.stringify(response)}`, { itemIndex });
1470
+ }
1471
+ }
1472
+ catch (error) {
1473
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
1474
+ throw error;
1475
+ }
1476
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to search hashtag '${hashtagName}' for account ${accountId}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
1477
+ }
1155
1478
  returnItems.push({ json: response, pairedItem: { item: itemIndex } });
1156
1479
  continue;
1157
1480
  }
1158
1481
  if (operation === 'getRecentMedia' || operation === 'getTopMedia') {
1159
- const hashtagId = this.getNodeParameter('hashtagId', itemIndex);
1160
- const returnAll = this.getNodeParameter('returnAll', itemIndex, false);
1161
- const limit = this.getNodeParameter('limit', itemIndex, 0);
1482
+ let hashtagId;
1483
+ let returnAll;
1484
+ let limit;
1485
+ try {
1486
+ hashtagId = this.getNodeParameter('hashtagId', itemIndex);
1487
+ if (!hashtagId || typeof hashtagId !== 'string') {
1488
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid or missing hashtag ID parameter at item index ${itemIndex}. Hashtag ID must be a non-empty string.`, { itemIndex });
1489
+ }
1490
+ }
1491
+ catch (error) {
1492
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
1493
+ throw error;
1494
+ }
1495
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get hashtag ID parameter at item index ${itemIndex}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
1496
+ }
1497
+ try {
1498
+ returnAll = this.getNodeParameter('returnAll', itemIndex, false);
1499
+ if (typeof returnAll !== 'boolean') {
1500
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid returnAll parameter at item index ${itemIndex}. ReturnAll must be a boolean.`, { itemIndex });
1501
+ }
1502
+ }
1503
+ catch (error) {
1504
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
1505
+ throw error;
1506
+ }
1507
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get returnAll parameter at item index ${itemIndex}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
1508
+ }
1509
+ try {
1510
+ limit = this.getNodeParameter('limit', itemIndex, 0);
1511
+ if (typeof limit !== 'number' || limit < 0) {
1512
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid limit parameter at item index ${itemIndex}. Limit must be a non-negative number.`, { itemIndex });
1513
+ }
1514
+ }
1515
+ catch (error) {
1516
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
1517
+ throw error;
1518
+ }
1519
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get limit parameter at item index ${itemIndex}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
1520
+ }
1162
1521
  const edge = operation === 'getRecentMedia' ? 'recent_media' : 'top_media';
1163
1522
  const baseUrl = `https://${hostUrl}/${graphApiVersion}/${hashtagId}/${edge}`;
1164
1523
  const fields = [
@@ -1175,7 +1534,9 @@ class Instagram {
1175
1534
  let after;
1176
1535
  const hardCap = returnAll ? 5000 : limit;
1177
1536
  let hasMore = true;
1537
+ let pageNumber = 0;
1178
1538
  while (hasMore) {
1539
+ pageNumber++;
1179
1540
  const remaining = returnAll ? undefined : hardCap - accumulated.length;
1180
1541
  const pageLimit = remaining !== undefined ? Math.min(remaining, 50) : 50;
1181
1542
  const qs = {
@@ -1195,8 +1556,23 @@ class Instagram {
1195
1556
  qs,
1196
1557
  json: true,
1197
1558
  };
1198
- const response = (await this.helpers.httpRequestWithAuthentication.call(this, 'instagramApi', requestOptions));
1559
+ let response;
1560
+ try {
1561
+ response = (await this.helpers.httpRequestWithAuthentication.call(this, 'instagramApi', requestOptions));
1562
+ if (!response || typeof response !== 'object') {
1563
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid response format received from ${edge} API at page ${pageNumber}. Expected object, got: ${typeof response}. Response: ${JSON.stringify(response)}`, { itemIndex });
1564
+ }
1565
+ }
1566
+ catch (error) {
1567
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
1568
+ throw error;
1569
+ }
1570
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to fetch ${edge} for hashtag ${hashtagId} at page ${pageNumber}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
1571
+ }
1199
1572
  const pageData = (_o = response.data) !== null && _o !== void 0 ? _o : [];
1573
+ if (!Array.isArray(pageData)) {
1574
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid data format in response from ${edge} API at page ${pageNumber}. Expected array, got: ${typeof pageData}. Response: ${JSON.stringify(response)}`, { itemIndex });
1575
+ }
1200
1576
  accumulated.push(...pageData);
1201
1577
  const paging = response.paging;
1202
1578
  after = (_p = paging === null || paging === void 0 ? void 0 : paging.cursors) === null || _p === void 0 ? void 0 : _p.after;
@@ -1232,8 +1608,32 @@ class Instagram {
1232
1608
  }
1233
1609
  }
1234
1610
  if (resource === 'page') {
1235
- const graphApiVersion = this.getNodeParameter('graphApiVersion', itemIndex);
1236
- const pageId = this.getNodeParameter('pageId', itemIndex);
1611
+ let graphApiVersion;
1612
+ let pageId;
1613
+ try {
1614
+ graphApiVersion = this.getNodeParameter('graphApiVersion', itemIndex);
1615
+ if (!graphApiVersion || typeof graphApiVersion !== 'string') {
1616
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid or missing Graph API version parameter at item index ${itemIndex}. Graph API version must be a non-empty string (e.g., 'v22.0').`, { itemIndex });
1617
+ }
1618
+ }
1619
+ catch (error) {
1620
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
1621
+ throw error;
1622
+ }
1623
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get Graph API version parameter at item index ${itemIndex}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
1624
+ }
1625
+ try {
1626
+ pageId = this.getNodeParameter('pageId', itemIndex);
1627
+ if (!pageId || typeof pageId !== 'string') {
1628
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid or missing page ID parameter at item index ${itemIndex}. Page ID must be a non-empty string.`, { itemIndex });
1629
+ }
1630
+ }
1631
+ catch (error) {
1632
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
1633
+ throw error;
1634
+ }
1635
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get page ID parameter at item index ${itemIndex}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
1636
+ }
1237
1637
  try {
1238
1638
  if (operation === 'getInstagramAccount') {
1239
1639
  const url = `https://${hostUrl}/${graphApiVersion}/${pageId}`;
@@ -1248,7 +1648,19 @@ class Instagram {
1248
1648
  },
1249
1649
  json: true,
1250
1650
  };
1251
- const response = (await this.helpers.httpRequestWithAuthentication.call(this, 'instagramApi', requestOptions));
1651
+ let response;
1652
+ try {
1653
+ response = (await this.helpers.httpRequestWithAuthentication.call(this, 'instagramApi', requestOptions));
1654
+ if (!response || typeof response !== 'object') {
1655
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid response format received from page API. Expected object, got: ${typeof response}. Response: ${JSON.stringify(response)}`, { itemIndex });
1656
+ }
1657
+ }
1658
+ catch (error) {
1659
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
1660
+ throw error;
1661
+ }
1662
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get Instagram account for page ${pageId}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
1663
+ }
1252
1664
  returnItems.push({ json: response, pairedItem: { item: itemIndex } });
1253
1665
  continue;
1254
1666
  }
@@ -1276,8 +1688,32 @@ class Instagram {
1276
1688
  }
1277
1689
  }
1278
1690
  if (resource === 'igUser') {
1279
- const graphApiVersion = this.getNodeParameter('graphApiVersion', itemIndex);
1280
- const accountId = this.getNodeParameter('node', itemIndex);
1691
+ let graphApiVersion;
1692
+ let accountId;
1693
+ try {
1694
+ graphApiVersion = this.getNodeParameter('graphApiVersion', itemIndex);
1695
+ if (!graphApiVersion || typeof graphApiVersion !== 'string') {
1696
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid or missing Graph API version parameter at item index ${itemIndex}. Graph API version must be a non-empty string (e.g., 'v22.0').`, { itemIndex });
1697
+ }
1698
+ }
1699
+ catch (error) {
1700
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
1701
+ throw error;
1702
+ }
1703
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get Graph API version parameter at item index ${itemIndex}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
1704
+ }
1705
+ try {
1706
+ accountId = this.getNodeParameter('node', itemIndex);
1707
+ if (!accountId || typeof accountId !== 'string') {
1708
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid or missing account ID (node) parameter at item index ${itemIndex}. Account ID must be a non-empty string.`, { itemIndex });
1709
+ }
1710
+ }
1711
+ catch (error) {
1712
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
1713
+ throw error;
1714
+ }
1715
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get account ID (node) parameter at item index ${itemIndex}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
1716
+ }
1281
1717
  try {
1282
1718
  if (operation === 'get') {
1283
1719
  const url = `https://${hostUrl}/${graphApiVersion}/${accountId}`;
@@ -1302,13 +1738,49 @@ class Instagram {
1302
1738
  },
1303
1739
  json: true,
1304
1740
  };
1305
- const response = (await this.helpers.httpRequestWithAuthentication.call(this, 'instagramApi', requestOptions));
1741
+ let response;
1742
+ try {
1743
+ response = (await this.helpers.httpRequestWithAuthentication.call(this, 'instagramApi', requestOptions));
1744
+ if (!response || typeof response !== 'object') {
1745
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid response format received from IG User API. Expected object, got: ${typeof response}. Response: ${JSON.stringify(response)}`, { itemIndex });
1746
+ }
1747
+ }
1748
+ catch (error) {
1749
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
1750
+ throw error;
1751
+ }
1752
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get IG User profile for account ${accountId}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
1753
+ }
1306
1754
  returnItems.push({ json: response, pairedItem: { item: itemIndex } });
1307
1755
  continue;
1308
1756
  }
1309
1757
  if (operation === 'getMedia') {
1310
- const returnAll = this.getNodeParameter('returnAll', itemIndex, false);
1311
- const limit = this.getNodeParameter('limit', itemIndex, 0);
1758
+ let returnAll;
1759
+ let limit;
1760
+ try {
1761
+ returnAll = this.getNodeParameter('returnAll', itemIndex, false);
1762
+ if (typeof returnAll !== 'boolean') {
1763
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid returnAll parameter at item index ${itemIndex}. ReturnAll must be a boolean.`, { itemIndex });
1764
+ }
1765
+ }
1766
+ catch (error) {
1767
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
1768
+ throw error;
1769
+ }
1770
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get returnAll parameter at item index ${itemIndex}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
1771
+ }
1772
+ try {
1773
+ limit = this.getNodeParameter('limit', itemIndex, 0);
1774
+ if (typeof limit !== 'number' || limit < 0) {
1775
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid limit parameter at item index ${itemIndex}. Limit must be a non-negative number.`, { itemIndex });
1776
+ }
1777
+ }
1778
+ catch (error) {
1779
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
1780
+ throw error;
1781
+ }
1782
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get limit parameter at item index ${itemIndex}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
1783
+ }
1312
1784
  const baseUrl = `https://${hostUrl}/${graphApiVersion}/${accountId}/media`;
1313
1785
  const fields = [
1314
1786
  'id',
@@ -1324,7 +1796,9 @@ class Instagram {
1324
1796
  let after;
1325
1797
  const hardCap = returnAll ? 5000 : limit;
1326
1798
  let hasMore = true;
1799
+ let pageNumber = 0;
1327
1800
  while (hasMore) {
1801
+ pageNumber++;
1328
1802
  const remaining = returnAll ? undefined : hardCap - accumulated.length;
1329
1803
  const pageLimit = remaining !== undefined ? Math.min(remaining, 100) : 100;
1330
1804
  const qs = {
@@ -1343,8 +1817,23 @@ class Instagram {
1343
1817
  qs,
1344
1818
  json: true,
1345
1819
  };
1346
- const response = (await this.helpers.httpRequestWithAuthentication.call(this, 'instagramApi', requestOptions));
1820
+ let response;
1821
+ try {
1822
+ response = (await this.helpers.httpRequestWithAuthentication.call(this, 'instagramApi', requestOptions));
1823
+ if (!response || typeof response !== 'object') {
1824
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid response format received from IG User media API at page ${pageNumber}. Expected object, got: ${typeof response}. Response: ${JSON.stringify(response)}`, { itemIndex });
1825
+ }
1826
+ }
1827
+ catch (error) {
1828
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
1829
+ throw error;
1830
+ }
1831
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to fetch media for account ${accountId} at page ${pageNumber}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
1832
+ }
1347
1833
  const pageData = (_u = response.data) !== null && _u !== void 0 ? _u : [];
1834
+ if (!Array.isArray(pageData)) {
1835
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid data format in response from IG User media API at page ${pageNumber}. Expected array, got: ${typeof pageData}. Response: ${JSON.stringify(response)}`, { itemIndex });
1836
+ }
1348
1837
  accumulated.push(...pageData);
1349
1838
  const paging = response.paging;
1350
1839
  after = (_v = paging === null || paging === void 0 ? void 0 : paging.cursors) === null || _v === void 0 ? void 0 : _v.after;
@@ -1380,10 +1869,34 @@ class Instagram {
1380
1869
  }
1381
1870
  }
1382
1871
  if (resource === 'comments') {
1383
- const graphApiVersion = this.getNodeParameter('graphApiVersion', itemIndex);
1872
+ let graphApiVersion;
1873
+ try {
1874
+ graphApiVersion = this.getNodeParameter('graphApiVersion', itemIndex);
1875
+ if (!graphApiVersion || typeof graphApiVersion !== 'string') {
1876
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid or missing Graph API version parameter at item index ${itemIndex}. Graph API version must be a non-empty string (e.g., 'v22.0').`, { itemIndex });
1877
+ }
1878
+ }
1879
+ catch (error) {
1880
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
1881
+ throw error;
1882
+ }
1883
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get Graph API version parameter at item index ${itemIndex}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
1884
+ }
1384
1885
  try {
1385
1886
  if (operation === 'list') {
1386
- const mediaId = this.getNodeParameter('mediaId', itemIndex);
1887
+ let mediaId;
1888
+ try {
1889
+ mediaId = this.getNodeParameter('mediaId', itemIndex);
1890
+ if (!mediaId || typeof mediaId !== 'string') {
1891
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid or missing media ID parameter at item index ${itemIndex}. Media ID must be a non-empty string.`, { itemIndex });
1892
+ }
1893
+ }
1894
+ catch (error) {
1895
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
1896
+ throw error;
1897
+ }
1898
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get media ID parameter at item index ${itemIndex}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
1899
+ }
1387
1900
  const url = `https://${hostUrl}/${graphApiVersion}/${mediaId}/comments`;
1388
1901
  const requestOptions = {
1389
1902
  headers: {
@@ -1393,12 +1906,36 @@ class Instagram {
1393
1906
  url,
1394
1907
  json: true,
1395
1908
  };
1396
- const response = (await this.helpers.httpRequestWithAuthentication.call(this, 'instagramApi', requestOptions));
1909
+ let response;
1910
+ try {
1911
+ response = (await this.helpers.httpRequestWithAuthentication.call(this, 'instagramApi', requestOptions));
1912
+ if (!response || typeof response !== 'object') {
1913
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid response format received from comments list API. Expected object, got: ${typeof response}. Response: ${JSON.stringify(response)}`, { itemIndex });
1914
+ }
1915
+ }
1916
+ catch (error) {
1917
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
1918
+ throw error;
1919
+ }
1920
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to list comments for media ${mediaId}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
1921
+ }
1397
1922
  returnItems.push({ json: response, pairedItem: { item: itemIndex } });
1398
1923
  continue;
1399
1924
  }
1400
1925
  if (operation === 'hideComment' || operation === 'unhideComment') {
1401
- const commentId = this.getNodeParameter('commentId', itemIndex);
1926
+ let commentId;
1927
+ try {
1928
+ commentId = this.getNodeParameter('commentId', itemIndex);
1929
+ if (!commentId || typeof commentId !== 'string') {
1930
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid or missing comment ID parameter at item index ${itemIndex}. Comment ID must be a non-empty string.`, { itemIndex });
1931
+ }
1932
+ }
1933
+ catch (error) {
1934
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
1935
+ throw error;
1936
+ }
1937
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get comment ID parameter at item index ${itemIndex}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
1938
+ }
1402
1939
  const hideValue = operation === 'hideComment';
1403
1940
  const url = `https://${hostUrl}/${graphApiVersion}/${commentId}`;
1404
1941
  const requestOptions = {
@@ -1412,12 +1949,36 @@ class Instagram {
1412
1949
  },
1413
1950
  json: true,
1414
1951
  };
1415
- const response = (await this.helpers.httpRequestWithAuthentication.call(this, 'instagramApi', requestOptions));
1952
+ let response;
1953
+ try {
1954
+ response = (await this.helpers.httpRequestWithAuthentication.call(this, 'instagramApi', requestOptions));
1955
+ if (!response || typeof response !== 'object') {
1956
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid response format received from ${operation} API. Expected object, got: ${typeof response}. Response: ${JSON.stringify(response)}`, { itemIndex });
1957
+ }
1958
+ }
1959
+ catch (error) {
1960
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
1961
+ throw error;
1962
+ }
1963
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to ${operation} for comment ${commentId}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
1964
+ }
1416
1965
  returnItems.push({ json: response, pairedItem: { item: itemIndex } });
1417
1966
  continue;
1418
1967
  }
1419
1968
  if (operation === 'deleteComment') {
1420
- const commentId = this.getNodeParameter('commentId', itemIndex);
1969
+ let commentId;
1970
+ try {
1971
+ commentId = this.getNodeParameter('commentId', itemIndex);
1972
+ if (!commentId || typeof commentId !== 'string') {
1973
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid or missing comment ID parameter at item index ${itemIndex}. Comment ID must be a non-empty string.`, { itemIndex });
1974
+ }
1975
+ }
1976
+ catch (error) {
1977
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
1978
+ throw error;
1979
+ }
1980
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get comment ID parameter at item index ${itemIndex}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
1981
+ }
1421
1982
  const url = `https://${hostUrl}/${graphApiVersion}/${commentId}`;
1422
1983
  const requestOptions = {
1423
1984
  headers: {
@@ -1427,12 +1988,36 @@ class Instagram {
1427
1988
  url,
1428
1989
  json: true,
1429
1990
  };
1430
- const response = (await this.helpers.httpRequestWithAuthentication.call(this, 'instagramApi', requestOptions));
1991
+ let response;
1992
+ try {
1993
+ response = (await this.helpers.httpRequestWithAuthentication.call(this, 'instagramApi', requestOptions));
1994
+ if (!response || typeof response !== 'object') {
1995
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid response format received from delete comment API. Expected object, got: ${typeof response}. Response: ${JSON.stringify(response)}`, { itemIndex });
1996
+ }
1997
+ }
1998
+ catch (error) {
1999
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
2000
+ throw error;
2001
+ }
2002
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to delete comment ${commentId}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
2003
+ }
1431
2004
  returnItems.push({ json: response, pairedItem: { item: itemIndex } });
1432
2005
  continue;
1433
2006
  }
1434
2007
  if (operation === 'disableComments' || operation === 'enableComments') {
1435
- const mediaId = this.getNodeParameter('mediaId', itemIndex);
2008
+ let mediaId;
2009
+ try {
2010
+ mediaId = this.getNodeParameter('mediaId', itemIndex);
2011
+ if (!mediaId || typeof mediaId !== 'string') {
2012
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid or missing media ID parameter at item index ${itemIndex}. Media ID must be a non-empty string.`, { itemIndex });
2013
+ }
2014
+ }
2015
+ catch (error) {
2016
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
2017
+ throw error;
2018
+ }
2019
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get media ID parameter at item index ${itemIndex}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
2020
+ }
1436
2021
  const commentEnabled = operation === 'enableComments';
1437
2022
  const url = `https://${hostUrl}/${graphApiVersion}/${mediaId}`;
1438
2023
  const requestOptions = {
@@ -1446,14 +2031,62 @@ class Instagram {
1446
2031
  },
1447
2032
  json: true,
1448
2033
  };
1449
- const response = (await this.helpers.httpRequestWithAuthentication.call(this, 'instagramApi', requestOptions));
2034
+ let response;
2035
+ try {
2036
+ response = (await this.helpers.httpRequestWithAuthentication.call(this, 'instagramApi', requestOptions));
2037
+ if (!response || typeof response !== 'object') {
2038
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid response format received from ${operation} API. Expected object, got: ${typeof response}. Response: ${JSON.stringify(response)}`, { itemIndex });
2039
+ }
2040
+ }
2041
+ catch (error) {
2042
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
2043
+ throw error;
2044
+ }
2045
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to ${operation} for media ${mediaId}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
2046
+ }
1450
2047
  returnItems.push({ json: response, pairedItem: { item: itemIndex } });
1451
2048
  continue;
1452
2049
  }
1453
2050
  if (operation === 'sendPrivateReply') {
1454
- const accountId = this.getNodeParameter('node', itemIndex);
1455
- const commentId = this.getNodeParameter('commentId', itemIndex);
1456
- const text = this.getNodeParameter('privateReplyText', itemIndex);
2051
+ let accountId;
2052
+ let commentId;
2053
+ let text;
2054
+ try {
2055
+ accountId = this.getNodeParameter('node', itemIndex);
2056
+ if (!accountId || typeof accountId !== 'string') {
2057
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid or missing account ID (node) parameter at item index ${itemIndex}. Account ID must be a non-empty string.`, { itemIndex });
2058
+ }
2059
+ }
2060
+ catch (error) {
2061
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
2062
+ throw error;
2063
+ }
2064
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get account ID (node) parameter at item index ${itemIndex}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
2065
+ }
2066
+ try {
2067
+ commentId = this.getNodeParameter('commentId', itemIndex);
2068
+ if (!commentId || typeof commentId !== 'string') {
2069
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid or missing comment ID parameter at item index ${itemIndex}. Comment ID must be a non-empty string.`, { itemIndex });
2070
+ }
2071
+ }
2072
+ catch (error) {
2073
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
2074
+ throw error;
2075
+ }
2076
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get comment ID parameter at item index ${itemIndex}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
2077
+ }
2078
+ try {
2079
+ text = this.getNodeParameter('privateReplyText', itemIndex);
2080
+ if (!text || typeof text !== 'string') {
2081
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid or missing private reply text parameter at item index ${itemIndex}. Private reply text must be a non-empty string.`, { itemIndex });
2082
+ }
2083
+ }
2084
+ catch (error) {
2085
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
2086
+ throw error;
2087
+ }
2088
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get private reply text parameter at item index ${itemIndex}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
2089
+ }
1457
2090
  const url = `https://${hostUrl}/${graphApiVersion}/${accountId}/messages`;
1458
2091
  const requestOptions = {
1459
2092
  headers: {
@@ -1472,7 +2105,19 @@ class Instagram {
1472
2105
  },
1473
2106
  json: true,
1474
2107
  };
1475
- const response = (await this.helpers.httpRequestWithAuthentication.call(this, 'instagramApi', requestOptions));
2108
+ let response;
2109
+ try {
2110
+ response = (await this.helpers.httpRequestWithAuthentication.call(this, 'instagramApi', requestOptions));
2111
+ if (!response || typeof response !== 'object') {
2112
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid response format received from send private reply API. Expected object, got: ${typeof response}. Response: ${JSON.stringify(response)}`, { itemIndex });
2113
+ }
2114
+ }
2115
+ catch (error) {
2116
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
2117
+ throw error;
2118
+ }
2119
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to send private reply to comment ${commentId} for account ${accountId}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
2120
+ }
1476
2121
  returnItems.push({ json: response, pairedItem: { item: itemIndex } });
1477
2122
  continue;
1478
2123
  }
@@ -1506,21 +2151,101 @@ class Instagram {
1506
2151
  }
1507
2152
  const handler = resources_1.instagramResourceHandlers[resource];
1508
2153
  if (!handler) {
1509
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unsupported resource: ${resource}`, {
1510
- itemIndex,
1511
- });
2154
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unsupported resource: ${resource}. Supported resources are: ${Object.keys(resources_1.instagramResourceHandlers).join(', ')}.`, { itemIndex });
2155
+ }
2156
+ let node;
2157
+ let graphApiVersion;
2158
+ let caption;
2159
+ let additionalFields;
2160
+ try {
2161
+ node = this.getNodeParameter('node', itemIndex);
2162
+ if (!node || typeof node !== 'string') {
2163
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid or missing node (account ID) parameter at item index ${itemIndex}. Node must be a non-empty string.`, { itemIndex });
2164
+ }
2165
+ }
2166
+ catch (error) {
2167
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
2168
+ throw error;
2169
+ }
2170
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get node parameter at item index ${itemIndex}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
2171
+ }
2172
+ try {
2173
+ graphApiVersion = this.getNodeParameter('graphApiVersion', itemIndex);
2174
+ if (!graphApiVersion || typeof graphApiVersion !== 'string') {
2175
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid or missing Graph API version parameter at item index ${itemIndex}. Graph API version must be a non-empty string (e.g., 'v22.0').`, { itemIndex });
2176
+ }
2177
+ }
2178
+ catch (error) {
2179
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
2180
+ throw error;
2181
+ }
2182
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get Graph API version parameter at item index ${itemIndex}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
2183
+ }
2184
+ try {
2185
+ caption = this.getNodeParameter('caption', itemIndex);
2186
+ if (typeof caption !== 'string') {
2187
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid caption parameter at item index ${itemIndex}. Caption must be a string.`, { itemIndex });
2188
+ }
2189
+ }
2190
+ catch (error) {
2191
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
2192
+ throw error;
2193
+ }
2194
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get caption parameter at item index ${itemIndex}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
2195
+ }
2196
+ try {
2197
+ additionalFields = this.getNodeParameter('additionalFields', itemIndex, {});
2198
+ if (!additionalFields || typeof additionalFields !== 'object') {
2199
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid additional fields parameter at item index ${itemIndex}. Additional fields must be an object.`, { itemIndex });
2200
+ }
2201
+ }
2202
+ catch (error) {
2203
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
2204
+ throw error;
2205
+ }
2206
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to get additional fields parameter at item index ${itemIndex}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
1512
2207
  }
1513
- const node = this.getNodeParameter('node', itemIndex);
1514
- const graphApiVersion = this.getNodeParameter('graphApiVersion', itemIndex);
1515
- const caption = this.getNodeParameter('caption', itemIndex);
1516
- const additionalFields = this.getNodeParameter('additionalFields', itemIndex, {});
1517
2208
  const altText = (_0 = additionalFields.altText) !== null && _0 !== void 0 ? _0 : '';
1518
2209
  const rawLocationId = additionalFields.locationId;
1519
2210
  const userTagsCollection = additionalFields.userTags;
1520
2211
  const productTagsCollection = additionalFields.productTags;
1521
2212
  const httpRequestMethod = 'POST';
1522
2213
  const mediaUri = `https://${hostUrl}/${graphApiVersion}/${node}/media`;
1523
- const mediaPayload = handler.buildMediaPayload.call(this, itemIndex);
2214
+ let mediaPayload;
2215
+ try {
2216
+ mediaPayload = handler.buildMediaPayload.call(this, itemIndex);
2217
+ if (!mediaPayload || typeof mediaPayload !== 'object') {
2218
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid media payload returned from handler for resource '${resource}' at item index ${itemIndex}. Expected object, got: ${typeof mediaPayload}.`, { itemIndex });
2219
+ }
2220
+ }
2221
+ catch (error) {
2222
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
2223
+ throw error;
2224
+ }
2225
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to build media payload for resource '${resource}' at item index ${itemIndex}: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
2226
+ }
2227
+ const videoUrl = mediaPayload.video_url;
2228
+ const imageUrl = mediaPayload.image_url;
2229
+ if (videoUrl) {
2230
+ const trimmedUrl = videoUrl.trim();
2231
+ if (!trimmedUrl) {
2232
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Video URL is empty for resource '${resource}' at item index ${itemIndex}. Please provide a valid video URL.`, { itemIndex });
2233
+ }
2234
+ const urlPattern = /^https?:\/\/.+/i;
2235
+ if (!urlPattern.test(trimmedUrl)) {
2236
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid video URL format for resource '${resource}' at item index ${itemIndex}. URL must be a valid HTTP/HTTPS URL starting with http:// or https://. Provided URL: ${trimmedUrl.substring(0, 100)}${trimmedUrl.length > 100 ? '...' : ''}`, { itemIndex });
2237
+ }
2238
+ }
2239
+ if (imageUrl) {
2240
+ const trimmedUrl = imageUrl.trim();
2241
+ if (!trimmedUrl) {
2242
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Image URL is empty for resource '${resource}' at item index ${itemIndex}. Please provide a valid image URL.`, { itemIndex });
2243
+ }
2244
+ const urlPattern = /^https?:\/\/.+/i;
2245
+ if (!urlPattern.test(trimmedUrl)) {
2246
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid image URL format for resource '${resource}' at item index ${itemIndex}. URL must be a valid HTTP/HTTPS URL starting with http:// or https://. Provided URL: ${trimmedUrl.substring(0, 100)}${trimmedUrl.length > 100 ? '...' : ''}`, { itemIndex });
2247
+ }
2248
+ }
1524
2249
  const mediaQs = {
1525
2250
  caption,
1526
2251
  ...mediaPayload,
@@ -1592,16 +2317,63 @@ class Instagram {
1592
2317
  };
1593
2318
  let mediaResponse;
1594
2319
  try {
1595
- mediaResponse = await this.helpers.httpRequestWithAuthentication.call(this, 'instagramApi', mediaRequestOptions);
2320
+ mediaResponse = (await this.helpers.httpRequestWithAuthentication.call(this, 'instagramApi', mediaRequestOptions));
1596
2321
  }
1597
2322
  catch (error) {
2323
+ let errorMessage = 'Unknown error';
2324
+ let errorCode;
2325
+ let errorType;
2326
+ const err = error;
2327
+ if ((_2 = (_1 = err.response) === null || _1 === void 0 ? void 0 : _1.body) === null || _2 === void 0 ? void 0 : _2.error) {
2328
+ const graphError = err.response.body.error;
2329
+ errorMessage = graphError.message || errorMessage;
2330
+ errorCode = graphError.code;
2331
+ errorType = graphError.type;
2332
+ }
2333
+ else if (err.message) {
2334
+ errorMessage = err.message;
2335
+ }
2336
+ else if (error instanceof Error) {
2337
+ errorMessage = error.message;
2338
+ }
2339
+ else {
2340
+ errorMessage = String(error);
2341
+ }
2342
+ const lowerErrorMessage = errorMessage.toLowerCase();
2343
+ if (lowerErrorMessage.includes('invalid url') ||
2344
+ lowerErrorMessage.includes('url') ||
2345
+ lowerErrorMessage.includes('not found') ||
2346
+ lowerErrorMessage.includes('404') ||
2347
+ lowerErrorMessage.includes('cannot access') ||
2348
+ lowerErrorMessage.includes('unreachable')) {
2349
+ const urlToCheck = videoUrl || imageUrl || 'provided URL';
2350
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to create media container: The ${videoUrl ? 'video' : 'image'} URL appears to be invalid or unreachable. Error: ${errorMessage}${errorCode ? ` (Code: ${errorCode})` : ''}. Please verify that the URL is accessible and points to a valid ${videoUrl ? 'video' : 'image'} file. URL: ${urlToCheck.substring(0, 100)}${urlToCheck.length > 100 ? '...' : ''}`, { itemIndex });
2351
+ }
1598
2352
  if (!this.continueOnFail()) {
1599
- throw new n8n_workflow_1.NodeApiError(this.getNode(), error);
2353
+ const errorObj = (_4 = (_3 = err.response) === null || _3 === void 0 ? void 0 : _3.body) === null || _4 === void 0 ? void 0 : _4.error;
2354
+ const detailedError = {
2355
+ message: errorMessage,
2356
+ ...(errorCode && { code: errorCode }),
2357
+ ...(errorType && { type: errorType }),
2358
+ ...(err.statusCode && { statusCode: err.statusCode }),
2359
+ };
2360
+ if (errorObj && typeof errorObj === 'object' && !Array.isArray(errorObj)) {
2361
+ Object.keys(errorObj).forEach((key) => {
2362
+ const value = errorObj[key];
2363
+ if (value !== undefined &&
2364
+ value !== null &&
2365
+ (typeof value === 'string' ||
2366
+ typeof value === 'number' ||
2367
+ typeof value === 'boolean')) {
2368
+ detailedError[`error_${key}`] = value;
2369
+ }
2370
+ });
2371
+ }
2372
+ throw new n8n_workflow_1.NodeApiError(this.getNode(), detailedError);
1600
2373
  }
1601
2374
  let errorItem;
1602
- const err = error;
1603
2375
  if (err.response !== undefined) {
1604
- const graphApiErrors = (_2 = (_1 = err.response.body) === null || _1 === void 0 ? void 0 : _1.error) !== null && _2 !== void 0 ? _2 : {};
2376
+ const graphApiErrors = (_6 = (_5 = err.response.body) === null || _5 === void 0 ? void 0 : _5.error) !== null && _6 !== void 0 ? _6 : {};
1605
2377
  errorItem = {
1606
2378
  statusCode: err.statusCode,
1607
2379
  ...graphApiErrors,
@@ -1615,30 +2387,68 @@ class Instagram {
1615
2387
  continue;
1616
2388
  }
1617
2389
  if (typeof mediaResponse === 'string') {
2390
+ const responseStr = mediaResponse;
1618
2391
  if (!this.continueOnFail()) {
1619
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Media creation response body is not valid JSON.', {
1620
- itemIndex,
1621
- });
2392
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Media creation response body is not valid JSON. Received string response: ${responseStr.substring(0, 200)}${responseStr.length > 200 ? '...' : ''}`, { itemIndex });
1622
2393
  }
1623
- returnItems.push({ json: { message: mediaResponse }, pairedItem: { item: itemIndex } });
2394
+ returnItems.push({ json: { message: responseStr }, pairedItem: { item: itemIndex } });
1624
2395
  continue;
1625
2396
  }
1626
2397
  const creationId = mediaResponse.id;
1627
- if (!creationId) {
2398
+ if (!creationId || typeof creationId !== 'string') {
2399
+ const responseData = mediaResponse;
2400
+ const errorObj = responseData.error;
2401
+ const errorMessage = errorObj && typeof errorObj === 'object' && !Array.isArray(errorObj)
2402
+ ? errorObj.message
2403
+ : undefined;
2404
+ const errorCode = errorObj && typeof errorObj === 'object' && !Array.isArray(errorObj)
2405
+ ? errorObj.code
2406
+ : undefined;
1628
2407
  if (!this.continueOnFail()) {
1629
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Media creation response did not contain an id (creation_id).', { itemIndex });
2408
+ const errorDetails = errorMessage
2409
+ ? ` API Error: ${errorMessage}${errorCode ? ` (Code: ${errorCode})` : ''}`
2410
+ : '';
2411
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Media creation response did not contain a valid id (creation_id).${errorDetails} Response: ${JSON.stringify(mediaResponse)}`, { itemIndex });
1630
2412
  }
1631
- returnItems.push({ json: { error: 'No creation_id in response', response: mediaResponse }, pairedItem: { item: itemIndex } });
2413
+ returnItems.push({
2414
+ json: {
2415
+ error: 'No creation_id in response',
2416
+ response: mediaResponse,
2417
+ resource,
2418
+ itemIndex,
2419
+ ...(errorMessage && { apiError: errorMessage }),
2420
+ ...(errorCode && { apiErrorCode: errorCode }),
2421
+ },
2422
+ pairedItem: { item: itemIndex },
2423
+ });
1632
2424
  continue;
1633
2425
  }
1634
- await waitForContainerReady({
1635
- creationId,
1636
- hostUrl,
1637
- graphApiVersion,
1638
- itemIndex,
1639
- pollIntervalMs: handler.pollIntervalMs,
1640
- maxPollAttempts: handler.maxPollAttempts,
1641
- });
2426
+ const responseData = mediaResponse;
2427
+ const responseError = responseData.error;
2428
+ if (responseError && typeof responseError === 'object' && !Array.isArray(responseError)) {
2429
+ const errorObj = responseError;
2430
+ const errorMsg = errorObj.message;
2431
+ const errorCode = errorObj.code;
2432
+ if (!this.continueOnFail()) {
2433
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Media container creation returned an error despite providing an ID. Error: ${errorMsg || 'Unknown error'}${errorCode ? ` (Code: ${errorCode})` : ''}. Container ID: ${creationId}. This may indicate the media URL is invalid or inaccessible.`, { itemIndex });
2434
+ }
2435
+ }
2436
+ try {
2437
+ await waitForContainerReady({
2438
+ creationId,
2439
+ hostUrl,
2440
+ graphApiVersion,
2441
+ itemIndex,
2442
+ pollIntervalMs: handler.pollIntervalMs,
2443
+ maxPollAttempts: handler.maxPollAttempts,
2444
+ });
2445
+ }
2446
+ catch (error) {
2447
+ if (error instanceof n8n_workflow_1.NodeOperationError) {
2448
+ throw error;
2449
+ }
2450
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to wait for container to become ready. Creation ID: ${creationId}, Resource: ${resource}. Error: ${error instanceof Error ? error.message : String(error)}`, { itemIndex });
2451
+ }
1642
2452
  const publishUri = `https://${hostUrl}/${graphApiVersion}/${node}/media_publish`;
1643
2453
  const publishQs = {
1644
2454
  creation_id: creationId,
@@ -1659,7 +2469,7 @@ class Instagram {
1659
2469
  let publishFailedWithError = false;
1660
2470
  for (let attempt = 1; attempt <= publishMaxAttempts; attempt++) {
1661
2471
  try {
1662
- publishResponse = await this.helpers.httpRequestWithAuthentication.call(this, 'instagramApi', publishRequestOptions);
2472
+ publishResponse = (await this.helpers.httpRequestWithAuthentication.call(this, 'instagramApi', publishRequestOptions));
1663
2473
  publishSucceeded = true;
1664
2474
  break;
1665
2475
  }
@@ -1674,7 +2484,7 @@ class Instagram {
1674
2484
  let errorItem;
1675
2485
  const err = error;
1676
2486
  if (err.response !== undefined) {
1677
- const graphApiErrors = (_4 = (_3 = err.response.body) === null || _3 === void 0 ? void 0 : _3.error) !== null && _4 !== void 0 ? _4 : {};
2487
+ const graphApiErrors = (_8 = (_7 = err.response.body) === null || _7 === void 0 ? void 0 : _7.error) !== null && _8 !== void 0 ? _8 : {};
1678
2488
  errorItem = {
1679
2489
  statusCode: err.statusCode,
1680
2490
  ...graphApiErrors,
@@ -1699,13 +2509,18 @@ class Instagram {
1699
2509
  }
1700
2510
  if (typeof publishResponse === 'string') {
1701
2511
  if (!this.continueOnFail()) {
1702
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Media publish response body is not valid JSON.', {
1703
- itemIndex,
1704
- });
2512
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Media publish response body is not valid JSON. Received string response: ${publishResponse.substring(0, 200)}${publishResponse.length > 200 ? '...' : ''}`, { itemIndex });
1705
2513
  }
1706
2514
  returnItems.push({ json: { message: publishResponse }, pairedItem: { item: itemIndex } });
1707
2515
  continue;
1708
2516
  }
2517
+ if (!publishResponse || typeof publishResponse !== 'object') {
2518
+ if (!this.continueOnFail()) {
2519
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid publish response format. Expected object, got: ${typeof publishResponse}. Response: ${JSON.stringify(publishResponse)}`, { itemIndex });
2520
+ }
2521
+ returnItems.push({ json: { response: publishResponse }, pairedItem: { item: itemIndex } });
2522
+ continue;
2523
+ }
1709
2524
  returnItems.push({ json: publishResponse, pairedItem: { item: itemIndex } });
1710
2525
  }
1711
2526
  catch (error) {
@@ -1715,7 +2530,7 @@ class Instagram {
1715
2530
  let errorItem;
1716
2531
  const errorWithGraph = error;
1717
2532
  if (errorWithGraph.response !== undefined) {
1718
- const graphApiErrors = (_6 = (_5 = errorWithGraph.response.body) === null || _5 === void 0 ? void 0 : _5.error) !== null && _6 !== void 0 ? _6 : {};
2533
+ const graphApiErrors = (_10 = (_9 = errorWithGraph.response.body) === null || _9 === void 0 ? void 0 : _9.error) !== null && _10 !== void 0 ? _10 : {};
1719
2534
  errorItem = {
1720
2535
  statusCode: errorWithGraph.statusCode,
1721
2536
  ...graphApiErrors,