KEY INSIGHT
Feature phones still dominate in many African markets; USSD and SMS interfaces extend AI services to the widest possible audience.
USSD (Unstructured Supplementary Service Data) provides real-time, session-based communication that works on any GSM phone without internet. SMS offers asynchronous communication. Integrating AI capabilities into these channels requires careful design—character limits, menu-driven navigation, and the absence of rich formatting.
A weather information service accessed via USSD: the user dials a code, navigates a menu, and receives plain-text weather forecasts for their location.
```python
# USSD AI service framework
class USSDService:
def __init__(self, session_store, ai_services):
self.sessions = session_store
self.ai = ai_services
def handle_request(self, text, phone_number):
"""
Process incoming USSD request
text: the user's input (multiple entries separated by *)
"""
session = self.sessions.get_or_create(phone_number)
# Parse USSD input (comes as asterisk-separated string)
inputs = text.split('*')
current_input = inputs[-1] if inputs[-1] else None
# Menu state machine
if session['state'] == 'initial':
return self._show_main_menu(session)
elif session['state'] == 'main_menu':
return self._handle_main_choice(current_input, session)
elif session['state'] == 'query_entry':
return self._process_ai_query(current_input, session)
return self._show_main_menu(session)
def _show_main_menu(self, session):
session['state'] = 'main_menu'
self.sessions.update(session)
menu_text = """Welcome to FarmAI
1. Market Prices
2. Weather Forecast
3. Crop Advice
4. Language Translation
5. Help"""
return self._ussd_response(menu_text, continue_session=True)
def _handle_main_choice(self, choice, session):
handlers = {
'1': ('market_prices', 'location_entry'),
'2': ('weather', 'location_entry'),
'3': ('crop_advice', 'crop_select'),
'4': ('translation', 'translation_menu'),
'5': ('help', 'help_display'),
}
if choice in handlers:
service, next_state = handlers[choice]
session['service'] = service
session['state'] = next_state
self.sessions.update(session)
prompts = {
'location_entry': "Enter your LGA (e.g., Zaria):",
'crop_select': "Select crop: 1-Maize 2-Rice 3-Cassava",
'translation_menu': "Enter text to translate:"
}
return self._ussd_response(prompts[next_state], continue_session=True)
return self._ussd_response("Invalid choice", continue_session=True)
def _process_ai_query(self, input_text, session):
service = session.get('service')
location = session.get('location', '')
if service == 'weather':
result = self.ai.get_weather(location)
elif service == 'market_prices':
result = self.ai.get_market_prices(location, input_text)
elif service == 'translation':
result = self.ai.translate_text(input_text, target='en')
else:
result = "Service unavailable"
# USSD has 182 character limit per message
truncated = result[:180]
return self._ussd_response(truncated, continue_session=False)
def _ussd_response(self, message, continue_session):
return {
'text': message,
'continue': continue_session
}
```
The 182-character USSD limit requires aggressive truncation. For longer AI responses, multi-message sequences work, but the session-based nature of USSD complicates state management.