Skip to content

Architecture and Integrations

Architecture

Architectural concept

The system is built on an event-driven model.

The static frontend is served via S3/CloudFront. The user authenticates through Cognito Hosted UI and calls API Gateway using the obtained JWT. API Gateway routes requests to Lambda functions.

Large audio files do not pass through API Gateway and Lambda. The backend issues a presigned POST URL, after which the browser uploads the file directly to S3. An S3 ObjectCreated event triggers a handler that creates a temporary URL for the transcription provider and submits a new transcription request. The external provider performs long transcription asynchronously and returns the result via webhook. The final text transcript is saved to S3, and the job status is updated and stored in DynamoDB.

architecture-beta
    service dynamo(aws:dynamodb)[AWS DynamoDB]
    service lambda(aws:lambda)[AWS Lambda] 
    service api(aws:api-gateway)[AWS API Gateway]
    service static(aws:simple-storage-service)[Static website at Amazon S3]
    service storage(aws:simple-storage-service)[File storage at Amazon S3]
    service browser(logos:chrome)[Browser]
    service cognito(aws:cognito)[AWS Cognito]
    service ai(logos:webhooks)[Transcriber API]
    service front(aws:cloudfront)[AWS CloudFront]

    front:T --> B:static
    browser:T --> B:api
    browser:L --> R:front
    browser:B --> T:cognito

    api:R --> L:lambda
    api:T <-- B:ai
    lambda:T --> R:ai
    lambda:R --> L:dynamo
    lambda:B --> T:storage
    storage:L <-- R:browser

Integration flows

Sequence diagrams

Audio file submission

sequenceDiagram
    autonumber

    actor U as Browser (SPA)
    participant API as API Gateway
    participant L as AWS Lambda
    participant S3 as Amazon S3
    participant DB as DynamoDB

    U->>API: GET /upload-url (+JWT in Header)
    activate API
    API->>L: Invoke get_upload_url
    deactivate API
    activate L
    L->>DB: Create record (Status: UPLOADING)
    L->>S3: Generate Presigned POST URL
    activate S3
    S3-->>L: Upload link
    deactivate S3
    L-->>U: JSON: { uploadUrl, fileId }
    deactivate L

Direct upload and asynchronous trigger (event-driven)

sequenceDiagram
    autonumber

    actor U as Browser (SPA)
    participant L as AWS Lambda
    participant S3 as Amazon S3
    participant DB as DynamoDB
    participant AI as TranscribeProvider

    U->>S3: POST Upload audio file (Bypass API Gateway)
    activate S3
    S3-->>U: 204 No Content (Success)
    deactivate S3

    S3-)L: Event: ObjectCreated (Async invoke s3_trigger)
    activate L
    L->>DB: Update status (TRANSMITTING)
    L->>S3: Generate temporary GET Presigned URL for AI
    L->>AI: POST /v2/transcript (Audio URL + Webhook URL)
    activate AI
    alt TranscribeProvider accepts request
        AI-->>L: 201 Created (transcript_id)
        L->>DB: Status = PROCESSING (save ID)
    else API error (e.g. HTTP 400/500)
        AI-->>L: 4xx / 5xx Error
        deactivate AI
        L->>DB: Status = ERROR (Log reason)
    end
    deactivate L

AI processing and webhook (up to several minutes)

sequenceDiagram
    autonumber

    actor U as Browser (SPA)
    participant API as API Gateway
    participant L as AWS Lambda
    participant S3 as Amazon S3
    participant DB as DynamoDB
    participant AI as TranscribeProvider

    loop Every 15 seconds (Polling)
        U->>API: GET /jobs
        activate API 
        API->>L: Invoke get_jobs
        deactivate API
        activate L
        L->>DB: Request user's file list
        activate DB
        DB-->>L: Data (Status: PROCESSING)
        deactivate DB
        L-->>U: Update UI
        deactivate L
    end

    Note over AI, DB: TranscribeProvider completes processing
    AI->>API: POST /webhook (pass transcript_id)
    activate API
    API->>L: Invoke webhook_TranscribeProvider
    deactivate API
    activate L
    L->>AI: GET /v2/transcript/{id}
    activate AI
    AI-->>L: Completed transcription text
    deactivate AI
    L->>S3: PUT Save text (Transcript.txt)
    L->>DB: Update status (READY)
    deactivate L

Result retrieval (download)

sequenceDiagram
    autonumber

    actor U as Browser (SPA)
    participant API as API Gateway
    participant L as AWS Lambda
    participant S3 as Amazon S3
    participant DB as DynamoDB

    U->>API: GET /jobs (Next polling interval)
    activate API
    API-->>U: Status: READY (Download button active)
    deactivate API

    U->>API: GET /download-url?fileId=...
    activate API
    API->>L: Invoke get_download_url
    deactivate API
    activate L
    L->>DB: Verify user access rights to file
    L->>S3: Generate Presigned GET URL (with Content-Disposition)
    L-->>U: JSON: { downloadUrl }
    deactivate L
    U->>S3: Direct download of Transcript.txt
    activate S3
    S3-->>U: Transcription file
    deactivate S3