Skip to content

Commit fd0ea43

Browse files
committed
Refine docs
1 parent bf718ed commit fd0ea43

9 files changed

Lines changed: 57 additions & 241 deletions

File tree

actions/gls-action/src/helpers.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ export function transformValidateShipmentRequestDataToInternalFormat(data: Valid
245245
Shipment: {
246246
...data.Shipment,
247247
Middleware: "CodeZeroviaGLS",
248-
Shipper: getShipper(data.Shipment.Shipper, context, contactID),
248+
Shipper: getShipper(context, contactID, data.Shipment.Shipper),
249249
Service: InternalShipmentServiceSchema.parse(data.Shipment.Service),
250250
ShipmentUnit: InternalShipmentUnitSchema.parse(data.Shipment.ShipmentUnit)
251251
}
@@ -258,27 +258,31 @@ function transformShipmentRequestDataToInternalFormat(data: ShipmentRequestData,
258258
Shipment: {
259259
...data.Shipment,
260260
Middleware: "CodeZeroviaGLS",
261-
Shipper: getShipper(data.Shipment.Shipper, context, contactID),
261+
Shipper: getShipper(context, contactID, data.Shipment.Shipper),
262262
Service: InternalShipmentServiceSchema.parse(data.Shipment.Service),
263263
ShipmentUnit: InternalShipmentUnitSchema.parse(data.Shipment.ShipmentUnit)
264264
}
265265
}
266266
}
267267

