Documentation Index
Fetch the complete documentation index at: https://developers.telnyx.com/llms.txt
Use this file to discover all available pages before exploring further.
Sending Text Messages to AI Agents
Overview
In addition to voice conversation, you can send text messages directly to the AI Agent during an active call. This allows for mixed-mode communication where users can both speak and type messages to the AI Assistant.
Method Signature
fun sendAIAssistantMessage(message: String)
Parameters
| Parameter | Type | Description |
|---|
message | String | The text message to send to the AI Assistant |
Basic Usage
// Send a text message to the AI Agent during an active call
telnyxClient.sendAIAssistantMessage("Hello, can you help me with my account?")
Complete Example
class AIConversationActivity : AppCompatActivity() {
private lateinit var messageInput: EditText
private lateinit var sendButton: Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_ai_conversation)
messageInput = findViewById(R.id.messageInput)
sendButton = findViewById(R.id.sendButton)
setupMessageSending()
}
private fun setupMessageSending() {
sendButton.setOnClickListener {
val message = messageInput.text.toString().trim()
if (message.isNotEmpty()) {
sendTextMessage(message)
messageInput.text.clear()
}
}
// Send on Enter key
messageInput.setOnEditorActionListener { _, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_SEND) {
sendButton.performClick()
true
} else {
false
}
}
}
private fun sendTextMessage(message: String) {
try {
telnyxClient.sendAIAssistantMessage(message)
Log.d("AI", "Text message sent: $message")
} catch (e: Exception) {
Log.e("AI", "Failed to send text message: ${e.message}")
showError("Failed to send message")
}
}
}
Advanced Usage with Call State Checking
class AIMessageManager(private val telnyxClient: TelnyxClient) {
fun sendMessage(message: String): Boolean {
return if (isAICallActive()) {
telnyxClient.sendAIAssistantMessage(message)
true
} else {
Log.w("AI", "Cannot send message: No active AI call")
false
}
}
private fun isAICallActive(): Boolean {
return telnyxClient.calls.values.any { call ->
call.callState == CallState.ACTIVE
}
}
fun sendMessageWithConfirmation(message: String, callback: (Boolean) -> Unit) {
if (sendMessage(message)) {
// Listen for confirmation in transcript updates
listenForMessageConfirmation(message, callback)
} else {
callback(false)
}
}
private fun listenForMessageConfirmation(
sentMessage: String,
callback: (Boolean) -> Unit
) {
// Monitor transcript for the sent message appearing
lifecycleScope.launch {
telnyxClient.transcriptUpdateFlow.collect { transcript ->
val userMessages = transcript.filter {
it.role == TranscriptItem.ROLE_USER
}
if (userMessages.any { it.content.contains(sentMessage) }) {
callback(true)
}
}
}
}
}
UI Integration Example
class ConversationFragment : Fragment() {
private lateinit var binding: FragmentConversationBinding
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = FragmentConversationBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupMessageInput()
setupTranscriptDisplay()
}
private fun setupMessageInput() {
binding.messageInput.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
binding.sendButton.isEnabled = !s.isNullOrBlank()
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
})
binding.sendButton.setOnClickListener {
sendCurrentMessage()
}
}
private fun sendCurrentMessage() {
val message = binding.messageInput.text.toString().trim()
if (message.isNotEmpty()) {
// Show message as "sending" in UI
addPendingMessage(message)
// Send to AI Assistant
telnyxClient.sendAIAssistantMessage(message)
// Clear input
binding.messageInput.text.clear()
}
}
private fun addPendingMessage(message: String) {
// Add message to UI with "sending" indicator
// This will be replaced when transcript updates arrive
}
}
class AIMessageHelper {
fun sendQuestion(question: String) {
telnyxClient.sendAIAssistantMessage("Question: $question")
}
fun sendCommand(command: String) {
telnyxClient.sendAIAssistantMessage("Command: $command")
}
fun sendContextualMessage(message: String, context: Map<String, String>) {
val contextString = context.entries.joinToString(", ") { "${it.key}: ${it.value}" }
telnyxClient.sendAIAssistantMessage("$message [Context: $contextString]")
}
fun sendFormattedMessage(message: String, format: MessageFormat) {
val formattedMessage = when (format) {
MessageFormat.URGENT -> "URGENT: $message"
MessageFormat.QUESTION -> "❓ $message"
MessageFormat.FEEDBACK -> "💬 $message"
MessageFormat.PLAIN -> message
}
telnyxClient.sendAIAssistantMessage(formattedMessage)
}
}
enum class MessageFormat {
URGENT, QUESTION, FEEDBACK, PLAIN
}
Error Handling
private fun sendTextMessageWithErrorHandling(message: String) {
try {
// Check if we have an active AI call
val hasActiveCall = telnyxClient.calls.values.any {
it.callState == CallState.ACTIVE
}
if (!hasActiveCall) {
showError("No active AI conversation. Please start a call first.")
return
}
// Send the message
telnyxClient.sendAIAssistantMessage(message)
// Show success feedback
showMessageSent(message)
} catch (e: Exception) {
Log.e("AI", "Failed to send message: ${e.message}")
showError("Failed to send message: ${e.message}")
}
}
private fun showError(message: String) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}
private fun showMessageSent(message: String) {
// Optional: Show brief confirmation
Log.d("AI", "Message sent successfully: $message")
}
Important Notes
- Active Call Required: You must have an active call established before sending text messages
- AI Assistant Only: The
sendAIAssistantMessage method is only available during AI Assistant conversations
- Transcript Integration: Text messages sent this way will appear in transcript updates alongside spoken conversation
- Processing: The AI Agent will process and respond to text messages just like spoken input
- Mixed Communication: Users can seamlessly switch between voice and text communication
Best Practices
- Validate Input: Always check that messages are not empty before sending
- Check Call State: Verify an active AI call exists before sending messages
- User Feedback: Provide visual feedback when messages are sent
- Error Handling: Handle network errors and call state issues gracefully
- UI Updates: Update the conversation UI immediately for better user experience
Integration with Transcript Updates
Text messages will appear in the transcript flow:
lifecycleScope.launch {
telnyxClient.transcriptUpdateFlow.collect { transcript ->
transcript.forEach { item ->
when (item.role) {
TranscriptItem.ROLE_USER -> {
// This includes both spoken words and text messages
displayUserMessage(item.content, item.timestamp)
}
TranscriptItem.ROLE_ASSISTANT -> {
// AI responses to both voice and text
displayAssistantMessage(item.content, item.timestamp)
}
}
}
}
}
This feature enables rich conversational experiences where users can seamlessly switch between voice and text communication with the AI Assistant.