@mookielianhd/n8n-nodes-instagram 2.5.4 → 2.6.1

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,25 +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
- const effectiveInterval = attempt <= 3 ? Math.min(pollIntervalMs, 1500) : pollIntervalMs;
837
- await (0, n8n_workflow_1.sleep)(effectiveInterval);
838
899
  }
839
- 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 });
840
901
  };
841
902
  const isMediaNotReadyError = (error) => {
842
903
  var _a, _b, _c, _d;
@@ -855,15 +916,87 @@ class Instagram {
855
916
  };
856
917
  for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
857
918
  try {
858
- const resource = this.getNodeParameter('resource', itemIndex);
859
- 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
+ }
860
945
  if (resource === 'messaging') {
861
- const graphApiVersion = this.getNodeParameter('graphApiVersion', itemIndex);
862
- 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
+ }
863
972
  try {
864
973
  if (operation === 'sendMessage') {
865
- const recipientId = this.getNodeParameter('recipientId', itemIndex);
866
- 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
+ }
867
1000
  const url = `https://${hostUrl}/${graphApiVersion}/${accountId}/messages`;
868
1001
  const requestOptions = {
869
1002
  headers: {
@@ -882,7 +1015,19 @@ class Instagram {
882
1015
  },
883
1016
  json: true,
884
1017
  };
885
- 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
+ }
886
1031
  returnItems.push({ json: response, pairedItem: { item: itemIndex } });
887
1032
  continue;
888
1033
  }
@@ -914,11 +1059,20 @@ class Instagram {
914
1059
  if (operation === 'refreshAccessToken') {
915
1060
  let token = (_c = this.getNodeParameter('accessToken', itemIndex, '')) !== null && _c !== void 0 ? _c : '';
916
1061
  if (!token) {
917
- 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
+ }
918
1072
  token = (_d = credentials === null || credentials === void 0 ? void 0 : credentials.accessToken) !== null && _d !== void 0 ? _d : '';
919
1073
  }
920
- if (!token) {
921
- 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 });
922
1076
  }
923
1077
  const url = 'https://graph.instagram.com/refresh_access_token';
924
1078
  const requestOptions = {
@@ -933,13 +1087,49 @@ class Instagram {
933
1087
  },
934
1088
  json: true,
935
1089
  };
936
- 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
+ }
937
1103
  returnItems.push({ json: response, pairedItem: { item: itemIndex } });
938
1104
  continue;
939
1105
  }
940
1106
  if (operation === 'exchangeAccessToken') {
941
- const shortLivedToken = this.getNodeParameter('shortLivedAccessToken', itemIndex);
942
- 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
+ }
943
1133
  const url = 'https://graph.instagram.com/access_token';
944
1134
  const requestOptions = {
945
1135
  headers: {
@@ -954,7 +1144,19 @@ class Instagram {
954
1144
  },
955
1145
  json: true,
956
1146
  };
957
- 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
+ }
958
1160
  returnItems.push({ json: response, pairedItem: { item: itemIndex } });
959
1161
  continue;
960
1162
  }
@@ -968,7 +1170,19 @@ class Instagram {
968
1170
  url,
969
1171
  json: true,
970
1172
  };
971
- 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
+ }
972
1186
  returnItems.push({ json: response, pairedItem: { item: itemIndex } });
973
1187
  continue;
974
1188
  }
@@ -1003,13 +1217,64 @@ class Instagram {
1003
1217
  return typeof apiMsg === 'string' ? apiMsg : (_d = e === null || e === void 0 ? void 0 : e.message) !== null && _d !== void 0 ? _d : String(error);
1004
1218
  };
1005
1219
  try {
1006
- const node = this.getNodeParameter('node', itemIndex);
1007
- const graphApiVersion = this.getNodeParameter('graphApiVersion', itemIndex);
1008
- const caption = this.getNodeParameter('caption', itemIndex);
1009
- 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
+ }
1010
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
+ }
1011
1276
  if (mediaItems.length < 2 || mediaItems.length > 10) {
1012
- 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 });
1013
1278
  }
