|
GRUPOS DE DISCUSSÃO PROFISSIONAL WINDEV, WEBDEV e WINDEV Mobile |
| | | | | |
Inicio → WINDEV 25 → Classe WX Send SMS v5 (Windev, Webdev e Windev Mobile) |
Classe WX Send SMS v5 (Windev, Webdev e Windev Mobile) |
Iniciado por Boller, jun., 21 2025 4:18 PM - Sem resposta |
| |
| | | |
|
| |
Membro registado 4.520 mensagems |
|
Publicado em junho, 21 2025 - 4:18 PM |
Bom dia
Segue abaixo a ClasseWxSendSMS_v5
//############################## // CLASSE WX SEND SMS v5.0 - TÉCNICAS AVANÇADAS WLANGUAGE // Autor: Adriano - Seguindo Diretivas WX // Data: 21/06/2025 // Recursos: EvaluateExpression + Indirection + Operadores Ternários //##############################
// Estrutura avançada com configuração dinâmica t001_sms_message_v5 is Structure t001_id is string // ID único da mensagem t001_phone_number is string // Número de telefone destino t001_message_text is string // Texto da mensagem t001_provider_name is string // Nome do provedor t001_status is string // Status atual t001_sent_date is DateTime // Data/hora do envio t001_delivery_date is DateTime // Data/hora da entrega t001_error_message is string // Mensagem de erro t001_cost is real // Custo do envio t001_segments is int // Número de segmentos t001_priority is int // Prioridade t001_retry_count is int // Contador de tentativas t001_external_id is string // ID do provedor externo t001_queue_id is string // ID da fila t001_metadata is string // JSON com metadados dinâmicos t001_validation_rules is string // Regras de validação dinâmicas t001_routing_expression is string // Expressão para roteamento END
// Estrutura de configuração dinâmica dos provedores t002_sms_provider_v5 is Structure t002_provider_id is string // ID do provedor t002_provider_name is string // Nome amigável t002_api_config is string // JSON com configuração da API t002_validation_expression is string // Expressão de validação t002_routing_weight is real // Peso para roteamento (0.0-1.0) t002_is_active is boolean // Provedor ativo t002_priority_expression is string // Expressão para calcular prioridade t002_cost_formula is string // Fórmula para calcular custo t002_rate_limit_config is string // Configuração de rate limiting t002_failover_rules is string // Regras de failover t002_dynamic_headers is string // Headers dinâmicos (JSON) t002_response_parser is string // Parser de resposta customizado END
// Estrutura de resposta avançada t003_sms_response_v5 is Structure t003_success is boolean // Sucesso da operação t003_message_id is string // ID da mensagem t003_external_id is string // ID do provedor t003_status is string // Status retornado t003_error_code is string // Código de erro t003_error_message is string // Mensagem de erro t003_cost is real // Custo calculado t003_segments is int // Segmentos utilizados t003_provider_used is string // Provedor utilizado t003_response_time is int // Tempo de resposta em ms t003_metadata is string // Metadados da resposta (JSON) t003_routing_decision is string // Decisão de roteamento tomada t003_validation_results is string // Resultados das validações END
// Classe principal SMS v5 com técnicas avançadas ClasseWxSendSMS_v5 is Class // Propriedades privadas usando arrays associativos para flexibilidade m_providers is associative array of t002_sms_provider_v5 // Provedores indexados por ID m_config_cache is associative array of string // Cache de configurações m_validation_cache is associative array of boolean // Cache de validações m_routing_rules is associative array of string // Regras de roteamento m_dynamic_properties is associative array of Variant // Propriedades dinâmicas m_expression_cache is associative array of Variant // Cache de expressões avaliadas // Configurações avançadas m_debug_mode is boolean = False m_auto_failover is boolean = True m_smart_routing is boolean = True m_cache_enabled is boolean = True m_expression_timeout is int = 5000 // Timeout para expressões (ms) // Constantes avançadas usando operadores ternários CONSTANT SMS_STATUS_PENDING = "PENDING" SMS_STATUS_SENT = "SENT" SMS_STATUS_DELIVERED = "DELIVERED" SMS_STATUS_FAILED = "FAILED" PROVIDER_TWILIO = "TWILIO" PROVIDER_ZENVIA = "ZENVIA" PROVIDER_AWS_SNS = "AWS_SNS" PROVIDER_NEXMO = "NEXMO" PROVIDER_MESSAGEBIRD = "MESSAGEBIRD" PROVIDER_CLICKSEND = "CLICKSEND" PROVIDER_PLIVO = "PLIVO" PRIORITY_CRITICAL = 0 PRIORITY_HIGH = 1 PRIORITY_NORMAL = 2 PRIORITY_LOW = 3 PRIORITY_BULK = 4 ROUTING_ROUND_ROBIN = "ROUND_ROBIN" ROUTING_COST_OPTIMIZED = "COST_OPTIMIZED" ROUTING_PERFORMANCE = "PERFORMANCE" ROUTING_SMART = "SMART" ROUTING_CUSTOM = "CUSTOM" END END
// Construtor avançado com inicialização dinâmica Procedure Constructor() // Inicializar propriedades usando operadores ternários m_debug_mode = (fFileExist(fCurrentDir() + "\debug.flag") ? True : False) m_auto_failover = (GetEnvironmentVariable("SMS_AUTO_FAILOVER") = "false" ? False : True) m_smart_routing = (GetEnvironmentVariable("SMS_SMART_ROUTING") = "false" ? False : True) m_cache_enabled = (GetEnvironmentVariable("SMS_CACHE_ENABLED") = "false" ? False : True) // Configurar propriedades dinâmicas usando Indirection {m_dynamic_properties, "log_file"} = fCurrentDir() + "\logs\sms_v5.log" {m_dynamic_properties, "thread_pool_size"} = 10 {m_dynamic_properties, "max_concurrent_sends"} = 50 {m_dynamic_properties, "retry_delay"} = 2000 {m_dynamic_properties, "default_timeout"} = 30 // Inicializar cache de configurações InitializeConfigurationCache() // Carregar provedores usando configuração dinâmica LoadProvidersFromConfiguration() // Log de inicialização usando EvaluateExpression log_message is string = EvaluateExpression([ "ClasseWxSendSMS_v5 inicializada - Debug: " + (m_debug_mode ? "ON" : "OFF") + ", Failover: " + (m_auto_failover ? "ON" : "OFF") + ", Smart Routing: " + (m_smart_routing ? "ON" : "OFF") ]) LogAdvanced(log_message, "INIT") END
// Procedure para inicializar cache de configurações usando Indirection Procedure InitializeConfigurationCache() config_keys is array of string = [ "twilio_base_url", "zenvia_base_url", "aws_sns_region", "nexmo_base_url", "messagebird_base_url", "clicksend_base_url", "plivo_base_url", "default_sender_id", "max_message_length", "unicode_support", "rate_limit_global", "cost_threshold", "performance_threshold" ] // Usar Indirection para configurar valores padrão FOR i = 1 TO ArrayCount(config_keys) config_key is string = config_keys[i] default_value is string = GetDefaultConfigValue(config_key) // Indirection para acessar cache dinamicamente {m_config_cache, config_key} = default_value END//For LogAdvanced("Cache de configuração inicializado com " + ArrayCount(config_keys) + " chaves", "CONFIG") END
// Procedure para obter valor padrão de configuração usando operadores ternários Procedure GetDefaultConfigValue(config_key is string) : string // Usar operadores ternários para configurações condicionais SWITCH config_key CASE "twilio_base_url" Result "https://api.twilio.com/2010-04-01/Accounts/" CASE "zenvia_base_url" Result "https://api.zenvia.com/v2/channels/sms/messages" CASE "aws_sns_region" Result (GetEnvironmentVariable("AWS_REGION") <> "" ? GetEnvironmentVariable("AWS_REGION") : "us-east-1") CASE "default_sender_id" Result (GetEnvironmentVariable("SMS_SENDER_ID") <> "" ? GetEnvironmentVariable("SMS_SENDER_ID") : "SMS_SYSTEM") CASE "max_message_length" Result "1600" // 10 segmentos padrão CASE "unicode_support" Result "true" CASE "rate_limit_global" Result "100" // 100 SMS por minuto CASE "cost_threshold" Result "0.10" // R$ 0.10 por SMS CASE "performance_threshold" Result "2000" // 2 segundos OTHER CASE Result "" END END
// Procedure para carregar provedores usando configuração dinâmica Procedure LoadProvidersFromConfiguration() provider_configs is array of string = [ "TWILIO", "ZENVIA", "AWS_SNS", "NEXMO", "MESSAGEBIRD", "CLICKSEND", "PLIVO" ] FOR i = 1 TO ArrayCount(provider_configs) provider_id is string = provider_configs[i] // Usar EvaluateExpression para verificar se provedor deve ser carregado should_load is boolean = EvaluateExpression([ GetEnvironmentVariable("SMS_ENABLE_" + provider_id) <> "false" AND GetEnvironmentVariable("SMS_API_KEY_" + provider_id) <> "" ]) IF should_load LoadProviderConfiguration(provider_id) END//If END//For LogAdvanced("Provedores carregados: " + ArrayCount(m_providers), "CONFIG") END
// Procedure para carregar configuração de um provedor específico Procedure LoadProviderConfiguration(provider_id is string) provider is t002_sms_provider_v5 // Configuração básica provider.t002_provider_id = provider_id provider.t002_provider_name = GetProviderDisplayName(provider_id) // Usar Indirection para acessar configurações dinamicamente api_key_env is string = "SMS_API_KEY_" + provider_id api_secret_env is string = "SMS_API_SECRET_" + provider_id sender_id_env is string = "SMS_SENDER_ID_" + provider_id // Configuração da API usando JSON dinâmico api_config is string = StringBuild([ { "api_key": "%1", "api_secret": "%2", "sender_id": "%3", "base_url": "%4", "timeout": %5, "max_retries": %6 }], GetEnvironmentVariable(api_key_env), GetEnvironmentVariable(api_secret_env), (GetEnvironmentVariable(sender_id_env) <> "" ? GetEnvironmentVariable(sender_id_env) : {m_config_cache, "default_sender_id"}), {m_config_cache, Lower(provider_id) + "_base_url"}, 30, 3) provider.t002_api_config = api_config // Expressões dinâmicas usando EvaluateExpression provider.t002_validation_expression = GetProviderValidationExpression(provider_id) provider.t002_priority_expression = GetProviderPriorityExpression(provider_id) provider.t002_cost_formula = GetProviderCostFormula(provider_id) // Configurações avançadas provider.t002_routing_weight = GetProviderRoutingWeight(provider_id) provider.t002_is_active = True provider.t002_rate_limit_config = GetProviderRateLimitConfig(provider_id) provider.t002_failover_rules = GetProviderFailoverRules(provider_id) // Adicionar ao array associativo usando Indirection {m_providers, provider_id} = provider LogAdvanced("Provedor " + provider_id + " configurado com sucesso", "CONFIG") END
// Procedure para obter nome de exibição do provedor usando operadores ternários Procedure GetProviderDisplayName(provider_id is string) : string Result (provider_id = "TWILIO" ? "Twilio SMS" : (provider_id = "ZENVIA" ? "Zenvia Brasil" : (provider_id = "AWS_SNS" ? "Amazon SNS" : (provider_id = "NEXMO" ? "Vonage (Nexmo)" : (provider_id = "MESSAGEBIRD" ? "MessageBird" : (provider_id = "CLICKSEND" ? "ClickSend" : (provider_id = "PLIVO" ? "Plivo SMS" : provider_id))))))) END
// Procedure para obter expressão de validação do provedor Procedure GetProviderValidationExpression(provider_id is string) : string // Expressões customizadas por provedor usando EvaluateExpression SWITCH provider_id CASE "TWILIO" Result [Length(phone_number) >= 10 AND Left(phone_number, 1) = "+" AND Length(message_text) <= 1600] CASE "ZENVIA" Result [MatchRegularExpression(phone_number, "^\\+55[0-9]{10,11}$") AND Length(message_text) <= 4096] CASE "AWS_SNS" Result [Length(phone_number) >= 10 AND Length(message_text) <= 1600] OTHER CASE Result [Length(phone_number) >= 10 AND Length(message_text) <= 1600 AND Length(message_text) > 0] END END
// Procedure para obter expressão de prioridade do provedor Procedure GetProviderPriorityExpression(provider_id is string) : string // Prioridade dinâmica baseada em performance e custo SWITCH provider_id CASE "TWILIO" Result [(response_time < 1000 ? 1 : 2) + (cost < 0.01 ? 0 : 1)] CASE "ZENVIA" Result [(response_time < 2000 ? 1 : 3) + (cost < 0.05 ? 0 : 2)] OTHER CASE Result [2 + (response_time > 3000 ? 2 : 0) + (cost > 0.02 ? 1 : 0)] END END
// Procedure para obter fórmula de custo do provedor Procedure GetProviderCostFormula(provider_id is string) : string // Fórmulas de custo dinâmicas SWITCH provider_id CASE "TWILIO" Result [segments * 0.0075 * (priority = 0 ? 1.5 : 1.0)] CASE "ZENVIA" Result [segments * 0.05 * (Length(message_text) > 160 ? 1.2 : 1.0)] CASE "AWS_SNS" Result [segments * 0.006 * (region = "us-east-1" ? 1.0 : 1.1)] OTHER CASE Result [segments * 0.01] END END
// Procedure para obter peso de roteamento usando operadores ternários Procedure GetProviderRoutingWeight(provider_id is string) : real // Pesos baseados em confiabilidade e performance Result (provider_id = "TWILIO" ? 0.9 : (provider_id = "ZENVIA" ? 0.8 : (provider_id = "AWS_SNS" ? 0.85 : (provider_id = "NEXMO" ? 0.75 : (provider_id = "MESSAGEBIRD" ? 0.7 : (provider_id = "CLICKSEND" ? 0.65 : (provider_id = "PLIVO" ? 0.7 : 0.5))))))) END
// Procedure para configuração de rate limiting Procedure GetProviderRateLimitConfig(provider_id is string) : string // Configuração JSON para rate limiting SWITCH provider_id CASE "TWILIO" Result [{"requests_per_second": 10, "burst_limit": 50, "window_size": 60}] CASE "ZENVIA" Result [{"requests_per_second": 5, "burst_limit": 25, "window_size": 60}] OTHER CASE Result [{"requests_per_second": 3, "burst_limit": 15, "window_size": 60}] END END
// Procedure para regras de failover Procedure GetProviderFailoverRules(provider_id is string) : string // Regras de failover em JSON Result StringBuild([ { "max_consecutive_failures": %1, "failure_window_minutes": %2, "recovery_test_interval": %3, "fallback_providers": %4 }], (provider_id = "TWILIO" ? 3 : 5), (provider_id = "ZENVIA" ? 10 : 15), (provider_id = "AWS_SNS" ? 5 : 10), GetFallbackProviders(provider_id)) END
// Procedure para obter provedores de fallback Procedure GetFallbackProviders(provider_id is string) : string // Lista de fallback baseada no provedor principal SWITCH provider_id CASE "TWILIO" Result [["ZENVIA", "AWS_SNS", "NEXMO"]] CASE "ZENVIA" Result [["TWILIO", "PLIVO", "CLICKSEND"]] CASE "AWS_SNS" Result [["TWILIO", "MESSAGEBIRD", "NEXMO"]] OTHER CASE Result [["TWILIO", "ZENVIA"]] END END
// Procedure de log avançado usando Indirection Procedure LogAdvanced(message is string, level is string = "INFO") timestamp is string = DateTimeToString(DateTimeSys(), "YYYY-MM-DD HH:MM:SS.CCC") log_entry is string = StringBuild("[%1] [%2] %3", timestamp, level, message) // Usar Indirection para acessar arquivo de log dinamicamente log_file is string = {m_dynamic_properties, "log_file"} // Escrever no arquivo usando operador ternário para verificação (fDirectoryExist(fExtractPath(log_file)) ? True : fMakeDir(fExtractPath(log_file))) fWriteLine(log_file, log_entry) // Debug usando operador ternário (m_debug_mode ? Trace(log_entry) : Null) END
// Procedure para configurar propriedade dinâmica usando Indirection Procedure SetDynamicProperty(property_name is string, property_value is Variant) // Usar Indirection para acesso dinâmico {m_dynamic_properties, property_name} = property_value LogAdvanced(StringBuild("Propriedade dinâmica '%1' configurada", property_name), "CONFIG") END
// Procedure para obter propriedade dinâmica usando Indirection Procedure GetDynamicProperty(property_name is string, default_value is Variant = Null) : Variant // Usar operador ternário com Indirection Result ({m_dynamic_properties, property_name} <> Null ? {m_dynamic_properties, property_name} : default_value) END
// Procedure para validação avançada usando EvaluateExpression Procedure ValidateMessageAdvanced(phone_number is string, message_text is string, provider_id is string = "") : boolean // Cache de validação usando Indirection cache_key is string = MD5(phone_number + "|" + message_text + "|" + provider_id) // Verificar cache primeiro usando operador ternário IF m_cache_enabled AND {m_validation_cache, cache_key} <> Null Result {m_validation_cache, cache_key} END//If // Validação básica usando EvaluateExpression basic_validation is string = [ Length(Trim(phone_number)) >= 10 AND Length(Trim(message_text)) > 0 AND Length(message_text) <= 4096 AND MatchRegularExpression(phone_number, "^\\+?[0-9\\s\\-\\(\\)]+$") ] is_valid is boolean = EvaluateExpression(basic_validation) // Validação específica do provedor se especificado IF is_valid AND provider_id <> "" AND {m_providers, provider_id} <> Null provider_validation is string = {m_providers, provider_id}.t002_validation_expression // Substituir variáveis na expressão provider_validation = Replace(provider_validation, "phone_number", "\"" + phone_number + "\"") provider_validation = Replace(provider_validation, "message_text", "\"" + message_text + "\"") is_valid = is_valid AND EvaluateExpression(provider_validation) END//If // Armazenar no cache usando Indirection IF m_cache_enabled {m_validation_cache, cache_key} = is_valid END//If Result is_valid END
//Final do Arquivo
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianoboller http://wxinformatica.com.br/ |
| |
| |
| | | |
|
| | | | |
| | |
| | |
| |
|
|
|