H HotelDeskComplete Hotel Management System

Plugin quick start

Create the ZIP structure, manifest, backend and first page.

Create a folder whose ZIP root contains hoteldesk-plugin.json. IDs use lowercase letters, numbers and hyphens; versions use semantic versioning.

{
  "id": "my-hotel-plugin",
  "name": "My Hotel Plugin",
  "version": "1.0.0",
  "api": 2,
  "main": "main.js",
  "icon": "assets/icon.svg",
  "minAppVersion": "0.1.1",
  "capabilities": ["hooks", "storage", "hotel-info", "rpc"],
  "hooks": ["app:ready"],
  "web": { "enabled": true },
  "contributes": {
    "navigation": [{
      "id": "overview",
      "page": "overview",
      "icon": "package",
      "surfaces": ["desktop", "web"],
      "title": { "en": "Overview", "fr": "Aperçu", "ro": "Prezentare" }
    }],
    "pages": [{
      "id": "overview",
      "type": "document",
      "entry": "pages/overview.html",
      "surfaces": ["desktop", "web"],
      "title": { "en": "Overview", "fr": "Aperçu", "ro": "Prezentare" }
    }]
  }
}

Create main.js for trusted sandboxed backend logic:

module.exports.activate = async function activate(hoteldesk) {
  await hoteldesk.storage.set('activatedAt', new Date().toISOString());

  hoteldesk.hooks.on('app:ready', async ({ version }) => {
    const hotel = await hoteldesk.system.hotelInfo();
    console.log(`${hotel.name} runs HotelDesk ${version}`);
  });

  hoteldesk.rpc.handle(async (action, payload) => {
    if (action === 'hello') {
      return { message: `Hello ${String(payload.name || 'guest')}` };
    }
    throw new Error('Unsupported plugin action.');
  });
};

Create pages/overview.html:

<!doctype html>
<html><body>
  <article class="hd-card">
    <h1>My plugin</h1>
    <button id="hello">Run action</button>
    <output id="result"></output>
  </article>
  <script>
    document.querySelector('#hello').addEventListener('click', async () => {
      const result = await window.HotelDeskPlugin.invoke('hello', { name: 'HotelDesk' });
      document.querySelector('#result').textContent = result.message;
    });
  </script>
</body></html>

ZIP the folder contents, not the parent folder, then install it from Plugins → Install ZIP.