VillageLink AI — Bringing Tswana AI to Makuta via WhatsApp

VillageLink AI — Bringing Tswana AI to Makuta via WhatsApp

# devchallenge# weekendchallenge# showdev
VillageLink AI — Bringing Tswana AI to Makuta via WhatsAppPEACEBINFLOW

VillageLink AI — Bringing Tswana AI to Makuta via WhatsApp An AI voice & chat app for community...

VillageLink AI — Bringing Tswana AI to Makuta via WhatsApp

An AI voice & chat app for community information in Botswana’s Makuta Village

Makuta is a small village in the Central District of Botswana located about 70 km northwest of Francistown, along the road to Tutume. It had ~907 residents in the 2022 census, and like many rural communities, access to information is patchy — especially when literacy, data costs, and low-end phones are real constraints.

🧠 The Problem

In Makuta and surrounding areas:

Many people speak Setswana (Tswana) more fluently than English.

A significant portion can’t easily read or write complex text.

WhatsApp is the communication platform everyone already uses.

Data costs are high and unreliable connectivity is common.

Traditional news channels and apps don’t serve this reality — most tools assume:

keyboards

stable Internet

English proficiency

That’s not Makuta.
So I built something for us.

🛠️ What I Built — VillageLink AI

VillageLink AI is a WhatsApp-powered AI assistant that:

📱 Speaks Tswana

You can talk to it in Setswana — voice or text — and it responds in Setswana (or English if needed).
No complex apps — just WhatsApp.

🔊 Voice-First Interaction

Users send a voice clip or message like:

“Ka ntlha yang ga re kopane ka kgotla gompieno?”
(Why are we meeting at the kgotla today?)

VillageLink AI replies with:

Voice reply in Setswana

Short text summary

Optional offline shareable files

This makes it accessible even to people who don’t type or read well.

🌍 Information Sync for the Whole Community

It can:

Share announcements (village meetings, health info, events)

Summarize important news

Answer local questions

Generate short, low-data audio & text updates

📦 Offline & Low-Data Support

We optimized:

File sizes for low-end devices

Offline info packs (tiny audio/text bundles)

Summaries that can be saved and shared

Because data is expensive.

💥 Why This Matters

This isn’t just another bot — it’s:

Culturally grounded: Designed for Setswana speakers in Botswana, starting with Makuta.

Practical: Uses WhatsApp, which people already use daily.

Inclusive: Works for non-readers, elders, farmers, students.

Low-barrier: No new apps, no new accounts, low data.

It’s information justice — not tech for tech’s sake.

📊 Demo Walkthrough

Open WhatsApp → send a voice message in Setswana.

VillageLink AI transcribes & understands it.

AI responds with:

Tswana voice reply

Short text summary

Optional downloadable info file

We show this in the demo video and screenshots in the post.

🧪 Tech Stack (in brief)

WhatsApp Cloud API (Meta)

GPT-powered NLP tuned for Setswana

Speech-to-text + text-to-speech

Node.js backend

Minimal offline file generator

💬 Community Impact (Makuta & Beyond)

This tool is a social connector for a village where:

People often learn everything via word of mouth

Outsiders (family in towns) are cut off from daily life

Elders might miss crucial updates because they can’t read

VillageLink AI bridges that gap — making Makuta smarter, more connected, and more empowered.

🔧 Technical Breakdown

This section documents how VillageLink AI is built, how it works, and how it can scale.


🧱 System Architecture

[ User (WhatsApp) ]
        |
        v
[ WhatsApp Cloud API ]
        |
        v
[ Node.js API Server ]
        |
        +--> Speech-to-Text (Whisper)
        |
        +--> Prompt System (Setswana)
        |
        +--> GPT AI Core
        |
        +--> Text-to-Speech
        |
        v
[ Response Formatter ]
        |
        v
[ WhatsApp Reply (Voice + Text + Files) ]
Enter fullscreen mode Exit fullscreen mode

🔁 Message Processing Flow (Flowchart)

User sends voice/text
        |
        v
Detect type (voice or text)
        |
        +--> If voice:
        |       Transcribe to text
        |
        v
Normalize Setswana input
        |
        v
Send to Prompt System
        |
        v
GPT processes request
        |
        v
Generate:
 - Setswana text reply
 - Optional audio reply
 - Optional info pack
        |
        v
Send back via WhatsApp
Enter fullscreen mode Exit fullscreen mode

🧠 Prompt System Design

System Prompt (core AI behavior)

