Skip to content

pezkins/messaging-app

Repository files navigation

Intok πŸ’¬πŸŒ

A multilingual mobile messaging app that automatically translates messages into your preferred language. Talk to anyone, anywhere!

πŸ“– New to coding? Check out SETUP.md for a beginner-friendly step-by-step guide!

Architecture Overview

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                                INTOK ARCHITECTURE                                β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   πŸ“± Mobile App  β”‚         β”‚   πŸ“± Mobile App  β”‚         β”‚   🌐 Web App     β”‚
β”‚   (iOS/Android)  β”‚         β”‚   (iOS/Android)  β”‚         β”‚   (Browser)      β”‚
β”‚   User: Alice    β”‚         β”‚   User: Carlos   β”‚         β”‚   User: Yuki     β”‚
β”‚   Lang: English  β”‚         β”‚   Lang: Spanish  β”‚         β”‚   Lang: Japanese β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚                            β”‚                            β”‚
         β”‚  REST API (HTTP)           β”‚  REST API (HTTP)           β”‚  REST API (HTTP)
         β”‚  + Socket.IO (WS)          β”‚  + Socket.IO (WS)          β”‚  + Socket.IO (WS)
         β”‚                            β”‚                            β”‚
         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                      β”‚
                                      β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                           πŸ–₯️  NODE.JS SERVER                                    β”‚