1014
1279
  const pollIntervalMs = 1500;
1015
1280
  const maxPollAttempts = 20;
@@ -1017,11 +1282,20 @@ class Instagram {
1017
1282
  const mediaUri = `https://${hostUrl}/${graphApiVersion}/${node}/media`;
1018
1283
  for (let i = 0; i < mediaItems.length; i++) {
1019
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
+ }
1020
1288
  const isVideo = item.mediaType === 'video';
1021
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
+ }
1022
1296
  const url = isVideo ? ((_h = item.videoUrl) !== null && _h !== void 0 ? _h : '').trim() : ((_j = item.imageUrl) !== null && _j !== void 0 ? _j : '').trim();
1023
- if (!url) {
1024
- 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 });
1025
1299
  }
1026
1300
  const childQs = isVideo
1027
1301
  ? { media_type: 'VIDEO', video_url: url, is_carousel_item: true }
@@ -1041,8 +1315,8 @@ class Instagram {
1041
1315
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), `${mediaLabel}: container creation failed — ${getCarouselErrorMessage(err)}`, { itemIndex });
1042
1316
  }
1043
1317
  const childId = childResponse.id;
1044
- if (!childId) {
1045
- 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 });
1046
1320
  }
1047
1321
  try {
1048
1322
  await waitForContainerReady({
@@ -1079,8 +1353,8 @@ class Instagram {
1079
1353
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Carousel container (create): ${getCarouselErrorMessage(err)}`, { itemIndex });
1080
1354
  }
1081
1355
  const carouselContainerId = carouselResponse.id;
1082
- if (!carouselContainerId) {
1083
- 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 });
1084
1358
  }
1085
1359
  try {
1086
1360
  await waitForContainerReady({
@@ -1134,11 +1408,47 @@ class Instagram {
1134
1408
  }
1135
1409
  }
1136
1410
  if (resource === 'igHashtag') {
1137
- const graphApiVersion = this.getNodeParameter('graphApiVersion', itemIndex);
1138
- 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
+ }
1139
1437
  try {
1140
1438
  if (operation === 'search') {
1141
- 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
+ }
1142
1452
  const url = `https://${hostUrl}/${graphApiVersion}/ig_hashtag_search`;
1143
1453
  const requestOptions = {
1144
1454
  headers: {
@@ -1152,14 +1462,62 @@ class Instagram {
1152
1462
  },
1153
1463
  json: true,
1154
1464
  };
1155
- 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
+ }
1156
1478
  returnItems.push({ json: response, pairedItem: { item: itemIndex } });
1157
1479
  continue;
1158
1480
  }
1159
1481
  if (operation === 'getRecentMedia' || operation === 'getTopMedia') {
1160
- const hashtagId = this.getNodeParameter('hashtagId', itemIndex);
1161
- const returnAll = this.getNodeParameter('returnAll', itemIndex, false);
1162
- 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
+ }
1163
1521
  const edge = operation === 'getRecentMedia' ? 'recent_media' : 'top_media';
1164
1522
  const baseUrl = `https://${hostUrl}/${graphApiVersion}/${hashtagId}/${edge}`;
1165
1523
  const fields = [
@@ -1176,7 +1534,9 @@ class Instagram {
1176
1534
  let after;
1177
1535
  const hardCap = returnAll ? 5000 : limit;
1178
1536
  let hasMore = true;
1537
+ let pageNumber = 0;
1179
1538
  while (hasMore) {
1539
+ pageNumber++;
1180
1540
  const remaining = returnAll ? undefined : hardCap - accumulated.length;
1181
1541
  const pageLimit = remaining !== undefined ? Math.min(remaining, 50) : 50;
1182
1542
  const qs = {
@@ -1196,8 +1556,23 @@ class Instagram {
1196
1556
  qs,
1197
1557
  json: true,
1198
1558
  };
1199
- 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
+ }
1200
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
+ }
1201
1576
  accumulated.push(...pageData);
1202
1577
  const paging = response.paging;
1203
1578
  after = (_p = paging === null || paging === void 0 ? void 0 : paging.cursors) === null || _p === void 0 ? void 0 : _p.after;
@@ -1233,8 +1608,32 @@ class Instagram {
1233
1608
  }
1234
1609
  }
1235
1610
  if (resource === 'page') {
1236
- const graphApiVersion = this.getNodeParameter('graphApiVersion', itemIndex);
1237
- 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
+ }
1238
1637
  try {
1239
1638
  if (operation === 'getInstagramAccount') {
1240
1639
  const url = `https://${hostUrl}/${graphApiVersion}/${pageId}`;
@@ -1249,7 +1648,19 @@ class Instagram {
1249
1648
  },
1250
1649
  json: true,
1251
1650
  };
1252
- 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
+ }
1253
1664
  returnItems.push({ json: response, pairedItem: { item: itemIndex } });
1254
1665
  continue;
1255
1666
  }
@@ -1277,8 +1688,32 @@ class Instagram {
1277
1688
  }
1278
1689
  }
1279
1690
  if (resource === 'igUser') {
1280
- const graphApiVersion = this.getNodeParameter('graphApiVersion', itemIndex);
1281
- 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
+ }
1282
1717
  try {
1283
1718
  if (operation === 'get') {
1284
1719
  const url = `https://${hostUrl}/${graphApiVersion}/${accountId}`;
@@ -1303,13 +1738,49 @@ class Instagram {
1303
1738
  },
1304
1739
  json: true,
1305
1740
  };
1306
- 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
+ }
1307
1754
  returnItems.push({ json: response, pairedItem: { item: itemIndex } });
1308
1755
  continue;
1309
1756
  }
1310
1757
  if (operation === 'getMedia') {
1311
- const returnAll = this.getNodeParameter('returnAll', itemIndex, false);
1312
- 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
+ }
1313
1784
  const baseUrl = `https://${hostUrl}/${graphApiVersion}/${accountId}/media`;
1314
1785
  const fields = [
1315
1786
  'id',
@@ -1325,7 +1796,9 @@ class Instagram {
1325
1796
  let after;
1326
1797
  const hardCap = returnAll ? 5000 : limit;
1327
1798
  let hasMore = true;
1799
+ let pageNumber = 0;
1328
1800
  while (hasMore) {
1801
+ pageNumber++;
1329
1802
  const remaining = returnAll ? undefined : hardCap - accumulated.length;
1330
1803
  const pageLimit = remaining !== undefined ? Math.min(remaining, 100) : 100;
1331
1804
  const qs = {
@@ -1344,8 +1817,23 @@ class Instagram {
1344
1817
  qs,
1345
1818
  json: true,
1346
1819
  };
1347
- 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
+ }
1348
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
+ }
1349
1837
  accumulated.push(...pageData);
1350
1838
  const paging = response.paging;
1351
1839
  after = (_v = paging === null || paging === void 0 ? void 0 : paging.cursors) === null || _v === void 0 ? void 0 : _v.after;
@@ -1381,10 +1869,34 @@ class Instagram {
1381
1869
  }
1382
1870
  }
1383
1871
  if (resource === 'comments') {
1384
- 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
+ }
1385
1885
  try {
1386
1886
  if (operation === 'list') {
1387
- 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
+ }
1388
1900
  const url = `https://${hostUrl}/${graphApiVersion}/${mediaId}/comments`;
1389
1901
  const requestOptions = {
1390
1902
  headers: {
@@ -1394,12 +1906,36 @@ class Instagram {
1394
1906
  url,
1395
1907
  json: true,
1396
1908
  };
1397
- 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
+ }
1398
1922
  returnItems.push({ json: response, pairedItem: { item: itemIndex } });
1399
1923
  continue;
1400
1924
  }
1401
1925
  if (operation === 'hideComment' || operation === 'unhideComment') {
1402
- 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
+ }
1403
1939
  const hideValue = operation === 'hideComment';
1404
1940
  const url = `https://${hostUrl}/${graphApiVersion}/${commentId}`;
1405
1941
  const requestOptions = {
@@ -1413,12 +1949,36 @@ class Instagram {
1413
1949
  },
1414
1950
  json: true,
1415
1951
  };
1416
- 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
+ }
1417
1965
  returnItems.push({ json: response, pairedItem: { item: itemIndex } });
1418
1966
  continue;
1419
1967
  }
1420
1968
  if (operation === 'deleteComment') {
1421
- 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
+ }
1422
1982
  const url = `https://${hostUrl}/${graphApiVersion}/${commentId}`;
1423
1983
  const requestOptions = {
1424
1984
  headers: {
@@ -1428,12 +1988,36 @@ class Instagram {
1428
1988
  url,
1429
1989
  json: true,
1430
1990
  };
1431
- 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
+ }
1432
2004
  returnItems.push({ json: response, pairedItem: { item: itemIndex } });
1433
2005
  continue;
1434
2006
  }
1435
2007
  if (operation === 'disableComments' || operation === 'enableComments') {
1436
- 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
+ }
1437
2021
  const commentEnabled = operation === 'enableComments';
1438
2022
  const url = `https://${hostUrl}/${graphApiVersion}/${mediaId}`;
1439
2023
  const requestOptions = {
@@ -1447,14 +2031,62 @@ class Instagram {
1447
2031
  },
1448
2032
  json: true,
1449
2033
  };
1450
- 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
+ }
1451
2047
  returnItems.push({ json: response, pairedItem: { item: itemIndex } });
