A React Native voice-powered todo application built with Expo. Voice recordings are transcribed through an Appwrite Function so the OpenAI API key is never bundled into the mobile app.
- Voice-to-text task creation
- Smart multi-task creation from one spoken phrase
- Task completion, editing, deletion, and detail views
- Local task persistence with AsyncStorage
- Reminder notifications with custom alarm sound support
- Expo Router navigation
- Node.js
- npm
- Android Studio / emulator or a physical Android device
- Expo development environment
- Appwrite project with one Node.js Function
- OpenAI API key stored only in the Appwrite Function environment
-
Create an Appwrite project in the Appwrite Console.
-
Create a Node.js Function named
transcribe-audio. -
Use this repository folder as the function root:
appwrite/functions/transcribe-audio -
Configure the function:
Runtime: Node.js 20 or newer Entrypoint: src/main.js Build command: npm install -
Add function environment variables in Appwrite:
OPENAI_API_KEY=sk-... OPENAI_TRANSCRIPTION_MODEL=gpt-4o-mini-transcribeOPENAI_TRANSCRIPTION_MODELis optional. -
Deploy the function and copy its generated function domain, for example:
https://your-function-id.region.appwrite.run -
Make sure the function can be executed by your app. For a public app without Appwrite login, allow public/guest execution or use the generated function domain as your public endpoint.
-
Install dependencies:
npm install
-
Create
.envfrom the example:cp .env.example .env
-
Set the Appwrite Function URL:
EXPO_PUBLIC_TRANSCRIPTION_FUNCTION_URL=https://your-function-id.region.appwrite.runDo not put
OPENAI_API_KEYin the Expo app. -
Start Expo:
npx expo start
-
Run Android:
npx expo run:android
todo-voice/
app/ Expo Router screens
appwrite/functions/transcribe-audio/ Appwrite Function for transcription
assets/ Images and sounds
src/components/ Reusable UI components
src/context/ Task state provider
src/hooks/ Voice recording and task hooks
src/screens/ Main app screens
src/services/speechToText.ts Calls the Appwrite Function
src/services/notification.ts Local notification scheduling
- Never commit
.env. - The Expo app should only contain public config like the Appwrite Function URL.
- Store
OPENAI_API_KEYonly in Appwrite Function environment variables. - Monitor OpenAI usage from the OpenAI dashboard because transcription calls still incur API usage.
If transcription fails:
- Confirm
EXPO_PUBLIC_TRANSCRIPTION_FUNCTION_URLpoints to the generated Appwrite Function domain. - Confirm the Appwrite Function has
OPENAI_API_KEYconfigured. - Check the function execution logs in Appwrite Console.
- Rebuild/restart Expo after changing
.env.
If Android notifications keep old sound settings:
adb uninstall com.thehubx.todovoice
npx expo run:android