β”‚                              (Express.js)                                        β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
β”‚  β”‚                         API ROUTES                                       β”‚    β”‚
β”‚  β”‚  /api/auth/*        - Login, Register, Token Refresh                    β”‚    β”‚
β”‚  β”‚  /api/users/*       - Profile, Language Settings, Search                β”‚    β”‚
β”‚  β”‚  /api/conversations - List, Create Conversations                        β”‚    β”‚
β”‚  β”‚  /api/messages/*    - Message History, Translation Preview              β”‚    β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
β”‚                                      β”‚                                           β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
β”‚  β”‚                      SOCKET.IO HANDLERS                                  β”‚    β”‚
β”‚  β”‚  message:send    β†’ Receive message, detect language, translate, store   β”‚    β”‚
β”‚  β”‚  message:receive ← Send translated message to recipient                 β”‚    β”‚
β”‚  β”‚  message:typing  ↔ Typing indicators                                    β”‚    β”‚
β”‚  β”‚  message:read    ↔ Read receipts                                        β”‚    β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
β”‚                                      β”‚                                           β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”‚
β”‚  β”‚ πŸ” Auth Service   β”‚    β”‚ 🌐 Translation Svc  β”‚    β”‚ πŸ’¬ Message Serviceβ”‚      β”‚
β”‚  β”‚ - JWT tokens      β”‚    β”‚ - Language detect   β”‚    β”‚ - Store messages  β”‚      β”‚
β”‚  β”‚ - Password hash   β”‚    β”‚ - Translate text    β”‚    β”‚ - Fetch history   β”‚      β”‚
β”‚  β”‚ - Session mgmt    β”‚    β”‚ - Cache results     β”‚    β”‚ - Real-time sync  β”‚      β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                       β”‚
         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
         β”‚                             β”‚                             β”‚
         β–Ό                             β–Ό                             β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  🐘 PostgreSQL  β”‚         β”‚   πŸ€– AI Provider    β”‚         β”‚   πŸ”΄ Redis      β”‚
β”‚                 β”‚         β”‚   (configurable)    β”‚         β”‚                 β”‚
β”‚  - Users        β”‚         β”‚                     β”‚         β”‚  - Translation  β”‚
β”‚  - Messages     β”‚         β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚         β”‚    cache        β”‚
β”‚  - Conversationsβ”‚         β”‚  β”‚ OpenAI        β”‚  β”‚         β”‚  - User sessionsβ”‚
β”‚  - Translations β”‚         β”‚  β”‚ (gpt-4o-mini) β”‚  β”‚         β”‚  - Socket IDs   β”‚
β”‚                 β”‚         β”‚  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€  β”‚         β”‚                 β”‚
β”‚                 β”‚         β”‚  β”‚ Claude        β”‚  β”‚         β”‚                 β”‚
β”‚                 β”‚         β”‚  β”‚ (haiku)       β”‚  β”‚         β”‚                 β”‚
β”‚                 β”‚         β”‚  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€  β”‚         β”‚                 β”‚
β”‚                 β”‚         β”‚  β”‚ DeepSeek      β”‚  β”‚         β”‚                 β”‚
β”‚                 β”‚         β”‚  β”‚ (chat)        β”‚  β”‚         β”‚                 β”‚
β”‚                 β”‚         β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚         β”‚                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Message Flow Example

Alice (English) sends "Hello, how are you?" to Carlos (Spanish):

1. πŸ“± Alice's App
   └─► Socket.IO: message:send { content: "Hello, how are you?", conversationId: "xxx" }

2. πŸ–₯️ Server receives message
   β”œβ”€β–Ί Detect language β†’ "en" (English)
   β”œβ”€β–Ί Store original message in PostgreSQL
   └─► For each recipient, translate to their language:

3. πŸ€– AI Provider (for Carlos - Spanish)
   β”œβ”€β–Ί Input: "Hello, how are you?" (en β†’ es)
   └─► Output: "Β‘Hola! ΒΏCΓ³mo estΓ‘s?"

4. πŸ”΄ Redis
   └─► Cache translation for future requests

5. πŸ“± Carlos's App
   └─◄ Socket.IO: message:receive { 
         originalContent: "Hello, how are you?",
         translatedContent: "Β‘Hola! ΒΏCΓ³mo estΓ‘s?",
         originalLanguage: "en",
         targetLanguage: "es"
       }

6. πŸ“± Carlos sees: "Β‘Hola! ΒΏCΓ³mo estΓ‘s?" 
   └─► (Can tap to view original English)

Network Diagram (Development Setup)

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     YOUR WINDOWS MACHINE                         β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚   🌐 Web Browser    β”‚    β”‚      πŸ“± Expo Go App             β”‚ β”‚
β”‚  β”‚   localhost:8081    β”‚    β”‚      (on your phone)            β”‚ β”‚
β”‚  β”‚                     β”‚    β”‚                                 β”‚ β”‚
β”‚  β”‚   React Native Web  β”‚    β”‚   Connects via WiFi to:         β”‚ β”‚
β”‚  β”‚   (Expo Web)        β”‚    β”‚   http://192.168.2.62:3001      β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚             β”‚                          β”‚                         β”‚
β”‚             β”‚ HTTP/WebSocket           β”‚ HTTP/WebSocket          β”‚
β”‚             └──────────────────────────┼──────────────────────────
β”‚                                        β”‚                         β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚              WSL (Ubuntu)           β”‚                       β”‚ β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚                       β”‚ β”‚
β”‚  β”‚  β”‚  πŸ“ Source Code             β”‚    β”‚                       β”‚ β”‚
β”‚  β”‚  β”‚  /home/ayepez/github/       β”‚    β”‚                       β”‚ β”‚
β”‚  β”‚  β”‚  messaging-app/             β”‚    β”‚                       β”‚ β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚                       β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                         β”‚
                        Network (LAN)    β”‚  192.168.2.x
                                         β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              PROXMOX VM (Ubuntu)       β”‚    IP: 192.168.2.62     β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚                    πŸ–₯️ Node.js Server                        β”‚ β”‚
β”‚  β”‚                    Port 3001                                 β”‚ β”‚
β”‚  β”‚                    (PM2 managed)                             β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚                             β”‚                                    β”‚
β”‚       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”              β”‚
β”‚       β–Ό                     β–Ό                     β–Ό              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”‚
β”‚  β”‚πŸ˜ Postgresβ”‚        β”‚ πŸ”΄ Redis    β”‚       β”‚ πŸ€– Claude β”‚        β”‚
β”‚  β”‚Port 5432 β”‚        β”‚ Port 6379   β”‚       β”‚   API     β”‚        β”‚
β”‚  β”‚(Docker)  β”‚        β”‚ (Docker)    β”‚       β”‚ (Internet)β”‚        β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ†• Native App Migration (In Progress)

We are migrating from React Native (Expo) to fully native apps:

Platform Technology Status
Android Kotlin + Jetpack Compose 🚧 In Development
iOS Swift + SwiftUI 🚧 In Development
React Native Expo βœ… Production (being deprecated)

Native Development Branches

dev    β†’ Development builds (simulators)
stage  β†’ Internal testing (Play Store Internal + TestFlight)
main   β†’ Production release (Play Store + App Store)

πŸ“– See NATIVE_MIGRATION.md for detailed setup and deployment instructions.

Developer Workflow: Testing CI/CD Builds Locally

After pushing to the dev branch, the CI/CD pipeline builds debug artifacts for both Android and iOS. Here's how to download and install them on your local simulators:

Prerequisites

# Install GitHub CLI (if not already installed)
brew install gh

# Authenticate with GitHub
gh auth login

Download & Install Builds

# 1. Find the latest successful run
gh run list --branch dev --limit 5

# 2. Download artifacts (replace RUN_ID with the actual run ID)
gh run download RUN_ID -D ./builds

# 3. Install Android APK to emulator
#    (Make sure Android emulator is running)
adb install ./builds/intok-android-debug-*/app-debug.apk

