Channel Source

Receive messages from another intu channel, enabling multi-stage pipelines through channel chaining.

Overview

The Channel source subscribes to the output of another intu channel within the same project. When the upstream channel finishes processing a message and sends it to its destinations, a copy is also delivered to any downstream channels that reference it via the Channel source.

Channel chaining is useful for building multi-stage processing pipelines where each stage performs a distinct operation. For example, a first channel might normalize incoming HL7v2 messages into a canonical JSON format, and a second channel might transform that canonical format into FHIR resources for a specific destination.

Note The upstream channel must exist in the same intu project. The source_channel_id must match the id field in the upstream channel's channel.yaml.

Configuration

yaml
listener:
  type: channel
  channel:
    source_channel_id: adt-inbound

Properties

source_channel_id string required
The id of the upstream channel to receive messages from. Must reference a valid channel within the same intu project.

Complete Example

A two-channel pipeline where the first channel (adt-inbound) receives raw HL7 ADT messages and normalizes them, and the second channel (adt-to-fhir) transforms the normalized output into FHIR resources.

Upstream Channel: adt-inbound

yaml
id: adt-inbound
enabled: true

listener:
  type: tcp
  tcp:
    port: 2575
    mode: mllp

validator:
  runtime: node
  entrypoint: validator.ts

transformer:
  runtime: node
  entrypoint: normalizer.ts

destinations:
  - audit-log

Downstream Channel: adt-to-fhir

yaml
id: adt-to-fhir
enabled: true

listener:
  type: channel
  channel:
    source_channel_id: adt-inbound

validator:
  runtime: node
  entrypoint: validator.ts

transformer:
  runtime: node
  entrypoint: transformer.ts

destinations:
  - fhir-server

TypeScript Transformer Example

This transformer receives the normalized JSON output from the upstream channel and maps it to a FHIR Patient resource with extended demographics.

typescript
import { Message, TransformResult } from "@intu/sdk";

interface NormalizedPatient {
  mrn: string;
  familyName: string;
  givenName: string;
  middleName?: string;
  dateOfBirth: string;
  gender: string;
  ssn?: string;
  address: {
    line1: string;
    line2?: string;
    city: string;
    state: string;
    postalCode: string;
    country: string;
  };
  phone?: string;
  email?: string;
  language?: string;
  maritalStatus?: string;
}

export default function transform(msg: Message): TransformResult {
  let patient: NormalizedPatient;
  try {
    patient = JSON.parse(msg.body as string);
  } catch {
    return { success: false, error: "Invalid JSON from upstream channel" };
  }

  const fhirPatient = {
    resourceType: "Patient",
    identifier: [
      {
        type: {
          coding: [{ system: "http://terminology.hl7.org/CodeSystem/v2-0203", code: "MR" }],
        },
        system: "urn:oid:2.16.840.1.113883.19.5",
        value: patient.mrn,
      },
    ],
    name: [
      {
        use: "official",
        family: patient.familyName,
        given: [patient.givenName, patient.middleName].filter(Boolean),
      },
    ],
    gender: mapGender(patient.gender),
    birthDate: patient.dateOfBirth,
    address: [
      {
        use: "home",
        line: [patient.address.line1, patient.address.line2].filter(Boolean),
        city: patient.address.city,
        state: patient.address.state,
        postalCode: patient.address.postalCode,
        country: patient.address.country,
      },
    ],
    telecom: buildTelecom(patient.phone, patient.email),
    communication: patient.language
      ? [{ language: { text: patient.language }, preferred: true }]
      : undefined,
    maritalStatus: patient.maritalStatus
      ? {
          coding: [
            {
              system: "http://terminology.hl7.org/CodeSystem/v3-MaritalStatus",
              code: patient.maritalStatus,
            },
          ],
        }
      : undefined,
  };

  return {
    success: true,
    body: JSON.stringify(fhirPatient),
    contentType: "application/fhir+json",
  };
}

function mapGender(code: string): string {
  const map: Record<string, string> = { M: "male", F: "female", O: "other", U: "unknown" };
  return map[code] || "unknown";
}

function buildTelecom(phone?: string, email?: string) {
  const telecom: { system: string; value: string; use: string }[] = [];
  if (phone) telecom.push({ system: "phone", value: phone, use: "home" });
  if (email) telecom.push({ system: "email", value: email, use: "home" });
  return telecom.length > 0 ? telecom : undefined;
}