You are VillageLink AI.
You assist people in Makuta village in Botswana.
You must:
- Prefer Setswana language
- Use simple words
- Be short and clear
- Prioritize voice-friendly responses
- Assume users may not read well
- Avoid technical or complex terms
Enter fullscreen mode Exit fullscreen mode

User Prompt Template

User said (in Setswana):
"{transcribed_text}"

Reply in Setswana.
Keep response under 4 sentences.
If useful, summarize clearly.
Enter fullscreen mode Exit fullscreen mode

🗂️ GitHub Repository Structure

village-link-ai/
│
├── server/
│   ├── index.js
│   ├── routes/
│   │     └── whatsapp.js
│   ├── services/
│   │     ├── ai.js
│   │     ├── speech.js
│   │     └── formatter.js
│   └── prompts/
│         └── system.txt
│
├── offline-packs/
│   └── generator.js
│
├── public/
│   └── demo.mp4
│
├── .env
├── package.json
└── README.md
Enter fullscreen mode Exit fullscreen mode

🧩 Code Skeleton

server/index.js

import express from "express";
import whatsappRouter from "./routes/whatsapp.js";

const app = express();
app.use(express.json());

app.use("/webhook", whatsappRouter);

app.listen(3000, () => {
  console.log("VillageLink AI running...");
});
Enter fullscreen mode Exit fullscreen mode

routes/whatsapp.js

import express from "express";
import { handleMessage } from "../services/ai.js";

const router = express.Router();

router.post("/", async (req, res) => {
  const message = req.body.message;
  const reply = await handleMessage(message);
  res.json(reply);
});

export default router;
Enter fullscreen mode Exit fullscreen mode

services/ai.js

import { transcribeAudio, speakText } from "./speech.js";
import { formatResponse } from "./formatter.js";
import fs from "fs";

export async function handleMessage(message) {
  let text = message.text;

  if (message.audio) {
    text = await transcribeAudio(message.audio);
  }

  const prompt = fs.readFileSync("./prompts/system.txt", "utf8");

  const aiReply = await callGPT(prompt, text);

  const audioReply = await speakText(aiReply);

  return formatResponse(aiReply, audioReply);
}
Enter fullscreen mode Exit fullscreen mode

services/speech.js

export async function transcribeAudio(audioFile) {
  return "Transcribed Setswana text here";
}

export async function speakText(text) {
  return "audio-file.mp3";
}
Enter fullscreen mode Exit fullscreen mode

services/formatter.js

export function formatResponse(text, audio) {
  return {
    text: text,
    audio: audio
  };
}
Enter fullscreen mode Exit fullscreen mode

📦 Offline Pack Generator

export function generateOfflinePack(content) {
  return {
    audio: "compressed.mp3",
    text: content,
    size: "small"
  };
}
Enter fullscreen mode Exit fullscreen mode

📈 Scaling Strategy

Phase 1 – Makuta Only

  • Single bot
  • Setswana only
  • Manual announcements

Phase 2 – District Level

  • Multiple villages
  • Language selection
  • Auto summaries

Phase 3 – National Scale

  • Multi-language support
  • SMS fallback
  • Distributed servers
  • Edge caching

🧭 Data Philosophy

  • No heavy user tracking
  • No unnecessary storage
  • Focus on:

    • community info
    • summaries
    • access

AI as a utility, not surveillance.


🏁 Why This Architecture Works

✔ WhatsApp = UI
✔ Voice-first
✔ Low data
✔ Modular
✔ Language-driven
✔ Scalable

🧩 Technical Appendix — VillageLink AI


🏗️ Architecture Diagram

[ WhatsApp User ]
        |
        v
[ WhatsApp Cloud API ]
        |
        v
[ Express API Server ]
        |
        +--> Speech-to-Text (Whisper)
        |
        +--> Prompt Engine (Setswana rules)
        |
        +--> GPT AI Core
        |
        +--> Text-to-Speech
        |
        v
[ Response Formatter ]
        |
        v
[ WhatsApp Reply (Text + Voice + File) ]
Enter fullscreen mode Exit fullscreen mode

🔁 Processing Flowchart

User sends message
        |
        v
Check message type
        |
   +----+-----+
   |          |
Voice       Text
   |          |
Transcribe   |
   |          |
   +----+-----+
        |
Normalize Setswana input
        |
Send to Prompt Engine
        |
Send to GPT
        |
Generate response
        |
Convert to audio
        |