# 4. Install iOS app to simulator
#    (Make sure iOS simulator is running)
xcrun simctl install booted ./builds/intok-ios-debug-*/Intok.app

One-Liner: Download & Install Latest Build

# Android (emulator must be running)
gh run download $(gh run list --branch dev --limit 1 --json databaseId -q '.[0].databaseId') -D ./builds && \
adb install ./builds/intok-android-debug-*/app-debug.apk

# iOS (simulator must be running)
gh run download $(gh run list --branch dev --limit 1 --json databaseId -q '.[0].databaseId') -D ./builds && \
xcrun simctl install booted ./builds/intok-ios-debug-*/Intok.app

Start Simulators

# Start Android emulator
emulator -avd Pixel_8_API_35 &

# Start iOS simulator
open -a Simulator
# Or specific device:
xcrun simctl boot "iPhone 15"

Features

  • Real-time messaging with WebSocket support
  • Automatic translation powered by Claude AI (Anthropic)
  • Translation preview before sending (1-to-1 chats)
  • Group chat support with per-user translation
  • Voice messages (Phase 2)
  • Message caching with Redis to minimize API calls
  • 16 supported languages including English, Spanish, French, Chinese, Japanese, etc.

Tech Stack

Backend (Two Options)

Option A: Traditional Server (server/)

  • Node.js + TypeScript - Server runtime
  • Express - REST API framework
  • Socket.IO - Real-time WebSocket communication
  • PostgreSQL + Prisma - Database
  • Redis - Translation caching

Option B: Serverless (Recommended) (server-serverless/)

  • AWS Lambda - Serverless functions
  • API Gateway - HTTP + WebSocket APIs
  • DynamoDB - Serverless database (pay-per-request)
  • No Redis needed - Translations cached in DynamoDB

AI Translation (Multi-Provider Support)

  • OpenAI - GPT-4o-mini model (default, fast & affordable)
  • Claude (Anthropic) - Claude Haiku model (~$0.25/million input tokens)
  • DeepSeek - DeepSeek Chat (~$0.14/million tokens, FREE tier available)

Switch providers via AI_PROVIDER environment variable.

Mobile App (iOS & Android)

  • React Native + Expo - Cross-platform mobile framework
  • Expo Router - File-based navigation
  • Socket.IO Client - Real-time communication
  • Zustand - State management
  • AsyncStorage - Token storage

Project Structure

messaging-app/
β”œβ”€β”€ server/                   # Traditional Express server (local dev)
β”‚   β”œβ”€β”€ prisma/               # PostgreSQL schema
β”‚   └── src/
β”‚       β”œβ”€β”€ routes/           # REST API endpoints
β”‚       β”œβ”€β”€ services/         # Translation service
β”‚       └── socket/           # Socket.IO handlers
β”‚
β”œβ”€β”€ server-serverless/        # AWS Lambda serverless (production)
β”‚   β”œβ”€β”€ template.yaml         # AWS SAM CloudFormation
β”‚   └── src/
β”‚       β”œβ”€β”€ handlers/         # Lambda functions
β”‚       └── lib/
β”‚           └── translation.ts # DeepSeek API + Ollama support
β”‚
β”œβ”€β”€ mobile/                   # React Native (Expo) app
β”‚   β”œβ”€β”€ app/                  # Expo Router screens
β”‚   β”‚   β”œβ”€β”€ (auth)/           # Login & Register
β”‚   β”‚   └── (app)/            # Conversations, Chat, Settings
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ services/         # API & WebSocket clients
β”‚   β”‚   β”œβ”€β”€ store/            # Zustand stores
β”‚   β”‚   └── constants/        # Theme & languages
β”‚   └── assets/               # App icons & images
β”‚
β”œβ”€β”€ infrastructure/
β”‚   β”œβ”€β”€ aws/                  # AWS deployment config
β”‚   β”‚   └── samconfig.toml
β”‚   └── ollama/               # Self-hosted AI setup
β”‚       β”œβ”€β”€ docker-compose.yml
β”‚       └── setup.sh
β”‚
β”œβ”€β”€ shared/                   # Shared TypeScript types
β”œβ”€β”€ DEPLOYMENT.md             # Detailed deployment guide
└── README.md                 # This file

Getting Started

Prerequisites

For Traditional Server:

  • Node.js >= 18
  • PostgreSQL database
  • Redis server
  • AI API key (OpenAI, Claude, or DeepSeek)

