UNPKG

matterbridge-webhooks

Version:
81 lines (80 loc) 4.5 kB
import { bridgedNode, MatterbridgeDynamicPlatform, MatterbridgeEndpoint, onOffLight, onOffOutlet, onOffSwitch } from 'matterbridge'; import { fetch } from './fetch.js'; export class Platform extends MatterbridgeDynamicPlatform { webhooks; bridgedDevices = new Map(); constructor(matterbridge, log, config) { super(matterbridge, log, config); if (this.verifyMatterbridgeVersion === undefined || typeof this.verifyMatterbridgeVersion !== 'function' || !this.verifyMatterbridgeVersion('2.2.5')) { throw new Error(`This plugin requires Matterbridge version >= "2.2.5". Please update Matterbridge to the latest version in the frontend.`); } this.log.info('Initializing platform:', this.config.name); this.webhooks = this.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 = 1; for (const webhookName in this.webhooks) { if (Object.prototype.hasOwnProperty.call(this.webhooks, webhookName)) { const webhook = this.webhooks[webhookName]; this.setSelectDevice('webhook' + i, webhookName, webhook.httpUrl, 'webhook'); if (!this.validateDevice(['webhook' + i, webhookName])) return; this.log.info(`Registering device: ${webhookName}`, webhook.method, 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) { this.log.info('onAction called with action:', action, 'and value:', value ?? 'none', 'and id:', id ?? 'none'); if (action === 'test') { 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!`); }) .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(); } }