Send via WhatsApp
Enter fullscreen mode Exit fullscreen mode

🧠 Prompt System

prompts/system.txt

You are VillageLink AI.
You serve the village of Makuta in Botswana.
Your job:
- Prefer Setswana language
- Use very simple words
- Speak like a helpful local assistant
- Keep responses under 4 sentences
- Assume user may not read well
- Prioritize clarity over detail
- Avoid technical language
Enter fullscreen mode Exit fullscreen mode

User Prompt Template

User said (Setswana):
"{input}"

Reply in Setswana.
Keep response short and voice-friendly.
Enter fullscreen mode Exit fullscreen mode

📁 GitHub Repository Structure

village-link-ai/
│
├── server/
│   ├── index.js
│   ├── routes/
│   │     └── whatsapp.js
│   ├── services/
│   │     ├── ai.js
│   │     ├── speech.js
│   │     └── formatter.js
│   └── prompts/
│         └── system.txt
│
├── offline-packs/
│   └── generator.js
│
├── public/
│   └── demo.mp4
│
├── .env
├── package.json
└── README.md
Enter fullscreen mode Exit fullscreen mode

🧩 Code Skeleton

server/index.js

import express from "express";
import whatsappRouter from "./routes/whatsapp.js";

const app = express();
app.use(express.json());
app.use("/webhook", whatsappRouter);

app.listen(3000, () => {
  console.log("VillageLink AI running");
});
Enter fullscreen mode Exit fullscreen mode

routes/whatsapp.js

import express from "express";
import { handleMessage } from "../services/ai.js";

const router = express.Router();

router.post("/", async (req, res) => {
  const message = req.body;
  const reply = await handleMessage(message);
  res.json(reply);
});

export default router;
Enter fullscreen mode Exit fullscreen mode

services/ai.js

import fs from "fs";
import { transcribeAudio, speakText } from "./speech.js";
import { formatResponse } from "./formatter.js";

export async function handleMessage(message) {
  let text = message.text;

  if (message.audio) {
    text = await transcribeAudio(message.audio);
  }

  const systemPrompt = fs.readFileSync("./prompts/system.txt", "utf8");
  const aiReply = await callGPT(systemPrompt, text);
  const audioReply = await speakText(aiReply);

  return formatResponse(aiReply, audioReply);
}
Enter fullscreen mode Exit fullscreen mode

services/speech.js

export async function transcribeAudio(file) {
  return "Transcribed Setswana text";
}

export async function speakText(text) {
  return "voice.mp3";
}
Enter fullscreen mode Exit fullscreen mode

services/formatter.js

export function formatResponse(text, audio) {
  return {
    text,
    audio
  };
}
Enter fullscreen mode Exit fullscreen mode

📦 Offline Pack Generator

export function generateOfflinePack(content) {
  return {
    text: content,
    audio: "compressed.mp3",
    size: "small"
  };
}
Enter fullscreen mode Exit fullscreen mode

📘 README.md

# VillageLink AI

An AI-powered WhatsApp assistant for Setswana-speaking village communities in Botswana.

## Features
- Setswana voice interaction
- WhatsApp interface
- Low-data optimization
- Offline info packs
- Community announcements

## Run locally
npm install  
node server/index.js

## Environment Variables
OPENAI_KEY  
WHATSAPP_TOKEN  
WHATSAPP_PHONE_ID

## Usage
Send a WhatsApp message to the bot number.
Receive voice and text replies in Setswana.
Enter fullscreen mode Exit fullscreen mode

🚀 Deployment Guide

1️⃣ Setup WhatsApp Cloud API

  • Create Meta Developer app
  • Enable WhatsApp
  • Set webhook URL

2️⃣ Server

  • Node.js backend
  • Host on:

    • Railway
    • Render
    • Fly.io

3️⃣ Environment

OPENAI_KEY=xxx
WHATSAPP_TOKEN=xxx
Enter fullscreen mode Exit fullscreen mode

4️⃣ Webhook

POST /webhook
Enter fullscreen mode Exit fullscreen mode

📈 Scaling Plan

Phase 1 — Makuta

  • One bot
  • Setswana
  • Manual announcements

Phase 2 — District

  • Multiple villages
  • Language selector
  • Auto summaries

Phase 3 — National

  • SMS fallback
  • Edge servers
  • Language packs
  • Community admins

🧭 Design Philosophy

  • WhatsApp = UI
  • Voice > Text
  • Language-first
  • Low-data
  • Human-centered AI