Portal Community

Callback Topic Architecture

Each interaction has a unique callback topic: interactions.callback.{interactionId}. When the server publishes a request, it simultaneously subscribes to this topic via EdgeStream. The subscription persists until one of these events occurs:

Server-Side Response Reception

1

EdgeStream Delivers the Response

The InteractionResponse arrives on interactions.callback.{interactionId}. The InteractionPipeline's EdgeStream subscription handler fires.

2

Respondent Validation

The pipeline verifies that respondedBy is a legitimate recipient of the original request (was the target user, or a member of the targeted role at publish time). Invalid respondents are rejected.

3

Response Validation Hook

The ResponseValidationHook checks that the outcome is valid for the interaction type and that the data matches the expected schema. Invalid responses return an error to the client.

4

Post-Receive Hooks Run

All registered IInteractionHook.OnAfterRespond() implementations run: audit logging, metrics emission, business-specific side effects.

5

TaskCompletionSource Resolves

The PublishAndWaitAsync() call's internal TaskCompletionSource<InteractionResponse> is resolved with the response. The awaiting server code resumes with the full response object.

Custom Callback Topics

In most cases, the default callback topic interactions.callback.{interactionId} is the right choice. Custom callback topics are useful when:

// Custom callback topic
const request: InteractionRequest = {
  type: 'approval',
  targetUserId: 'usr_abc',
  title: '...',
  payload: { ... },
  timeoutMs: 86_400_000,
  // Route response to a custom aggregator service
  callbackTopic: 'my-service/approval-responses'
};

Multi-Service Scenarios

If your server is distributed (multiple service instances), the InteractionPipeline handles response routing across instances using the EdgeStream broker:

Callback Topic Cleanup After the response (or timeout) is received, the callback topic subscription is automatically cleaned up. Do not leave callback topic subscriptions dangling — the pipeline handles this internally.