UNPKG

matterbridge-webhooks

Version:
110 lines (109 loc) 6.11 kB
import { bridgedNode, MatterbridgeDynamicPlatform, MatterbridgeEndpoint, onOffLight, onOffOutlet, onOffSwitch } from 'matterbridge'; import { isValidObject } from 'matterbridge/utils'; import { fetch } from './fetch.js'; export default function initializePlugin(matterbridge, log, config) { return new WebhooksPlatform(matterbridge, log, config); } export class WebhooksPlatform extends MatterbridgeDynamicPlatform { webhooks; bridgedDevices = new Map(); constructor(matterbridge, log, config) { super(matterbridge, log, config); if (this.verifyMatterbridgeVersion === undefined || typeof this.verifyMatterbridgeVersion !== 'function' || !this.verifyMatterbridgeVersion('3.3.0')) { throw new Error(`This plugin requires Matterbridge version >= "3.3.0". Please update Matterbridge to the latest version in the frontend.`); } this.log.info('Initializing platform:', this.config.name); this.webhooks = config.webhooks; this.log.info('Finished initializing platform:', this.config.name); } async onStart(reason) { this.log.info('onStart called with reason:', reason ?? 'none'); await this.ready; await this.clearSelect(); let i = 0; for (const webhookName in this.webhooks) { this.log.debug(`Loading webhook ${++i} ${webhookName} with method ${this.webhooks[webhookName].method} and url ${this.webhooks[webhookName].httpUrl}`); const webhook = this.webhooks[webhookName]; this.setSelectDevice('webhook' + i, webhookName, undefined, 'hub'); if (!this.validateDevice(['webhook' + i, webhookName], true)) continue; this.log.info(`Registering device: ${webhookName} with method ${webhook.method} and url ${webhook.httpUrl}`); const device = new MatterbridgeEndpoint([this.config.deviceType === 'Outlet' ? onOffOutlet : this.config.deviceType === 'Light' ? onOffLight : onOffSwitch, bridgedNode], { uniqueStorageKey: webhookName }, this.config.debug) .createDefaultBridgedDeviceBasicInformationClusterServer(webhookName, 'webhook' + i++, this.matterbridge.aggregatorVendorId, 'Matterbridge', 'Matterbridge Webhook', 0, this.config.version) .createOnOffClusterServer(false) .addRequiredClusterServers() .addCommandHandler('on', async () => { this.log.info(`Webhook ${webhookName} triggered.`); await device.setAttribute('onOff', 'onOff', false, device.log); fetch(webhook.httpUrl, webhook.method) .then(() => this.log.notice(`Webhook ${webhookName} successful!`)) .catch((err) => { this.log.error(`Webhook ${webhookName} failed: ${err instanceof Error ? err.message : err}`); }); }); await this.registerDevice(device); this.bridgedDevices.set(webhookName, device); } } async onConfigure() { await super.onConfigure(); this.log.info('onConfigure called'); this.bridgedDevices.forEach(async (device) => { this.log.info(`Configuring device: ${device.deviceName}`); await device.setAttribute('onOff', 'onOff', false, device.log); }); } async onAction(action, value, id, formData) { this.log.info('onAction called with action:', action, 'and value:', value ?? 'none', 'and id:', id ?? 'none'); this.log.debug('onAction called with formData:', formData ?? 'none'); if (id?.startsWith('root_webhooks_')) id = id.replace('root_webhooks_', ''); if (id?.endsWith('_test')) id = id.replace('_test', ''); if (action === 'test') { if (isValidObject(formData, 1) && isValidObject(formData.webhooks, 1)) { const webhooks = formData.webhooks; for (const webhookName in webhooks) { if (Object.prototype.hasOwnProperty.call(webhooks, webhookName)) { const webhook = webhooks[webhookName]; if (id?.includes(webhookName)) { this.log.info(`Testing new webhook ${webhookName} method ${webhook.method} url ${webhook.httpUrl}`); fetch(webhook.httpUrl, webhook.method) .then(() => { this.log.notice(`Webhook test ${webhookName} successful!`); return; }) .catch((err) => { this.log.error(`Webhook test ${webhookName} failed: ${err instanceof Error ? err.message : err}`); }); } } } return; } for (const webhookName in this.webhooks) { if (Object.prototype.hasOwnProperty.call(this.webhooks, webhookName)) { const webhook = this.webhooks[webhookName]; if (id?.includes(webhookName)) { this.log.info(`Testing webhook ${webhookName} method ${webhook.method} url ${webhook.httpUrl}`); fetch(webhook.httpUrl, webhook.method) .then(() => { this.log.notice(`Webhook test ${webhookName} successful!`); return; }) .catch((err) => { this.log.error(`Webhook test ${webhookName} failed: ${err instanceof Error ? err.message : err}`); }); } } } } } async onShutdown(reason) { await super.onShutdown(reason); this.log.info('onShutdown called with reason:', reason ?? 'none'); if (this.config.unregisterOnShutdown === true) await this.unregisterAllDevices(); this.bridgedDevices.clear(); } }