1452
2048
  continue;
1453
2049
  }
1454
2050
  if (operation === 'sendPrivateReply') {
1455
- const accountId = this.getNodeParameter('node', itemIndex);
1456
- const commentId = this.getNodeParameter('commentId', itemIndex);
1457
- 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
+ }
1458
2090
  const url = `https://${hostUrl}/${graphApiVersion}/${accountId}/messages`;
1459
2091
  const requestOptions = {
1460
2092
  headers: {
@@ -1473,7 +2105,19 @@ class Instagram {
1473
2105
  },
1474
2106
  json: true,
1475
2107
  };
1476
- 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
+ }
1477
2121
  returnItems.push({ json: response, pairedItem: { item: itemIndex } });
1478
2122
  continue;
1479
2123
  }
@@ -1507,21 +2151,101 @@ class Instagram {
1507
2151
  }
1508
2152
  const handler = resources_1.instagramResourceHandlers[resource];
1509
2153
  if (!handler) {
1510
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unsupported resource: ${resource}`, {
1511
- itemIndex,
1512
- });
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 });
1513
2207
  }
1514
- const node = this.getNodeParameter('node', itemIndex);
1515
- const graphApiVersion = this.getNodeParameter('graphApiVersion', itemIndex);
1516
- const caption = this.getNodeParameter('caption', itemIndex);
1517
- const additionalFields = this.getNodeParameter('additionalFields', itemIndex, {});
1518
2208
  const altText = (_0 = additionalFields.altText) !== null && _0 !== void 0 ? _0 : '';
1519
2209
  const rawLocationId = additionalFields.locationId;
1520
2210
  const userTagsCollection = additionalFields.userTags;
1521
2211
  const productTagsCollection = additionalFields.productTags;
1522
2212
  const httpRequestMethod = 'POST';
1523
2213
  const mediaUri = `https://${hostUrl}/${graphApiVersion}/${node}/media`;
1524
- 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
+ }
1525
2249
  const mediaQs = {
1526
2250
  caption,
1527
2251
  ...mediaPayload,
@@ -1593,16 +2317,63 @@ class Instagram {
1593
2317
  };
1594
2318
  let mediaResponse;
1595
2319
  try {
1596
- mediaResponse = await this.helpers.httpRequestWithAuthentication.call(this, 'instagramApi', mediaRequestOptions);
2320
+ mediaResponse = (await this.helpers.httpRequestWithAuthentication.call(this, 'instagramApi', mediaRequestOptions));
1597
2321
  }
1598
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
+ }
1599
2352
  if (!this.continueOnFail()) {
1600
- 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);
1601
2373
  }
