{"record":{"id":"27991307f33ad91d","repo":"RocketChat/Rocket.Chat","slug":"trigger-is-not-configured-to-use-an-external-servi","errorCode":null,"errorMessage":"Trigger is not configured to use an external service","messagePattern":"Trigger is not configured to use an external service","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/ee/server/api/v1/omnichannel/triggers.ts","lineNumber":86,"sourceCode":"\t\t\tnumRequestsAllowed: 10,\n\t\t\tintervalTimeInMS: 60000,\n\t\t},\n\t\tvalidateParams: isLivechatTriggerWebhookCallParams,\n\t\tlicense: ['livechat-enterprise'],\n\t},\n\t{\n\t\tasync post() {\n\t\t\tconst { _id: triggerId } = this.urlParams;\n\t\t\tconst { token: visitorToken, extraData } = this.bodyParams;\n\n\t\t\tconst trigger = await LivechatTrigger.findOneById(triggerId);\n\n\t\t\tif (!trigger) {\n\t\t\t\tthrow new Error('Invalid trigger');\n\t\t\t}\n\n\t\t\tif (!trigger?.actions.length || !isExternalServiceTrigger(trigger)) {\n\t\t\t\tthrow new Error('Trigger is not configured to use an external service');\n\t\t\t}\n\n\t\t\tconst { params: { serviceTimeout = 5000, serviceUrl, serviceFallbackMessage = 'trigger-default-fallback-message' } = {} } =\n\t\t\t\ttrigger.actions[0];\n\n\t\t\tif (!serviceUrl) {\n\t\t\t\tthrow new Error('Invalid service URL');\n\t\t\t}\n\n\t\t\tconst token = settings.get<string>('Livechat_secret_token');\n\n\t\t\tif (!token) {\n\t\t\t\tthrow new Error('Livechat secret token is not configured');\n\t\t\t}\n\n\t\t\tconst body = {\n\t\t\t\tmetadata: extraData,\n\t\t\t\tvisitorToken,","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/ee/server/api/v1/omnichannel/triggers.ts#L68-L104","documentation":"Thrown by the POST livechat/triggers/:_id/external-service/call route when the loaded Livechat trigger either has no actions or its actions are not all of type 'use-external-service'. The guard isExternalServiceTrigger requires every action in trigger.actions to have name === 'use-external-service'. This route exists only to invoke an external webhook, so a trigger configured for a different action type (e.g. send-message) is a caller/configuration mistake.","triggerScenarios":"Calling POST /api/v1/livechat/triggers/<triggerId>/external-service/call with a visitorToken where the trigger referenced by <triggerId> was saved with actions of name 'send-message' (or with an empty actions array). The license livechat-enterprise is required by the route, so it only applies on EE.","commonSituations":"Admin saved a Livechat trigger with a 'Send a message' action, then the omnichannel widget or a custom integration tries to call the external-service endpoint against that same trigger ID. Also occurs after a trigger was edited to switch action types but the client still holds the old trigger ID, or a trigger was created via API with the wrong action schema.","solutions":["Open the trigger in Administration > Omnichannel > Triggers and confirm its action is set to 'Use an external service' (name === 'use-external-service') with a configured serviceUrl.","If using the REST API to create/edit the trigger, ensure every entry in the actions array has name: 'use-external-service' and a params.serviceUrl.","Verify you are passing the correct triggerId in the URL path; a different trigger with a non-external-service action will fail this check.","Confirm isExternalServiceTrigger semantics: ALL actions must be external-service, not just the first one."],"exampleFix":"// before - trigger saved with wrong action type\n{\n  \"actions\": [{ \"name\": \"send-message\", \"params\": { \"msg\": \"hi\" } }]\n}\n\n// after - configure as external service\n{\n  \"actions\": [{\n    \"name\": \"use-external-service\",\n    \"params\": {\n      \"sender\": \"queue\",\n      \"name\": \"my-bot\",\n      \"serviceUrl\": \"https://bot.example.com/inbox\",\n      \"serviceTimeout\": 5000,\n      \"serviceFallbackMessage\": \"Sorry, no agents available\"\n    }\n  }]\n}","handlingStrategy":"validation","validationCode":"import { LivechatTrigger } from '@rocket.chat/models';\nimport { isExternalServiceTrigger } from '@rocket.chat/core-typings';\n\nasync function assertTriggerReady(triggerId: string) {\n  const trigger = await LivechatTrigger.findOneById(triggerId);\n  if (!trigger) throw new Error('Invalid trigger');\n  if (!trigger.actions?.length || !isExternalServiceTrigger(trigger)) {\n    throw new Error(`Trigger ${triggerId} is not an external-service trigger`);\n  }\n  if (!trigger.actions[0].params?.serviceUrl) {\n    throw new Error(`Trigger ${triggerId} has no serviceUrl`);\n  }\n  return trigger;\n}\n\n// call before invoking /external-service/call\nawait assertTriggerReady(triggerId);","typeGuard":"import type { ILivechatTrigger, ILivechatUseExternalServiceAction } from '@rocket.chat/core-typings';\n\n// already exported by @rocket.chat/core-typings:\nexport const isExternalServiceTrigger = (\n  trigger: ILivechatTrigger,\n): trigger is ILivechatTrigger & { actions: ILivechatUseExternalServiceAction[] } =>\n  trigger.actions.every((a) => a.name === 'use-external-service');\n\nconst isExternalServiceUrlConfigured = (\n  trigger: ILivechatTrigger,\n): boolean =>\n  isExternalServiceTrigger(trigger) &&\n  !!trigger.actions[0]?.params?.serviceUrl;","tryCatchPattern":"try {\n  const res = await fetch(`/api/v1/livechat/triggers/${triggerId}/external-service/call`, {\n    method: 'POST',\n    headers: { 'Content-Type': 'application/json' },\n    body: JSON.stringify({ token: visitorToken, extraData })\n  });\n  if (!res.ok) throw new Error(await res.text());\n} catch (e) {\n  if (e instanceof Error && e.message.includes('not configured to use an external service')) {\n    // surface a configuration prompt to the admin instead of retrying\n  }\n}","preventionTips":["Validate the trigger document (actions type + serviceUrl) in an admin check before exposing the call endpoint to visitors.","Keep a typed helper that asserts isExternalServiceTrigger AND serviceUrl presence, used by every caller.","Do not reuse trigger IDs across action-type changes; create a new trigger when switching to external-service."],"tags":["omnichannel","livechat-trigger","configuration","enterprise"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}