| name | guidewire-webhooks-events |
| description | Implement Guidewire App Events and webhook integrations for event-driven architecture.
Use when setting up outbound events, message queuing, webhook receivers,
or asynchronous integration patterns.
Trigger with phrases like "guidewire webhooks", "app events",
"event-driven", "message queue", "guidewire notifications".
|
| allowed-tools | Read, Write, Edit, Bash(curl:*), Bash(npm:*), Grep |
| version | 1.0.0 |
| license | MIT |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
Guidewire Webhooks & Events
Overview
Implement event-driven integrations using Guidewire App Events, webhooks, and message queuing for real-time notifications and asynchronous processing.
Prerequisites
- Guidewire Cloud Console access
- Understanding of event-driven architecture
- HTTPS endpoint for webhook receiver
- Message queue service (optional)
App Events Architecture
+------------------+ +------------------+ +------------------+
| | | | | |
| InsuranceSuite |----->| App Events |----->| Your System |
| (PC/CC/BC) | | Service | | (Webhook/Queue) |
| | | | | |
+------------------+ +------------------+ +------------------+
| | |
v v v
Business Event Kafka Topic Event Handler
(Policy Issued) (Buffered) (Process Event)
Instructions
Step 1: Configure App Events in Cloud Console
events:
- name: policy.issued
description: Triggered when a policy is issued
application: PolicyCenter
entity: Policy
payload:
include:
- policyNumber
- effectiveDate
- expirationDate
- totalPremium
- accountNumber
- insuredName
delivery:
type: webhook
endpoint: https://your-api.com/webhooks/guidewire
retryPolicy:
maxAttempts: 5
backoffMultiplier: 2
initialDelaySeconds: 10
- name: claim.created
description: Triggered when a new claim is filed
Step 2: Webhook Receiver Implementation
import express from 'express';
import crypto from 'crypto';
import { Redis } from 'ioredis';
const app = express();
const redis = new Redis(process.env.REDIS_URL);
app.post('/webhooks/guidewire',
express.raw({ type: 'application/json' }),
async (req, res) => {
const signature = req.headers['x-gw-signature'] as string;
const timestamp = req.headers['x-gw-timestamp'] as string;
const eventId = req.headers['x-gw-event-id'] as string;
if (!verifySignature(req.body, signature, timestamp)) {
console.error('Invalid signature');
return res.status(401).({ : });
}
(! (timestamp)) {
res.().({ : });
}
( (eventId)) {
.();
res.().({ : });
}
{
event = .(req..());
(event);
(eventId);
res.().({ : });
} (error) {
.(, error);
res.().({ : });
}
}
);
(): {
secret = process..!;
timestampAge = .() - (timestamp) * ;
(timestampAge > ) {
;
}
signedPayload = ;
expectedSignature = crypto
.(, secret)
.(signedPayload)
.();
crypto.(
.(signature),
.()
);
}
(): <> {
key = ;
( redis.(key)) === ;
}
(): <> {
key = ;
redis.(key, , , * );
}
Step 3: Event Handler Implementation
interface GuidewireEvent {
id: string;
type: string;
timestamp: string;
application: 'PolicyCenter' | 'ClaimCenter' | 'BillingCenter';
data: Record<string, any>;
}
interface PolicyIssuedEvent extends GuidewireEvent {
type: 'policy.issued';
data: {
policyNumber: string;
effectiveDate: string;
expirationDate: string;
totalPremium: { amount: number; currency: string };
accountNumber: string;
insuredName: string;
};
}
interface ClaimCreatedEvent extends GuidewireEvent {
type: 'claim.created';
data: {
claimNumber: string;
lossDate: string;
lossType: string;
policyNumber: ;
: ;
};
}
<T > = <>;
: <, <>> = {
: (: ) => {
.();
crmClient.({
: event..,
: event..,
: event...
});
emailService.({
: event..,
: event..,
: event..
});
analyticsService.(event.);
},
: (: ) => {
.();
notificationService.({
: event..,
: event..,
: event..
});
taskService.({
: ,
: event..,
: (event.)
});
}
};
(): <> {
handler = eventHandlers[event.];
(!handler) {
.();
;
}
(event);
.();
}
Step 4: Gosu Event Publisher
// Publishing custom events from Gosu
package gw.events
uses gw.api.messaging.MessageTransport
uses gw.api.util.Logger
uses gw.pl.persistence.core.Bundle
class CustomEventPublisher {
private static final var LOG = Logger.forCategory("CustomEventPublisher")
// Publish event when policy state changes
static function publishPolicyEvent(policy : Policy, eventType : String) {
var event = buildPolicyEvent(policy, eventType)
publishEvent(event)
}
// Publish event when claim status changes
static function publishClaimEvent(claim : Claim, eventType : String) {
var event = buildClaimEvent(claim, eventType)
publishEvent(event)
}
private static function buildPolicyEvent(policy : Policy, eventType : String) : Map<String, Object> {
return {
"eventType" -> eventType,
"timestamp" -> Date.Now.toString(),
"application" -> "PolicyCenter",
"data" -> {
"policyNumber" -> policy.PolicyNumber,
"accountNumber" -> policy.Account.AccountNumber,
"effectiveDate" -> policy.EffectiveDate.toString(),
"expirationDate" -> policy.ExpirationDate.toString(),
"status" -> policy.Status.Code,
"totalPremium" -> {
"amount" -> policy.TotalPremiumRPT.Amount,
"currency" -> policy.TotalPremiumRPT.Currency.Code
}
}
}
}
private static function buildClaimEvent(claim : Claim, eventType : String) : Map<String, Object> {
return {
"eventType" -> eventType,
"timestamp" -> Date.Now.toString(),
"application" -> "ClaimCenter",
"data" -> {
"claimNumber" -> claim.ClaimNumber,
"policyNumber" -> claim.Policy.PolicyNumber,
"lossDate" -> claim.LossDate.toString(),
"lossType" -> claim.LossType.Code,
"status" -> claim.State.Code
}
}
}
private static function publishEvent(event : Map<String, Object>) {
try {
// Publish to message destination
var transport = MessageTransport.getInstance()
var message = new gw.api.messaging.Message()
message.Destination = "ExternalEventDestination"
message.Body = gw.api.json.JsonObject.toJson(event)
transport.send(message)
LOG.info("Published event: ${event.get('eventType')}")
} catch (e : Exception) {
LOG.error("Failed to publish event", e)
throw e
}
}
}
Step 5: Integration Gateway Route
route:
name: claim-processor
description: Process incoming claim events
from:
type: app-events
event: claim.created
steps:
- transform:
type: gosu
class: gw.integration.transform.ClaimEventTransformer
- filter:
condition: ${body.data.lossType != 'test'}
- choice:
when:
- condition: ${body.data.totalLoss == true}
to:
type: http
url: https://external-system.com/total-loss
method: POST
- condition: ${body.data.subrogation == true}
to:
type: http
Step 6: Event Monitoring
interface EventMetrics {
totalReceived: number;
totalProcessed: number;
totalFailed: number;
processingTimeMs: number[];
eventsByType: Record<string, number>;
failuresByType: Record<string, number>;
}
class EventMonitor {
private metrics: EventMetrics = {
totalReceived: 0,
totalProcessed: 0,
totalFailed: 0,
processingTimeMs: [],
eventsByType: {},
failuresByType: {}
};
recordEvent(eventType: string, success: boolean, durationMs: number): void {
this.metrics.totalReceived++;
this.metrics.eventsByType[eventType] = (this.metrics.eventsByType[eventType] || 0) + 1;
(success) {
..++;
...(durationMs);
} {
..++;
..[eventType] = (..[eventType] || ) + ;
}
}
(): & { : ; : } {
avgProcessingTimeMs = ... >
? ...( a + b, ) / ...
: ;
successRate = .. >
? .. / ..
: ;
{
....,
avgProcessingTimeMs,
successRate
};
}
(): {
.();
}
}
Event Types Reference
| Application | Event Type | Trigger |
|---|
| PolicyCenter | policy.created | New policy bound |
| PolicyCenter | policy.issued | Policy issued |
| PolicyCenter | policy.cancelled | Policy cancelled |
| PolicyCenter | policy.renewed | Policy renewed |
| PolicyCenter | submission.quoted | Quote generated |
| ClaimCenter | claim.created | FNOL submitted |
| ClaimCenter | claim.closed | Claim closed |
| ClaimCenter | payment.issued | Payment created |
| BillingCenter | invoice.created | Invoice generated |
| BillingCenter | payment.received | Payment received |
Output
- App Events configuration
- Webhook receiver with signature validation
- Type-safe event handlers
- Gosu event publisher
- Integration Gateway routes
- Event monitoring
Error Handling
| Error | Cause | Solution |
|---|
| Invalid signature | Wrong secret | Verify webhook secret |
| Event timeout | Slow processing | Use async queue |
| Duplicate events | Missing idempotency | Track processed event IDs |
| Delivery failure | Endpoint down | Check webhook endpoint |
Resources
Next Steps
For performance optimization, see guidewire-performance-tuning.