1602
2374
  let errorItem;
1603
- const err = error;
1604
2375
  if (err.response !== undefined) {
1605
- 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 : {};
1606
2377
  errorItem = {
1607
2378
  statusCode: err.statusCode,
1608
2379
  ...graphApiErrors,
@@ -1616,30 +2387,68 @@ class Instagram {
1616
2387
  continue;
1617
2388
  }
1618
2389
  if (typeof mediaResponse === 'string') {
2390
+ const responseStr = mediaResponse;
1619
2391
  if (!this.continueOnFail()) {
1620
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Media creation response body is not valid JSON.', {
1621
- itemIndex,
1622
- });
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 });
1623
2393
  }
1624
- returnItems.push({ json: { message: mediaResponse }, pairedItem: { item: itemIndex } });
2394
+ returnItems.push({ json: { message: responseStr }, pairedItem: { item: itemIndex } });
1625
2395
  continue;
1626
2396
  }
1627
2397
  const creationId = mediaResponse.id;
1628
- 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;
1629
2407
  if (!this.continueOnFail()) {
1630
- 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 });
1631
2412
  }
1632
- 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
+ });
1633
2424
  continue;
1634
2425
  }
1635
- await waitForContainerReady({
1636
- creationId,
1637
- hostUrl,
1638
- graphApiVersion,
1639
- itemIndex,
1640
- pollIntervalMs: handler.pollIntervalMs,
1641
- maxPollAttempts: handler.maxPollAttempts,
1642
- });
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
+ }
1643
2452
  const publishUri = `https://${hostUrl}/${graphApiVersion}/${node}/media_publish`;
