AbsoluteJS

@absolutejs/voice-google-speech

@absolutejs/voice-google-speechv0.0.1-beta.6betaVoice & Media

Google Cloud Speech-to-Text adapter for @absolutejs/voice — buffered-batch (REST) + real-time streaming (gRPC-Web over HTTP/2, no @grpc/grpc-js dep)

#Installation

BASH
bun add @absolutejs/voice-google-speech

#Capabilities

Overview

Google Cloud Speech-to-Text adapter for @absolutejs/voice. Ships two complementary modes — pick whichever fits your latency / cost / infrastructure tradeoffs:

googleSpeech(...) — buffered-batch via REST /v1/speech:recognize. Accumulate PCM, POST on flush() / close(), get one final transcript per turn. Good for post-call analysis and short utterances; simplest auth (API key, OAuth, or refresh hook).

googleSpeechStream(...) — real-time bidirectional streaming via Google Speech v2 StreamingRecognize. Speaks gRPC over HTTP/2 directly (node:http2) with hand-rolled protobuf wire-format for the request/response messages and gRPC-Web framing. No @grpc/grpc-js dependency. Use this when you want partial transcripts as the caller is speaking.

Streaming (googleSpeechStream)

OAuth refresh (preferred for long-running deployments):

What this adapter does protocol-wise

Opens a single HTTP/2 stream against https://speech.googleapis.com/google.cloud.speech.v2.Speech/StreamingRecognize.

Show 10 more

Headers: Authorization: Bearer , Content-Type: application/grpc-web+proto, X-Grpc-Web: 1, TE: trailers.

Sends the first message as a StreamingRecognizeRequest carrying recognizer = projects/{project}/locations/{location}/recognizers/_ and a streaming_config derived from STTAdapterOpenOptions.format + your options.

Each call to session.send(audio) encodes a StreamingRecognizeRequest { audio = }, wraps it in a 5-byte gRPC frame, and writes it to the HTTP/2 stream.

Reads StreamingRecognizeResponse frames as they arrive, decodes results[].alternatives[0], and emits partial events while is_final = false, final events when is_final = true. result_end_offset is lifted to transcript.endedAtMs, language_code to transcript.language, confidence to transcript.confidence.

speech_event_type values of END_OF_SINGLE_UTTERANCE or SPEECH_ACTIVITY_END emit an endOfTurn (reason: "vendor").

Trailer frame (gRPC-Web high-bit flag) or HTTP/2 trailer with non-zero grpc-status emits an error event with code = and message "Google Speech gRPC status : ".

Streaming options

Option — Required — Default — Notes

accessToken / getAccessToken — one of — — — OAuth Bearer token (or async refresh hook). API keys are not supported on the streaming RPC; use the buffered-batch googleSpeech(...) for API-key flows.

project — yes — — — Google Cloud project id; combined with location to form the recognizer resource path.

Buffered-batch (googleSpeech)

See the existing buffered-batch section for the REST-based API key / OAuth flow. The streaming and batch exports can coexist in the same project; pick per-route.

Notes & limitations

Bun's fetch is half-duplex (request body must finish before the response body starts), which is why the streaming adapter uses node:http2 directly instead of fetch. Bun's node:http2 polyfill supports the bidirectional pattern this adapter needs.

The protobuf encoder/decoder is hand-rolled and covers only the fields actually used by StreamingRecognizeRequest/StreamingRecognizeResponse. If Google adds new fields you want surfaced (alternatives beyond [0], word-level timing, channel tags, etc.), open an issue.

For STTAdapterOpenOptions.format.encoding: pcm_s16le → LINEAR16, mulaw / pcm_mulaw → MULAW, alaw / pcm_alaw → ALAW. Other encodings are rejected at open time.

Show 1 more

session.close(reason) ends the request stream cleanly and emits close. Any in-flight transcripts that arrive after close are dropped.

Outcomes

What you can build

Build on the supported package contract

Use @absolutejs/voice-google-speech through its supported public entry points.

Hardening checklist

Production guidance

Make every external boundary explicitPin the deployed @absolutejs/voice-google-speech version, replace example or memory-backed dependencies with durable implementations, bound external calls, protect credentials, and emit enough evidence to retry or recover safely.

Follow in order

Troubleshooting path

1
Trace from the first failed boundary
Reproduce the smallest canonical @absolutejs/voice-google-speech example, confirm the supported entry point and version in the API explorer, then inspect the first boundary that did not produce its documented result.

#Streaming (googleSpeechStream)

Partial snippet

Working example for Streaming (googleSpeechStream).

TS
import { voice } from "@absolutejs/voice";
import { googleSpeechStream } from "@absolutejs/voice-google-speech";

const app = voice({
  stt: googleSpeechStream({
    project: process.env.GOOGLE_PROJECT_ID!,
    accessToken: await mintBearerToken(),
    // optional:
    location: "global", // default
    model: "latest_long", // default; or 'latest_short' / 'chirp_2' / 'telephony' / ...
    language: "en-US",
    languages: ["en-US"], // used unless languageStrategy overrides
    interimResults: true, // default — partial transcripts emitted
    enableVoiceActivityEvents: true, // surface SPEECH_ACTIVITY_END as endOfTurn
    enableAutomaticPunctuation: true,
    enableWordConfidence: true,
  }),
});

#Streaming (googleSpeechStream) 2

Partial snippet

OAuth refresh (preferred for long-running deployments):

TS
googleSpeechStream({
  project,
  getAccessToken: async () => await refreshGoogleAccessToken(),
});

#Public entry points

Supported entry points declared by this package manifest.

Package entry point declared in package.json.

@absolutejs/voice-google-speech@absolutejs/voice-google-speech/manifest@absolutejs/voice-google-speech/manifest.json

#Package commands

Scripts declared by this package manifest.

bun run buildrm -rf dist && bun build ./src/index.ts ./src/manifest.ts --outdir dist --target bun --external @absolutejs/manifest --external '@absolutejs/manifest/*' --external @absolutejs/voice --external '@absolutejs/voice/*' --external @sinclair/typebox --external '@sinclair/typebox/*' && tsc --emitDeclarationOnly --project tsconfig.json && absolute-manifest emit
bun run check:packagebun run format && bun run typecheck && bun run test && bun run verify-package && bun run build && bun run verify-package --artifacts
bun run formatprettier --write "./**/*.{js,ts,json,md}"
bun run testbun test
bun run typecheckbun run tsc --noEmit

#API reference

Search the declarations exported by the current package type files. Expand a symbol to inspect its source-backed signature.

11 symbols
googleSpeechexportPermalinkSource
TS
googleSpeech
Exported from @absolutejs/voice-google-speech