2026-10-14 23:17:40 +02:00
|
|
|
|
# nextcloud-nodered-zammad
|
|
|
|
|
|
|
|
|
|
|
|
Node-RED nodes for the [Zammad](https://zammad.org/) helpdesk API. Part of the
|
|
|
|
|
|
[nextcloud-nodered](https://kode.hannesahlin.se/n3wk/) suite.
|
|
|
|
|
|
|
|
|
|
|
|
## Package
|
|
|
|
|
|
|
|
|
|
|
|
`node-red-contrib-nextcloud-zammad`
|
|
|
|
|
|
|
|
|
|
|
|
## Nodes
|
|
|
|
|
|
|
|
|
|
|
|
| Node | Type | Purpose |
|
|
|
|
|
|
|------|------|---------|
|
|
|
|
|
|
| `zammad-config` | config | Base URL + Token (or Basic auth) |
|
|
|
|
|
|
| `zammad-api` | function | Generic HTTP caller — any method + endpoint |
|
|
|
|
|
|
| `zammad-ticket` | function | list, search, get, create, update, articles, addArticle, tags, addTag |
|
|
|
|
|
|
| `zammad-user` | function | me, list, search, get, create |
|
|
|
|
|
|
| `zammad-organization` | function | list, search, get, create |
|
|
|
|
|
|
|
|
|
|
|
|
## Installation
|
|
|
|
|
|
|
|
|
|
|
|
### Prerequisites
|
|
|
|
|
|
|
|
|
|
|
|
- An existing [nextcloud-node-red](https://kode.hannesahlin.se/n3wk/nextcloud-nodered-ocs-api) installation.
|
2026-10-14 23:21:15 +02:00
|
|
|
|
- A Zammad API token with `ticket.agent` permission.
|
2026-10-14 23:17:40 +02:00
|
|
|
|
|
|
|
|
|
|
### Quick install (recommended)
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
2026-10-14 23:27:59 +02:00
|
|
|
|
git clone https://kode.hannesahlin.se/n3wk/nextcloud-nodered-zammad.git
|
2026-10-14 23:17:40 +02:00
|
|
|
|
cd nextcloud-nodered-zammad
|
|
|
|
|
|
export NODERED_DIR=/path/to/your/nextcloud-node-red
|
|
|
|
|
|
bash bootstrap-install.sh
|
|
|
|
|
|
cd $NODERED_DIR
|
|
|
|
|
|
docker compose build --no-cache
|
|
|
|
|
|
docker compose up -d
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### Manual install
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
export NODERED_DIR=/path/to/your/nextcloud-node-red
|
|
|
|
|
|
bash integrate-into-nodered.sh
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
The integrate script:
|
|
|
|
|
|
1. Copies all `.js` and `.html` files into `$NODERED_DIR/nodes/`.
|
|
|
|
|
|
2. Copies the package to `$NODERED_DIR/opt/nextcloud-nodes/node-red-contrib-nextcloud-zammad/`.
|
|
|
|
|
|
3. Patches `$NODERED_DIR/entrypoint.sh` to install the nodes on container start.
|
|
|
|
|
|
4. Is idempotent — safe to run multiple times.
|
|
|
|
|
|
|
|
|
|
|
|
## Authentication
|
|
|
|
|
|
|
|
|
|
|
|
| Method | Header | Notes |
|
|
|
|
|
|
|--------|--------|-------|
|
2026-10-14 23:21:15 +02:00
|
|
|
|
| Token (preferred) | `Authorization: Token token=<your-token>` | Create token with `ticket.agent` permission |
|
2026-10-14 23:22:19 +02:00
|
|
|
|
| Basic | `Authorization: Basic base64(user:pass)` | Zammad username (may differ from email address) |
|
2026-10-14 23:17:40 +02:00
|
|
|
|
|
2026-10-14 23:21:15 +02:00
|
|
|
|
**Important:** Base URL is the Zammad API v1 URL, e.g. `https://example.com/api/v1/`.
|
2026-10-14 23:17:40 +02:00
|
|
|
|
|
|
|
|
|
|
## Node Details
|
|
|
|
|
|
|
|
|
|
|
|
### zammad-ticket
|
|
|
|
|
|
|
|
|
|
|
|
Operations: `list`, `search`, `get`, `create`, `update`, `articles`, `addArticle`, `tags`, `addTag`.
|
|
|
|
|
|
|
|
|
|
|
|
**Create from individual properties:**
|
|
|
|
|
|
```
|
2026-10-14 23:27:59 +02:00
|
|
|
|
msg.title = "Order #12345 – John Doe (Acme Corp)"
|
|
|
|
|
|
msg.customer = "john.doe@example.com"
|
2026-10-14 23:17:40 +02:00
|
|
|
|
msg.body = product list + address + phone
|
|
|
|
|
|
msg.group = "Orders"
|
|
|
|
|
|
msg.state = "open"
|
|
|
|
|
|
msg.priority = "2 normal"
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**Create from full JSON payload:**
|
|
|
|
|
|
```
|
|
|
|
|
|
msg.payload = { title: "...", customer: "...", body: "...", group: "..." }
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**Search syntax (Zammad query):**
|
|
|
|
|
|
```
|
|
|
|
|
|
state.name:open
|
|
|
|
|
|
title:order
|
|
|
|
|
|
customer.email:foo@example.com
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### zammad-api
|
|
|
|
|
|
|
|
|
|
|
|
Generic HTTP caller. Override config via:
|
|
|
|
|
|
- `msg.method` — GET, POST, PUT, DELETE
|
|
|
|
|
|
- `msg.endpoint` — `/tickets`, `/users/search`, etc.
|
|
|
|
|
|
- `msg.payload` — request body
|
|
|
|
|
|
- `msg.headers` — additional headers
|
|
|
|
|
|
|
|
|
|
|
|
## Vertical Integration Flow: WooCommerce → Zammad → Nextcloud
|
|
|
|
|
|
|
|
|
|
|
|
This example creates a Zammad ticket from a WooCommerce order and organizes
|
|
|
|
|
|
the customer in Nextcloud.
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
[
|
|
|
|
|
|
{
|
|
|
|
|
|
"id": "wc-trigger",
|
|
|
|
|
|
"type": "inject",
|
|
|
|
|
|
"name": "New Order",
|
|
|
|
|
|
"topic": "",
|
|
|
|
|
|
"payload": "",
|
|
|
|
|
|
"payloadType": "date",
|
|
|
|
|
|
"repeat": "",
|
|
|
|
|
|
"crontab": "",
|
|
|
|
|
|
"once": true,
|
|
|
|
|
|
"x": 150, "y": 100
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
"id": "wc-extract",
|
|
|
|
|
|
"type": "function",
|
|
|
|
|
|
"name": "Extract Order Info",
|
|
|
|
|
|
"func": "msg.title = 'Order #' + msg.payload.number + ' – ' + msg.payload.billing.first_name + ' ' + msg.payload.billing.last_name;\nmsg.customer = msg.payload.billing.email;\nmsg.body = 'Products:\\n';\nfor (let item of msg.payload.line_items) {\n msg.body += '- ' + item.name + ' x' + item.quantity + ' (' + msg.payload.currency + ' ' + item.total + ')\\n';\n}\nmsg.body += '\\nTotal: ' + msg.payload.currency + ' ' + msg.payload.total + '\\n';\nmsg.body += 'Address: ' + msg.payload.billing.address_1 + ', ' + msg.payload.billing.city + ' ' + msg.payload.billing.postcode + '\\n';\nmsg.body += 'Phone: ' + msg.payload.billing.phone;\nreturn msg;",
|
|
|
|
|
|
"outputs": 1,
|
|
|
|
|
|
"x": 350, "y": 100
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
"id": "zammad-create",
|
|
|
|
|
|
"type": "zammad-ticket",
|
|
|
|
|
|
"name": "Create Ticket",
|
|
|
|
|
|
"config": "zammad-config-id",
|
|
|
|
|
|
"operation": "create",
|
|
|
|
|
|
"x": 550, "y": 100
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
"id": "zammad-tag",
|
|
|
|
|
|
"type": "zammad-ticket",
|
|
|
|
|
|
"name": "Add WooCommerce Tag",
|
|
|
|
|
|
"config": "zammad-config-id",
|
|
|
|
|
|
"operation": "addTag",
|
|
|
|
|
|
"x": 750, "y": 100
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**Full flow with Nextcloud OCS nodes** (after Zammad ticket creation):
|
|
|
|
|
|
|
|
|
|
|
|
1. `woocommerce-order` (operation: list, status=processing) → trigger
|
|
|
|
|
|
2. Function node extracts `billing.email`, `billing.first_name`, `billing.last_name`, `billing.company`, `number`, `total`, `currency`, `line_items`
|
|
|
|
|
|
3. `zammad-ticket` (operation: create) — builds ticket from extracted data
|
|
|
|
|
|
4. `zammad-ticket` (operation: addTag) — tag `woocommerce-order`
|
|
|
|
|
|
5. Existing Nextcloud OCS nodes create/update:
|
|
|
|
|
|
- Customer folder
|
|
|
|
|
|
- Note or Deck card
|
|
|
|
|
|
- Optional calendar event
|
|
|
|
|
|
- Link back to Zammad ticket in ticket body or Nextcloud note
|
|
|
|
|
|
|
|
|
|
|
|
## Integration with Other Packages
|
|
|
|
|
|
|
|
|
|
|
|
- **nextcloud-nodered-woocommerce**: Polls WooCommerce API for new orders and triggers this flow.
|
|
|
|
|
|
- **nextcloud-nodered-ocs-api**: Provides Nextcloud OCS nodes for creating folders, notes, deck cards, etc.
|
|
|
|
|
|
- **nextcloud-nodered-agent**: Agent-based nodes for complex orchestration.
|
|
|
|
|
|
|
|
|
|
|
|
## Credentials Security
|
|
|
|
|
|
|
|
|
|
|
|
- Tokens and passwords are stored **only** in the Node-RED config node (encrypted at rest).
|
|
|
|
|
|
- Never commit credentials to git (`.gitignore` excludes them).
|
|
|
|
|
|
- The config node uses Node-RED's built-in credential encryption.
|
|
|
|
|
|
|
|
|
|
|
|
## License
|
|
|
|
|
|
|
|
|
|
|
|
MIT
|