From 969217ea4dfaa0bcabecefc4370d8eeff430f870 Mon Sep 17 00:00:00 2001 From: Rares Popa Date: Mon, 27 Apr 2026 01:36:49 -0400 Subject: [PATCH 1/7] feat: refactor example app with new component library and implement native Android audio service --- README.md | 1275 +++++++++++++---- android/src/main/AndroidManifest.xml | 13 + .../java/com/deepgram/DeepgramAudioService.kt | 85 ++ .../main/java/com/deepgram/DeepgramModule.kt | 580 ++++++-- example/.env.example | 3 + example/android/.gitignore | 16 + example/android/app/build.gradle | 176 +++ example/android/app/debug.keystore | Bin 0 -> 2257 bytes example/android/app/proguard-rules.pro | 14 + .../android/app/src/debug/AndroidManifest.xml | 7 + .../android/app/src/main/AndroidManifest.xml | 35 + .../MainActivity.kt | 61 + .../MainApplication.kt | 57 + .../res/drawable-hdpi/splashscreen_logo.png | Bin 0 -> 20754 bytes .../res/drawable-mdpi/splashscreen_logo.png | Bin 0 -> 12863 bytes .../res/drawable-xhdpi/splashscreen_logo.png | Bin 0 -> 29081 bytes .../res/drawable-xxhdpi/splashscreen_logo.png | Bin 0 -> 47123 bytes .../drawable-xxxhdpi/splashscreen_logo.png | Bin 0 -> 66529 bytes .../res/drawable/ic_launcher_background.xml | 6 + .../res/drawable/rn_edit_text_material.xml | 37 + .../src/main/res/mipmap-hdpi/ic_launcher.webp | Bin 0 -> 3056 bytes .../res/mipmap-hdpi/ic_launcher_round.webp | Bin 0 -> 5024 bytes .../src/main/res/mipmap-mdpi/ic_launcher.webp | Bin 0 -> 2096 bytes .../res/mipmap-mdpi/ic_launcher_round.webp | Bin 0 -> 2858 bytes .../main/res/mipmap-xhdpi/ic_launcher.webp | Bin 0 -> 4569 bytes .../res/mipmap-xhdpi/ic_launcher_round.webp | Bin 0 -> 7098 bytes .../main/res/mipmap-xxhdpi/ic_launcher.webp | Bin 0 -> 6464 bytes .../res/mipmap-xxhdpi/ic_launcher_round.webp | Bin 0 -> 10676 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.webp | Bin 0 -> 9250 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.webp | Bin 0 -> 15523 bytes .../app/src/main/res/values-night/colors.xml | 1 + .../app/src/main/res/values/colors.xml | 5 + .../app/src/main/res/values/strings.xml | 3 + .../app/src/main/res/values/styles.xml | 17 + example/android/build.gradle | 41 + example/android/gradle.properties | 56 + .../android/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 43583 bytes .../gradle/wrapper/gradle-wrapper.properties | 7 + example/android/gradlew | 252 ++++ example/android/gradlew.bat | 94 ++ example/android/settings.gradle | 38 + example/app.json | 3 + example/ios/Podfile.lock | 4 +- .../project.pbxproj | 88 +- .../ios/ReactNativeDeepgramExample/Info.plist | 4 + example/metro.config.js | 46 +- example/package.json | 7 +- example/src/App.tsx | 194 ++- example/src/Management.tsx | 301 ++-- example/src/SpeechToText.tsx | 358 +++-- example/src/TextIntelligence.tsx | 354 ++++- example/src/TextToSpeech.tsx | 576 ++++---- example/src/VoiceAgent.tsx | 708 +++++---- example/src/components/Button.tsx | 140 ++ example/src/components/Card.tsx | 94 ++ example/src/components/Field.tsx | 79 + example/src/components/OptionSelect.tsx | 70 +- example/src/components/StatusBadge.tsx | 94 ++ example/src/theme.ts | 74 + ios/Deepgram.mm | 503 ++++++- ios/MicPermission.m | 23 + package.json | 32 +- plugin/build/index.d.ts | 3 +- plugin/build/index.js | 39 +- plugin/src/index.ts | 50 +- react-native.config.js | 14 + src/NativeDeepgram.ts | 25 +- src/helpers/audioUtils.ts | 6 +- src/rn-missing.d.ts | 19 + src/types/deepgram/text-to-speech.ts | 9 + src/useDeepgramManagement.ts | 9 +- src/useDeepgramSpeechToText.ts | 304 ++-- src/useDeepgramTextIntelligence.ts | 19 +- src/useDeepgramTextToSpeech.ts | 201 +-- src/useDeepgramVoiceAgent.ts | 67 +- yarn.lock | 68 +- 76 files changed, 5682 insertions(+), 1782 deletions(-) create mode 100644 android/src/main/java/com/deepgram/DeepgramAudioService.kt create mode 100644 example/.env.example create mode 100644 example/android/.gitignore create mode 100644 example/android/app/build.gradle create mode 100644 example/android/app/debug.keystore create mode 100644 example/android/app/proguard-rules.pro create mode 100644 example/android/app/src/debug/AndroidManifest.xml create mode 100644 example/android/app/src/main/AndroidManifest.xml create mode 100644 example/android/app/src/main/java/com/ahhzo/reactnativedeepgramexample/MainActivity.kt create mode 100644 example/android/app/src/main/java/com/ahhzo/reactnativedeepgramexample/MainApplication.kt create mode 100644 example/android/app/src/main/res/drawable-hdpi/splashscreen_logo.png create mode 100644 example/android/app/src/main/res/drawable-mdpi/splashscreen_logo.png create mode 100644 example/android/app/src/main/res/drawable-xhdpi/splashscreen_logo.png create mode 100644 example/android/app/src/main/res/drawable-xxhdpi/splashscreen_logo.png create mode 100644 example/android/app/src/main/res/drawable-xxxhdpi/splashscreen_logo.png create mode 100644 example/android/app/src/main/res/drawable/ic_launcher_background.xml create mode 100644 example/android/app/src/main/res/drawable/rn_edit_text_material.xml create mode 100644 example/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp create mode 100644 example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp create mode 100644 example/android/app/src/main/res/mipmap-mdpi/ic_launcher.webp create mode 100644 example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp create mode 100644 example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp create mode 100644 example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp create mode 100644 example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp create mode 100644 example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp create mode 100644 example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp create mode 100644 example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp create mode 100644 example/android/app/src/main/res/values-night/colors.xml create mode 100644 example/android/app/src/main/res/values/colors.xml create mode 100644 example/android/app/src/main/res/values/strings.xml create mode 100644 example/android/app/src/main/res/values/styles.xml create mode 100644 example/android/build.gradle create mode 100644 example/android/gradle.properties create mode 100644 example/android/gradle/wrapper/gradle-wrapper.jar create mode 100644 example/android/gradle/wrapper/gradle-wrapper.properties create mode 100755 example/android/gradlew create mode 100644 example/android/gradlew.bat create mode 100644 example/android/settings.gradle create mode 100644 example/src/components/Button.tsx create mode 100644 example/src/components/Card.tsx create mode 100644 example/src/components/Field.tsx create mode 100644 example/src/components/StatusBadge.tsx create mode 100644 example/src/theme.ts create mode 100644 react-native.config.js create mode 100644 src/rn-missing.d.ts diff --git a/README.md b/README.md index 7047212..710cd56 100644 --- a/README.md +++ b/README.md @@ -3,59 +3,61 @@ [![npm version](https://badge.fury.io/js/react-native-deepgram.svg)](https://badge.fury.io/js/react-native-deepgram) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) -**react-native-deepgram** brings Deepgram's AI platform to React Native & Expo. +The complete client for Deepgram's voice AI platform on **React Native** and **Expo** β€” real-time transcription, conversational voice agents, text-to-speech, and text intelligence in a single dependency, with hardware echo cancellation and background-audio support wired up for you. -> βœ… Supports **Speech-to-Text v1** and the new **Speech-to-Text v2 (Flux)** streaming API alongside Text-to-Speech, Text Intelligence, and the Management API. +```bash +yarn add react-native-deepgram +``` + +## At a glance + +| | | +| --- | --- | +| πŸ—£οΈ **Voice Agent** | Full-duplex agents over Deepgram's WebSocket. Hardware AEC on iOS (VPIO) and Android (`VOICE_COMMUNICATION` + `MODE_IN_COMMUNICATION`). Function calling, prompt updates, latency telemetry. | +| πŸŽ™οΈ **Speech-to-Text** | Live PCM streaming over WebSocket on STT v1 *or* Flux v2 (`flux-general-en`). File transcription with summarisation, topics, intents, entities. | +| πŸ”Š **Text-to-Speech** | One-shot HTTP synthesis or low-latency WebSocket streaming with `Speak` / `Flush` / `Clear` / `Close` controls. | +| 🧠 **Text Intelligence** | Summaries, topics, intents, sentiment over text or URLs. | +| πŸ› οΈ **Management API** | Typed wrapper for projects, models, keys, usage, balances, members, invitations, scopes, purchases. | +| βš™οΈ **Expo plugin** | One-line install β€” handles permissions, background-audio modes, and Android foreground service automatically. | +| 🧰 **Resilient by default** | Audio interruptions, route changes, headphone unplugging, mediaserverd resets, audio-focus loss, and queue overflow are all handled. | +| πŸ†• **Modern iOS APIs** | `AVAudioApplication.requestRecordPermission` and `AllowBluetoothHFP` on iOS 17+, with safe fallbacks. | + +--- ## Table of contents -1. [Features](#features) -2. [Installation](#installation) -3. [Expo config plugin](#expo-config-plugin) -4. [Configuration](#configuration) -5. [Usage overview](#usage-overview) +1. [Quick start (5 minutes)](#quick-start-5-minutes) +2. [Requirements](#requirements) +3. [Installation](#installation) +4. [Core concepts](#core-concepts) +5. [Audio session, AEC & background](#audio-session-aec--background) 6. [Voice Agent](#voice-agent-usedeepgramvoiceagent) 7. [Speech-to-Text](#speech-to-text-usedeepgramspeechtotext) 8. [Text-to-Speech](#text-to-speech-usedeepgramtexttospeech) 9. [Text Intelligence](#text-intelligence-usedeepgramtextintelligence) 10. [Management API](#management-api-usedeepgrammanagement) -11. [Example app](#example-app) -12. [Roadmap](#roadmap) -13. [Contributing](#contributing) -14. [License](#license) +11. [Expo config plugin reference](#expo-config-plugin-reference) +12. [Common recipes](#common-recipes) +13. [Troubleshooting](#troubleshooting) +14. [Example app](#example-app) +15. [Roadmap](#roadmap) +16. [Contributing](#contributing) +17. [License](#license) --- -## Features +## Quick start (5 minutes) -- πŸ”Š **Live Speech-to-Text** – capture PCM audio and stream it over WebSocket (STT v1 or v2/Flux). -- πŸ“„ **File Transcription** – send audio files/URIs to Deepgram and receive transcripts. -- 🎀 **Text-to-Speech** – synthesize speech with HTTP requests or WebSocket streaming controls. -- πŸ—£οΈ **Voice Agent** – orchestrate realtime conversational agents with microphone capture + audio playback. -- 🧠 **Text Intelligence** – summarisation, topic detection, intents, sentiment and more. -- πŸ› οΈ **Management API** – list models, keys, usage, projects, balances, etc. -- βš™οΈ **Expo config plugin** – automatic native configuration for managed and bare workflows. - ---- - -## Installation +### 1. Install ```bash yarn add react-native-deepgram -# or -npm install react-native-deepgram ``` -### iOS (CocoaPods) - -```bash -cd ios && pod install -``` - -### Expo +### 2. Configure the Expo plugin ```js -// app.config.js +// app.config.js (or app.json under "plugins") module.exports = { expo: { plugins: [ @@ -76,19 +78,115 @@ npx expo prebuild npx expo run:ios # or expo run:android ``` +> Bare React Native? Skip the plugin, run `cd ios && pod install`. The package autolinks via `react-native.config.js`. + +### 3. Configure the SDK once at startup + +```ts +// App.tsx +import { configure } from 'react-native-deepgram'; + +configure({ apiKey: process.env.EXPO_PUBLIC_DEEPGRAM_API_KEY! }); +``` + +> **Never ship raw API keys.** Use `EXPO_PUBLIC_*` env vars, secrets storage, or a backend proxy that mints scoped keys. + +### 4. Stream microphone audio to Deepgram (live STT) + +```tsx +import { useDeepgramSpeechToText } from 'react-native-deepgram'; +import { Button, Text, View } from 'react-native'; + +export function LiveCaption() { + const { + startListening, + stopListening, + state, // { status: 'idle' | 'listening' | 'error' | ... } + transcript, // accumulated final transcript + interimTranscript, // current partial + } = useDeepgramSpeechToText({ + trackState: true, + trackTranscript: true, + live: { punctuate: true, interimResults: true }, + }); + + return ( + + {transcript} {interimTranscript} +