Message Processing
The message processing system analyzes customer conversation history and candidate responses to provide AI-enhanced communication recommendations.
Core Concepts
- Message History
A chronological sequence of customer messages leading up to the current interaction.
- Candidate Message
Your proposed response to the customer’s messages.
- Processing
The AI system analyzes context, sentiment, and intent to enhance your response.
- Optimization
Further refinement of messages for maximum customer engagement.
Basic Message Processing
from apala_client import ApalaClient, Message
client = ApalaClient(api_key="your-key")
client.authenticate()
# Customer conversation history
messages = [
Message(
content="I'm looking for a mortgage refinance",
channel="EMAIL",
reply_or_not=False
),
Message(
content="My current rate is 4.5% and I have excellent credit",
channel="EMAIL",
reply_or_not=False
)
]
# Your candidate response
candidate = Message(
content="With excellent credit, you could qualify for rates as low as 3.1%. Let me run some numbers for you.",
channel="EMAIL"
)
# Process through AI system
response = client.message_process(
message_history=messages,
candidate_message=candidate,
customer_id="550e8400-e29b-41d4-a716-446655440000",
zip_code="90210",
company_guid="company-uuid-here"
)
# Access results
processed_msg = response["candidate_message"]
print(f"Processed message ID: {processed_msg['message_id']}")
print(f"Enhanced content: {processed_msg['content']}")
Message Types and Channels
- Supported Channels
"SMS": Text message communication"EMAIL": Email communication"OTHER": Any other communication channel
- Channel-Specific Optimization
The AI adjusts message style based on channel:
# SMS - concise and direct sms_msg = Message( content="Hi! Ready to discuss loan options?", channel="SMS" ) # EMAIL - more detailed and formal email_msg = Message( content="Thank you for your inquiry. I'd be happy to discuss our competitive loan options and help you find the perfect solution.", channel="EMAIL" )
Advanced Processing Workflows
- Multi-Turn Conversations
Handle complex conversation flows:
def process_conversation_chain(client, conversation_data): """Process a multi-turn conversation.""" all_messages = [] responses = [] for turn in conversation_data["turns"]: # Add customer messages to history customer_msg = Message( content=turn["customer_content"], channel=turn["channel"], reply_or_not=False ) all_messages.append(customer_msg) # Process with full history candidate = Message( content=turn["candidate_response"], channel=turn["channel"] ) response = client.message_process( message_history=all_messages.copy(), candidate_message=candidate, customer_id=conversation_data["customer_id"], zip_code=conversation_data["zip_code"], company_guid=conversation_data["company_guid"] ) responses.append(response) # Add processed response to history for next turn response_msg = Message( content=response["candidate_message"]["content"], channel=response["candidate_message"]["channel"], message_id=response["candidate_message"]["message_id"], reply_or_not=True ) all_messages.append(response_msg) return responses
- Batch Processing
Process multiple conversations efficiently:
import concurrent.futures from typing import List, Dict def batch_process_messages( client: ApalaClient, conversations: List[Dict], max_workers: int = 5 ) -> List[Dict]: """Process multiple conversations in parallel.""" def process_single(conv_data): try: return client.message_process( message_history=conv_data["messages"], candidate_message=conv_data["candidate"], customer_id=conv_data["customer_id"], zip_code=conv_data["zip_code"], company_guid=conv_data["company_guid"] ) except Exception as e: return {"error": str(e), "conversation_id": conv_data.get("id")} with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor: results = list(executor.map(process_single, conversations)) return results
Message Optimization
Optimize messages for better customer engagement:
# Get optimized version of your message
optimization = client.optimize_message(
message_history=messages,
candidate_message=candidate,
customer_id="customer-uuid",
zip_code="90210",
company_guid="company-uuid"
)
print("=== Optimization Results ===")
print(f"Original: {optimization['original_message']}")
print(f"Optimized: {optimization['optimized_message']}")
print(f"Recommended Channel: {optimization['recommended_channel']}")
- A/B Testing with Optimization
Compare original vs optimized messages:
def ab_test_messages(client, message_data): """Run A/B test comparing original vs optimized messages.""" # Process original message original_response = client.message_process(**message_data) # Get optimized version optimization = client.optimize_message(**message_data) # Create optimized candidate optimized_candidate = Message( content=optimization["optimized_message"], channel=optimization["recommended_channel"] ) # Process optimized message optimized_data = message_data.copy() optimized_data["candidate_message"] = optimized_candidate optimized_response = client.message_process(**optimized_data) return { "original": original_response, "optimized": optimized_response, "optimization_suggestions": optimization }
Context and Personalization
- Customer Context
Use customer data for personalized responses:
def create_personalized_message(customer_profile, base_message): """Create personalized message based on customer profile.""" # Customize based on customer data if customer_profile.get("credit_score", 0) > 750: tone = "Our premium rates for excellent credit customers" elif customer_profile.get("first_time_buyer"): tone = "First-time buyer programs and guidance" else: tone = "Competitive rates and flexible terms" personalized_content = f"{base_message} {tone}" return Message( content=personalized_content, channel=customer_profile.get("preferred_channel", "EMAIL") )
- Geographic Personalization
Leverage zip code data:
# ZIP code influences processing high_cost_areas = ["90210", "10001", "94102"] # CA, NY examples if zip_code in high_cost_areas: candidate_content = "Our jumbo loan programs offer competitive rates for high-value properties in your area." else: candidate_content = "Our conventional loan programs offer great rates for properties in your market."
Error Handling and Validation
- Input Validation
The SDK automatically validates inputs:
try: response = client.message_process( message_history=messages, candidate_message=candidate, customer_id="invalid-uuid", # Will raise ValueError zip_code="123", # Will raise ValueError company_guid="company-uuid" ) except ValueError as e: print(f"Validation error: {e}")
- Processing Errors
Handle API errors gracefully:
import requests import time def robust_message_processing(client, message_data, max_retries=3): """Process message with retry logic.""" for attempt in range(max_retries): try: return client.message_process(**message_data) except requests.HTTPError as e: if e.response.status_code == 429: # Rate limited wait_time = 2 ** attempt print(f"Rate limited, waiting {wait_time}s...") time.sleep(wait_time) elif e.response.status_code >= 500: # Server error print(f"Server error on attempt {attempt + 1}") if attempt < max_retries - 1: time.sleep(1) else: raise # Don't retry client errors except requests.ConnectionError: print(f"Connection error on attempt {attempt + 1}") if attempt < max_retries - 1: time.sleep(2 ** attempt) raise Exception(f"Processing failed after {max_retries} attempts")
Performance Optimization
- Session Reuse
Reuse client instances for better performance:
# Good: Reuse client client = ApalaClient(api_key="key") client.authenticate() for conversation in conversations: response = client.message_process(**conversation) client.close() # Bad: Create new client each time for conversation in conversations: client = ApalaClient(api_key="key") # Wasteful client.authenticate() response = client.message_process(**conversation) client.close()
- Request Batching
Group related requests when possible:
def process_customer_workflow(client, customer_data): """Process multiple steps for a single customer efficiently.""" # Step 1: Process initial message response = client.message_process(**customer_data["initial"]) # Step 2: Optimize the same message optimization = client.optimize_message(**customer_data["initial"]) # Step 3: Process follow-up if needed if customer_data.get("followup"): followup_response = client.message_process(**customer_data["followup"]) return response, optimization, followup_response return response, optimization
Best Practices
- Message Quality
Provide clear, natural conversation history
Write candidate responses in your authentic voice
Include relevant context in message history
Use appropriate channels for message types
- Performance
Reuse authenticated client instances
Implement appropriate retry logic
Use batch processing for multiple conversations
Cache optimization results when applicable
- Error Handling
Always validate inputs before processing
Handle network errors gracefully
Log processing events for debugging
Implement circuit breaker patterns for high-volume usage
- Data Management
Store message IDs for feedback tracking
Maintain conversation history for context
Track processing metrics for optimization
Implement data retention policies as needed