diff --git a/apps/client/src/features/modals/integration-modal/http/HttpSubscriptionRow.tsx b/apps/client/src/features/modals/integration-modal/http/HttpSubscriptionRow.tsx index 3e7349cef..6b89e9366 100644 --- a/apps/client/src/features/modals/integration-modal/http/HttpSubscriptionRow.tsx +++ b/apps/client/src/features/modals/integration-modal/http/HttpSubscriptionRow.tsx @@ -1,5 +1,5 @@ import { Control, useFieldArray, UseFormRegister } from 'react-hook-form'; -import { Button, IconButton, Input, Switch } from '@chakra-ui/react'; +import { Button, IconButton, Input, Select, Switch } from '@chakra-ui/react'; import { FiChevronUp } from '@react-icons/all-files/fi/FiChevronUp'; import { IoRemove } from '@react-icons/all-files/io5/IoRemove'; import { HttpSettings, TimerLifeCycle } from 'ontime-types'; @@ -40,8 +40,10 @@ export default function SubscriptionRow(props: SubscriptionRowProps) { return; } append({ - message: '', + url: '', + options: '', enabled: false, + method: 'GET', }); }; @@ -70,10 +72,26 @@ export default function SubscriptionRow(props: SubscriptionRowProps) { size='xs' variant='ontime-filled-on-light' autoComplete='off' - {...register(`subscriptions.${cycle}.${index}.message`, { + {...register(`subscriptions.${cycle}.${index}.url`, { pattern: { value: startsWithHttpOrS, message: 'Request address must start with http://' }, })} /> + + ))} diff --git a/apps/server/src/services/integration-service/HttpIntegration.ts b/apps/server/src/services/integration-service/HttpIntegration.ts index db5a6abff..b6428df91 100644 --- a/apps/server/src/services/integration-service/HttpIntegration.ts +++ b/apps/server/src/services/integration-service/HttpIntegration.ts @@ -77,14 +77,15 @@ export class HttpIntegration implements IIntegration { } // check subscriptions for action - const eventSubscriptions = this.subscriptions?.[action] || []; + const eventSubscriptions = (this.subscriptions?.[action] as HttpSubscriptionOptions[]) || []; eventSubscriptions.forEach((sub) => { - const { enabled, message } = sub; - if (enabled && message) { - const parsedMessage = parseTemplateNested(message, state || {}); + const { enabled, url, options, method } = sub; + if (enabled && url) { + const templateUrl = parseTemplateNested(url, state || {}); + const templateOptions = parseTemplateNested(options, state || {}); try { - const parsedUrl = new globalThis.URL(parsedMessage); + const parsedUrl = new globalThis.URL(templateUrl); // if (parsedUrl.protocol != 'http:') { // logger.error(LogOrigin.Tx, `HTTP Integration: Only HTTP allowed, got ${parsedUrl.protocol}`); // return { @@ -92,7 +93,7 @@ export class HttpIntegration implements IIntegration { // message: `Only HTTP allowed, got ${parsedUrl.protocol}`, // }; // } - this.emit(parsedUrl); + this.emit(templateUrl, templateOptions, method); } catch (err) { logger.error(LogOrigin.Tx, `HTTP Integration: ${err}`); return { @@ -104,11 +105,18 @@ export class HttpIntegration implements IIntegration { }); } - async emit(path: globalThis.URL) { + async emit(path: string, options: string, method: 'GET' | 'POST') { try { - await got.get(path, { - retry: { limit: 0 }, - }); + if (method === 'GET') { + await got.get(path, { + searchParams: options, + retry: { limit: 0 }, + }); + } else if (method === 'POST') { + await got.post(path, { + retry: { limit: 0 }, + }); + } } catch (err) { logger.error(LogOrigin.Tx, `HTTP integration: ${err}`); } diff --git a/apps/server/src/utils/parserFunctions.ts b/apps/server/src/utils/parserFunctions.ts index 08c630211..5000a0d86 100644 --- a/apps/server/src/utils/parserFunctions.ts +++ b/apps/server/src/utils/parserFunctions.ts @@ -227,9 +227,15 @@ export const parseOsc = (data: { osc?: Partial }): OSCSettings => { */ export const validateHttpSubscriptionCycle = (data: HttpSubscriptionOptions[]): boolean => { for (const subscriptionOption of data) { - const isHttp = - subscriptionOption.message?.startsWith('http://') || subscriptionOption.message?.startsWith('https://'); - if (typeof subscriptionOption.message !== 'string' || !isHttp || typeof subscriptionOption.enabled !== 'boolean') { + const isHttp = subscriptionOption.url?.startsWith('http://') || subscriptionOption.url?.startsWith('https://'); + const ishttpMethod = subscriptionOption.method == 'GET' || subscriptionOption.method == 'POST'; + if ( + typeof subscriptionOption.url !== 'string' || + typeof subscriptionOption.options !== 'string' || + !isHttp || + !ishttpMethod || + typeof subscriptionOption.enabled !== 'boolean' + ) { return false; } } diff --git a/packages/types/src/definitions/core/HttpSettings.type.ts b/packages/types/src/definitions/core/HttpSettings.type.ts index 39c0898ad..fe592c36f 100644 --- a/packages/types/src/definitions/core/HttpSettings.type.ts +++ b/packages/types/src/definitions/core/HttpSettings.type.ts @@ -1,6 +1,7 @@ import { Subscription } from './Subscription.type.js'; -export type HttpSubscriptionOptions = { message: string; enabled: boolean }; +type httpMethod = 'GET' | 'POST'; +export type HttpSubscriptionOptions = { url: string; options: string; enabled: boolean; method: httpMethod }; export type HttpSubscription = Subscription; export interface HttpSettings {