For Serverless (Recommended):

  • Node.js >= 18
  • AWS Account (free tier eligible)
  • AWS CLI + SAM CLI installed
  • AI API key (OpenAI, Claude, or DeepSeek)

Backend Setup

cd messaging-app

# Install dependencies
npm install

# Create server/.env file
cat > server/.env << EOF
DATABASE_URL="postgresql://postgres:password@localhost:5432/lingualink"
REDIS_URL="redis://localhost:6379"
AI_PROVIDER="openai"
OPENAI_API_KEY="your-openai-api-key"
JWT_SECRET="your-super-secret-jwt-key"
JWT_REFRESH_SECRET="your-refresh-secret-key"
PORT=3001
CORS_ORIGIN="*"
EOF

# Generate Prisma client
npm run db:generate

# Run database migrations
npm run db:migrate

# Seed demo data (optional)
npm run db:seed

# Start the server
npm run dev:server

Mobile App Setup

cd mobile

# Install dependencies
npm install

# Create .env file for mobile
cat > .env << EOF
EXPO_PUBLIC_API_URL=http://YOUR_SERVER_IP:3001
EXPO_PUBLIC_WS_URL=http://YOUR_SERVER_IP:3001
EOF

# Start Expo development server
npm start

Then scan the QR code with Expo Go app on your phone.

Demo Accounts

After seeding, you can use these accounts:

  • alice@example.com / password123 (English)
  • carlos@example.com / password123 (Spanish)
  • marie@example.com / password123 (French)
  • yuki@example.com / password123 (Japanese)

Deploying to App Stores

Prerequisites

  1. Apple Developer Account ($99/year) for iOS
  2. Google Play Developer Account ($25 one-time) for Android
  3. EAS CLI installed: npm install -g eas-cli

Build & Submit

cd mobile

# Login to Expo
eas login

# Configure your project
eas build:configure

# Build for iOS
eas build --platform ios --profile production

# Build for Android
eas build --platform android --profile production

# Submit to App Store
eas submit --platform ios

# Submit to Google Play
eas submit --platform android

App Store Configuration

  1. iOS (App Store Connect)

    • Create app in App Store Connect
    • Update app.json with your bundle identifier
    • Configure push notification certificates
  2. Android (Google Play Console)

    • Create app in Play Console
    • Generate upload key and configure signing
    • Set up Play App Signing

See Expo EAS Submit docs for detailed instructions.

API Documentation

Authentication

  • POST /api/auth/register - Register new user
  • POST /api/auth/login - Login user
  • POST /api/auth/refresh - Refresh access token

Users

  • GET /api/users/me - Get current user
  • PATCH /api/users/me/language - Update preferred language
  • GET /api/users/search?q=query - Search users

Conversations & Messages

  • GET /api/conversations - Get all conversations
  • POST /api/conversations - Create conversation
  • GET /api/conversations/:id/messages - Get messages
  • POST /api/messages/preview-translation - Preview translation

WebSocket Events

  • message:send - Send a message
  • message:receive - Receive translated message
  • message:typing - Typing indicator
  • message:read - Read receipt

Environment Variables - Complete Setup Checklist

πŸ”‘ API Keys & Accounts You Need

Service Purpose How to Get Cost
OpenAI API AI Translation (default) https://platform.openai.com/api-keys ~$0.15/M tokens
Claude API AI Translation (alt) https://console.anthropic.com/ ~$0.25/M tokens
DeepSeek API AI Translation (alt) https://platform.deepseek.com/ FREE tier
AWS Account Serverless hosting https://aws.amazon.com/free Free tier available
Apple Developer iOS App Store https://developer.apple.com/programs/ $99/year
Google Play Developer Android Play Store https://play.google.com/console $25 one-time
Expo Account Mobile builds https://expo.dev/signup FREE

πŸ“‹ Option 1: Traditional Server (server/.env)

Create file: server/.env

# ============================================
# DATABASE (Required)
# ============================================
# PostgreSQL connection string
# Format: postgresql://USER:PASSWORD@HOST:PORT/DATABASE
DATABASE_URL="postgresql://postgres:your_password@localhost:5432/lingualink"

# ============================================
# REDIS (Required for caching)
# ============================================
# Redis connection string
# Local: redis://localhost:6379
# Cloud (Upstash free tier): redis://default:xxx@xxx.upstash.io:6379
REDIS_URL="redis://localhost:6379"

# ============================================
# AI TRANSLATION (Required - Choose one provider)
# ============================================
# Set which AI provider to use: "openai" | "anthropic" | "deepseek"
AI_PROVIDER="openai"

# OpenAI API Key (if AI_PROVIDER=openai)
# Get it at: https://platform.openai.com/api-keys
OPENAI_API_KEY="sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