268-
function getShipper(shipper: Shipper, context: HerculesFunctionContext | undefined, contactID: string | undefined): InternalShipper {
268+
function getShipper(context: HerculesFunctionContext | undefined, contactID: string | undefined, shipper?: Shipper): InternalShipper {
269269
const configShipper = context?.matchedConfig.findConfig("shipper") as Shipper || undefined
270270

271-
if (configShipper) {
272-
return {
273-
...configShipper,
274-
ContactID: contactID
275-
}
276-
} else {
271+
if (!shipper && !configShipper) {
272+
throw new RuntimeErrorException("MISSING_SHIPPER_INFORMATION", "No shipper information provided in shipment data or configuration.")
273+
}
274+
275+
if (shipper) {
277276
return {
278277
...shipper,
279278
ContactID: contactID
280279
}
281280
}
281+
282+
return {
283+
...configShipper,
284+
ContactID: contactID
285+
}
282286
}
283287

284288
export async function postShipmentHelper(context: HerculesFunctionContext, services: ShipmentService, shipment: ShipmentWithoutServices, printingOptions: PrintingOptions, customContent?: CustomContent, returnOptions?: ReturnOptions): Promise<CreateParcelsResponse> {

actions/gls-action/src/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ export const ShipmentSchema = z.object({
309309
Product: z.enum(["PARCEL", "EXPRESS"]),
310310
ExpressAltDeliveryAllowed: z.boolean().optional(),
311311
Consignee: ConsigneeSchema,
312-
Shipper: ShipperSchema,
312+
Shipper: ShipperSchema.optional(),
313313
Carrier: z.enum(["ROYALMAIL"]).optional(),
314314
ShipmentUnit: ShipmentUnitSchema,
315315
Service: ShipmentServiceSchema,

docs/Actions/GLS/configs.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,4 @@ The value must be a valid `GLS_SHIPPER` object:
107107
}
108108
```
109109

110-
See [Types — GLS_SHIPPER](./types#GLS_SHIPPER) for the full field reference.
110+
See [Types — GLS_SHIPPER](../types/#GLS_SHIPPER) for the full field reference.

docs/Actions/GLS/events.md

Lines changed: 1 addition & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -9,166 +9,10 @@ In the Hercules platform, **events** are notifications emitted **by an action**
99

1010
---
1111

12-
## How events work
13-
14-
```
15-
External world (e.g. GLS webhook / polling)
16-
17-
│ something happens (parcel delivered, shipment arrived, ...)
18-
19-
GLS Action
20-
21-
│ sdk.dispatchEvent(eventType, projectId, payload)
22-
23-
Aquila
24-
25-
│ routes event to all flows listening for eventType
26-
27-
Your Flow starts
28-
29-
│ event payload available as flow input
30-
31-
Flow nodes execute (functions, conditions, etc.)
32-
```
33-
34-
An event carries a **payload** — the data associated with what happened (e.g. shipment details, tracking ID, status). Flows that subscribe to an event type receive this payload as their starting input.
35-
36-
---
37-
3812
## Current status
3913

4014
> **The GLS Action does not currently emit any events.**
4115
>
4216
> The GLS action presently only exposes **functions** (called by flows) and registers **data types** and **configuration**. Event support — where the action proactively notifies Aquila of changes — is **planned for a future release**.
4317
44-
---
45-
46-
## Planned events
47-
48-
The following events are candidates for future implementation. Once added, each will allow you to build flows that react automatically to GLS shipment lifecycle changes.
49-
50-
### `gls.shipment.arrived`
51-
52-
Emitted when a parcel arrives at a GLS depot or is scanned into the GLS network.
53-
54-
**Trigger mechanism:** The action would periodically poll the GLS tracking API (or receive a GLS webhook) and emit this event for each new scan.
55-
56-
**Payload type (planned):** `GLS_TRACKING_EVENT`
57-
58-
```
59-
GLS Action (polling / webhook listener)
60-
61-
│ detects new scan for tracked parcel
62-
63-
sdk.dispatchEvent("gls.shipment.arrived", projectId, {
64-
TrackID: "12345678",
65-
Status: "IN_TRANSIT",
66-
Location: "MUC-HUB",
67-
Timestamp: "2025-06-01T10:30:00Z"
68-
})
69-
70-
71-
Aquila → triggers all flows subscribed to "gls.shipment.arrived"
72-
```
73-
74-
---
75-
76-
### `gls.shipment.delivered`
77-
78-
Emitted when a parcel is confirmed delivered to the recipient.
79-
80-
**Payload type (planned):** `GLS_TRACKING_EVENT`
81-
82-
```
83-
sdk.dispatchEvent("gls.shipment.delivered", projectId, {
84-
TrackID: "12345678",
85-
Status: "DELIVERED",
86-
DeliveredAt: "2025-06-02T14:15:00Z",
87-
SignedBy: "J. Doe"
88-
})
89-
```
90-
91-
---
92-
93-
### `gls.shipment.failed`
94-
95-
Emitted when a delivery attempt fails (e.g. recipient not home, address problem).
96-
97-
**Payload type (planned):** `GLS_TRACKING_EVENT`
98-
99-
```
100-
sdk.dispatchEvent("gls.shipment.failed", projectId, {
101-
TrackID: "12345678",
102-
Status: "DELIVERY_FAILED",
103-
Reason: "RECIPIENT_NOT_HOME",
104-
NextAttempt: "2025-06-03"
105-
})
106-
```
107-
108-
---
109-
110-
### `gls.shipment.returned`
111-
112-
Emitted when a parcel is returned to sender after failed delivery attempts.
113-
114-
---
115-
116-
## How events are implemented (SDK reference)
117-
118-
When events are added to the GLS Action, they will follow this pattern from the Hercules SDK:
119-
120-
### 1. Register the flow type (event definition)
121-
122-
```typescript
123-
sdk.registerFlowTypes({
124-
identifier: "gls.shipment.arrived",
125-
editable: false,
126-
inputType: "GLS_TRACKING_EVENT",
127-
linkedDataTypes: ["GLS_TRACKING_EVENT"],
128-
name: [{ code: "en-US", content: "GLS Shipment Arrived" }],
129-
description: [{
130-
code: "en-US",
131-
content: "Triggered when a GLS parcel arrives at a depot or is scanned."
132-
}]
133-
})
134-
```
135-
136-
### 2. Dispatch the event when it occurs
137-
138-
```typescript
139-
sdk.dispatchEvent(
140-
"gls.shipment.arrived", // must match registered flow type identifier
141-
projectId, // which project to notify
142-
payload // data payload (must match inputType)
143-
)
144-
```
145-
146-
### 3. User builds a flow triggered by the event
147-
148-
In the Hercules UI, users create a flow with **"GLS Shipment Arrived"** as the trigger. When the GLS action dispatches this event, Aquila starts the flow and provides the payload (e.g. `TrackID`, `Status`, `Location`) as the flow's input.
149-
150-
---
151-
152-
## Flow type settings
153-
154-
Flow types can expose **settings** that allow users to configure how an event filters or behaves. For example, a future `gls.shipment.arrived` event might let users specify:
155-
156-
| Setting | Type | Description |
157-
|---------|------|-------------|
158-
| `trackId` | string | Only trigger for a specific parcel |
159-
| `statusFilter` | string[] | Only trigger for specific status codes |
160-
161-
Settings are defined in the `settings` array of `HerculesFlowType` and are configurable per-flow in the Hercules UI.
162-
163-
---
164-
165-
## Difference between events and functions
166-
167-
| | Events | Functions |
168-
|-|--------|-----------|
169-
| **Direction** | Action → Aquila | Flow → Action |
170-
| **Who initiates** | The action (proactively) | The flow (on demand) |
171-
| **Purpose** | React to something that happened externally | Perform an operation and return a result |
172-
| **SDK method** | `registerFlowTypes` + `dispatchEvent` | `registerFunctionDefinitions` |
173-
| **Example** | Parcel delivered → trigger notification flow | Create a shipment and return the label |
174-
| **Current GLS status** | ❌ Not yet implemented | ✅ 26 functions available |
18+
---

docs/Actions/GLS/functions.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ createAddress(
5656
| `MobilePhonenumber` | string (min 4, max 35) | No | Mobile phone number |
5757
| `eMail` | string (max 80) | No | Email address |
5858

59-
**Returns:** [`GLS_ADDRESS`](./types#GLS_ADDRESS)
59+
**Returns:** [`GLS_ADDRESS`](../types#GLS_ADDRESS)
6060

6161
---
6262

@@ -83,7 +83,7 @@ createConsignee(
8383
| `Address` | GLS_ADDRESS | **Yes** | The delivery address for this consignee |
8484
| `Category` | `"BUSINESS"` \| `"PRIVATE"` | **Yes** | Whether the consignee is a business or private recipient |
8585

86-
**Returns:** [`GLS_CONSIGNEE`](./types#GLS_CONSIGNEE)
86+
**Returns:** [`GLS_CONSIGNEE`](../types#GLS_CONSIGNEE)
8787

8888
---
8989

@@ -114,7 +114,7 @@ createShipmentUnit(
114114
| `note2` | string (max 50) | No | Additional note printed on the label (line 2) |
115115
| `shipmentUnitService` | GLS_UNIT_SERVICE | No | Unit-level services (Cash, AddonLiability, HazardousGoods, etc.) |
116116

117-
**Returns:** [`GLS_SHIPMENT_UNIT`](./types#GLS_SHIPMENT_UNIT)
117+
**Returns:** [`GLS_SHIPMENT_UNIT`](../types#GLS_SHIPMENT_UNIT)
118118

119119
---
120120

@@ -140,7 +140,7 @@ createPrintingOptions(returnLabels: RETURN_LABELS): GLS_PRINTING_OPTIONS
140140
| `TemplateSet` | `NONE`, `D_200`, `PF_4_I`, `ZPL_200`, `ZPL_300`, ... | Label template set |
141141
| `LabelFormat` | `PDF`, `ZEBRA`, `INTERMEC`, `DATAMAX`, `TOSHIBA`, `PNG` | Output format |
142142

143-
**Returns:** [`GLS_PRINTING_OPTIONS`](./types#GLS_PRINTING_OPTIONS)
143+
**Returns:** [`GLS_PRINTING_OPTIONS`](../types#GLS_PRINTING_OPTIONS)
144144

145145
---
146146

@@ -169,7 +169,7 @@ createCustomContent(
169169
| `barcodeType` | `"EAN_128"` \| `"CODE_39"` | No | Barcode symbology |
170170
| `barcode` | string | No | Custom barcode value |
171171

172-
**Returns:** [`GLS_CUSTOM_CONTENT`](./types#GLS_CUSTOM_CONTENT)
172+
**Returns:** [`GLS_CUSTOM_CONTENT`](../types#GLS_CUSTOM_CONTENT)
173173

174174
---
175175

@@ -536,7 +536,7 @@ validateShipment
536536
└── validationResult.Issues[]
537537
```
538538

539-
See [Types — GLS_VALIDATE_SHIPMENT_REQUEST_DATA](./types#GLS_VALIDATE_SHIPMENT_REQUEST_DATA) for the input format.
539+
See [Types — GLS_VALIDATE_SHIPMENT_REQUEST_DATA](../types#GLS_VALIDATE_SHIPMENT_REQUEST_DATA) for the input format.
540540

541541
---
542542

docs/Actions/GLS/overview.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ description: Overview of the GLS ShipIT action — what it does, what you need t
55

66
# GLS Action
77

8-
The **GLS Action** integrates the [GLS ShipIT API](https://api.gls-group.net) into the Hercules automation platform. It lets you create, validate, cancel, and manage GLS parcel shipments directly from your flows — no manual API calls required.
8+
The **GLS Action** integrates the [GLS ShipIT API](https://dev-portal.gls-group.net/docs/shipit-farm/1/overview) as an action. It lets you create, validate, cancel, and manage GLS parcel shipments directly from your flows — no manual API calls required.
99

1010
---
1111

@@ -49,7 +49,7 @@ Before using the GLS Action you will need:
4949
## Architecture overview
5050

5151
```
52-
Your Flow (Hercules)
52+
Your Flow
5353
5454
5555
GLS Action (this action)
@@ -87,10 +87,10 @@ GLS_CREATE_PARCELS_RESPONSE ← tracking IDs, barcode data, print data, routing
8787

8888
## Next steps
8989

90-
- [Quick Start](./quick-start) — Create your first shipment in a few steps
91-
- [Configuration](./configs) — Full list of configuration options and how to get credentials
92-
- [Functions](./functions) — All available functions with parameter details
93-
- [Types](./types) — All data types used in the GLS Action
94-
- [Events](./events) — Events emitted by the GLS Action
95-
- [Common Use Cases](./use-cases) — Example flows for real-world scenarios
96-
- [Troubleshooting](./troubleshooting) — FAQ and community support
90+
- [Quick Start](../quick-start) — Create your first shipment in a few steps
91+
- [Configuration](../configs) — Full list of configuration options and how to get credentials
92+
- [Functions](../functions) — All available functions with parameter details
93+
- [Types](../types) — All data types used in the GLS Action
94+
- [Events](../events) — Events emitted by the GLS Action
95+
- [Common Use Cases](../use-cases) — Example flows for real-world scenarios
96+
- [Troubleshooting](../troubleshooting) — FAQ and community support

docs/Actions/GLS/troubleshooting.md

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ A: The action supports all major GLS shipment types and services, including:
3030
- Tyre service, addressee-only delivery
3131
- Saturday and next-working-day delivery (EXPRESS only)
3232

33-
See [Functions](./functions) for the complete list.
33+
See [Functions](../functions.md) for the complete list.
3434

3535
---
3636

@@ -63,29 +63,8 @@ A: Check the following:
6363

6464
---
6565

66-
**Q: I get "Failed to register config definitions" on startup. What does that mean?**
67-
68-
A: This means the action could not register its configuration schema with the Aquila server. Check:
69-
- The Aquila server is running and healthy
70-
- The `HERCULES_AUTH_TOKEN` has sufficient permissions
71-
- The action ID (`HERCULES_ACTION_ID`) is not already registered with a conflicting schema
72-
73-
---
74-
75-
**Q: The action shows "SDK connected successfully" but my functions don't appear in Hercules.**
76-
77-
A: Wait a few seconds — registration can take a moment. Then refresh the Hercules UI. If functions still don't appear, check that the action's `HERCULES_ACTION_ID` matches what is configured in Hercules.
78-
79-
---
80-
8166
### Authentication & API errors
8267

83-
**Q: I get a 401 Unauthorized error when the action tries to call the GLS API.**
84-
85-
A: Your `client_id` or `client_secret` is incorrect, or your GLS application does not have the required API scopes. Verify your credentials on the [GLS Developer Portal](https://dev-portal.gls-group.net) and ensure the **ShipIT** scope is enabled.
86-
87-
---
88-
8968
**Q: I get an `INVALID_PRODUCT` error when creating a Saturday delivery shipment.**
9069

9170
A: Saturday delivery (and next-working-day delivery) requires the shipment's `Product` to be set to `"EXPRESS"`. Change `Product: "PARCEL"` to `Product: "EXPRESS"` in your shipment data.
@@ -104,11 +83,6 @@ A: No. Once GLS has scanned the parcel at a depot or delivery vehicle, cancellat
10483

10584
---
10685

107-
**Q: My token expires frequently. Can I adjust the refresh interval?**
108-
109-
A: The action automatically refreshes tokens 60 seconds before they expire. This is hard-coded and cannot be changed through configuration. GLS OAuth2 tokens typically have a validity of 1 hour.
110-
111-
---
11286

11387
### Labels & printing
11488

@@ -212,9 +186,3 @@ Open a pull request against the `main` branch of [code0-tech/centaurus](https://
212186
| `npm run lint` | Run ESLint |
213187
| `npm run create-action -- <name>` | Scaffold a new action |
214188

215-
### Code conventions
216-
217-
- All types must use **Zod schemas** with a matching `Schema` suffix (e.g. `AddressSchema` / `Address`)
218-
- All registered types must have identifiers starting with `GLS_` (for the GLS action)
219-
- All function definitions must include `name` and `description` in `en-US`
220-
- Functions that call external APIs must wrap errors in `RuntimeErrorException`

0 commit comments

Comments
 (0)