1644
2453
  const publishQs = {
1645
2454
  creation_id: creationId,
@@ -1660,7 +2469,7 @@ class Instagram {
1660
2469
  let publishFailedWithError = false;
1661
2470
  for (let attempt = 1; attempt <= publishMaxAttempts; attempt++) {
1662
2471
  try {
1663
- publishResponse = await this.helpers.httpRequestWithAuthentication.call(this, 'instagramApi', publishRequestOptions);
2472
+ publishResponse = (await this.helpers.httpRequestWithAuthentication.call(this, 'instagramApi', publishRequestOptions));
1664
2473
  publishSucceeded = true;
1665
2474
  break;
1666
2475
  }
@@ -1675,7 +2484,7 @@ class Instagram {
1675
2484
  let errorItem;
1676
2485
  const err = error;
1677
2486
  if (err.response !== undefined) {
1678
- 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 : {};
1679
2488
  errorItem = {
1680
2489
  statusCode: err.statusCode,
1681
2490
  ...graphApiErrors,
@@ -1700,13 +2509,18 @@ class Instagram {
1700
2509
  }
1701
2510
  if (typeof publishResponse === 'string') {
1702
2511
  if (!this.continueOnFail()) {
1703
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Media publish response body is not valid JSON.', {
1704
- itemIndex,
1705
- });
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 });
1706
2513
  }
1707
2514
  returnItems.push({ json: { message: publishResponse }, pairedItem: { item: itemIndex } });
1708
2515
  continue;
1709
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
+ }
1710
2524
  returnItems.push({ json: publishResponse, pairedItem: { item: itemIndex } });
1711
2525
  }
1712
2526
  catch (error) {
@@ -1716,7 +2530,7 @@ class Instagram {
1716
2530
  let errorItem;
1717
2531
  const errorWithGraph = error;
1718
2532
  if (errorWithGraph.response !== undefined) {
1719
- 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 : {};
1720
2534
  errorItem = {
1721
2535
  statusCode: errorWithGraph.statusCode,
1722
2536
  ...graphApiErrors,