# Anthropic/Claude API Key (if AI_PROVIDER=anthropic)
# Get it at: https://console.anthropic.com/
ANTHROPIC_API_KEY="sk-ant-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

# DeepSeek API Key (if AI_PROVIDER=deepseek)
# Get it at: https://platform.deepseek.com/api_keys (FREE tier!)
DEEPSEEK_API_KEY="sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

# ============================================
# AUTHENTICATION (Required)
# ============================================
# JWT secrets - generate random strings (32+ characters)
# Generate with: openssl rand -base64 32
JWT_SECRET="your-super-secret-jwt-key-min-32-chars"
JWT_REFRESH_SECRET="your-refresh-secret-key-min-32-chars"

# Token expiration (optional)
JWT_EXPIRES_IN="15m"
JWT_REFRESH_EXPIRES_IN="7d"

# ============================================
# SERVER CONFIG (Optional)
# ============================================
PORT=3001
NODE_ENV="development"
CORS_ORIGIN="*"

πŸ“‹ Option 2: Serverless AWS (infrastructure/aws/samconfig.toml)

These are set during sam deploy --guided:

# ============================================
# REQUIRED PARAMETERS
# ============================================

# JWT Secret for authentication
# Generate with: openssl rand -base64 32
JwtSecret=your-jwt-secret-min-32-characters

# Translation mode: "api" or "ollama"
TranslationMode=api

# ============================================
# IF TranslationMode=api (DeepSeek Cloud)
# ============================================
# Get free API key at: https://platform.deepseek.com/api_keys
DeepSeekApiKey=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# ============================================
# IF TranslationMode=ollama (Self-hosted AI)
# ============================================
# URL of your Ollama server
OllamaUrl=http://your-server-ip:11434

πŸ“± Mobile App (mobile/.env)

Create file: mobile/.env

# ============================================
# API ENDPOINTS (Required)
# ============================================

# For LOCAL development:
EXPO_PUBLIC_API_URL=http://localhost:3001
EXPO_PUBLIC_WS_URL=ws://localhost:3001

# For AWS SERVERLESS (after deployment):
# Get these URLs from: sam deploy output or AWS Console
EXPO_PUBLIC_API_URL=https://xxxxxxxx.execute-api.us-east-1.amazonaws.com/prod
EXPO_PUBLIC_WS_URL=wss://xxxxxxxx.execute-api.us-east-1.amazonaws.com/prod

# For PRODUCTION with custom domain:
# EXPO_PUBLIC_API_URL=https://api.lingualink.app
# EXPO_PUBLIC_WS_URL=wss://ws.lingualink.app

πŸ“² App Store Submission (mobile/app.json & mobile/eas.json)

Update these in mobile/app.json:

{
  "expo": {
    "name": "LinguaLink",
    "slug": "lingualink",
    "ios": {
      "bundleIdentifier": "com.yourcompany.lingualink"  // Change this!
    },
    "android": {
      "package": "com.yourcompany.lingualink"  // Change this!
    },
    "extra": {
      "eas": {
        "projectId": "your-expo-project-id"  // From expo.dev
      }
    }
  }
}

Update in mobile/eas.json for app store submission:

{
  "submit": {
    "production": {
      "ios": {
        "appleId": "your-apple-id@email.com",
        "ascAppId": "1234567890"  // From App Store Connect
      },
      "android": {
        "serviceAccountKeyPath": "./google-service-account.json"
      }
    }
  }
}

πŸš€ Quick Start Commands

# 1. Generate secure JWT secrets
openssl rand -base64 32  # Run twice, use for JWT_SECRET and JWT_REFRESH_SECRET

# 2. Get an AI API key (choose one):
# - OpenAI (default): https://platform.openai.com/api-keys
# - Claude: https://console.anthropic.com/
# - DeepSeek (FREE): https://platform.deepseek.com/

# 3. Create server/.env with all values above

# 4. Start the app
cd messaging-app
npm install
npm run db:generate
npm run db:migrate
npm run dev:server

# 5. In another terminal, start mobile
cd mobile
npm install
npm start

πŸ” Security Notes

  • Never commit .env files to git (already in .gitignore)
  • Rotate JWT secrets periodically in production
  • Use AWS Secrets Manager for serverless production deployments
  • Claude API - monitor usage at console.anthropic.com

Roadmap

  • MVP: Text messaging + auto-translation
  • Phase 2: Voice messages
  • Phase 3: Group translation sync
  • Phase 4: Message reactions & emojis
  • Phase 5: Push notifications
  • Phase 6: Offline mode with local cache

License

MIT

About

Messaging app for android and apple

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published