TInstinct
source/classes/tinstinct.prg
Protótipo de transporte por email para uma aplicação falar com o Instinct do seu próprio utilizador. Não é uma API oficial. Requer um receptor configurado separadamente; enviar email não autoriza ações.
Configuração
cFrom: Caixa de email remetente da aplicação.cToken: Segredo partilhado acordado por um meio seguro; não o escreva no código.cTo: Caixa de email do assistente do utilizador. Pergunte-lhe o endereço; não há destino predefinido.
Só aceita um relay local (127.0.0.1 ou localhost). O salto externo deve usar TLS e validar certificados. As portas predefinidas são SMTP 25 e POP 110; use nSmtpPort e nPopPort para alterá-las. Configure cPopUser/cPopPassword para uma caixa dedicada às respostas.
Exemplos
oInstinct := TInstinct():New( cFrom, cToken, cTo )
if oInstinct:Send( "Hello Instinct" )
cAnswer := oInstinct:Answer( 10 )
endif
// Register once, then call Pump() from the application's timer:
oInstinct:OnAnswer( {| cText, cId | MsgInfo( cText, cId ) } )
oInstinct:Pump()
Answer() espera e bloqueia. OnAnswer() regista o bloco; Pump() consulta uma vez a partir de um timer, mas a ligação pode demorar até nTimeout. Não cria uma thread em segundo plano.
samples/instinct/tinstinct.prg: INSTINCT_FROM, INSTINCT_TOKEN, INSTINCT_TO, INSTINCT_POP_USER, INSTINCT_POP_PASSWORD.
Estado e limites
cError: último erro.cLog: registo de atividade.SaveLog( cFile ): guarda o registo.Send( cText, cId ): .T. significa aceitação pelo relay, não entrega. Não repita às cegas após um timeout final.ParseReply( cRaw, cExpectedId ): valida MIME simples text/plain, JSON completo e tipos id/text. A análise não autentica o remetente.PollOnce( nLimit ): respostas novas, até 20 mensagens por predefinição (1..100). O estado UIDL é guardado emcUidlFile; não elimina mensagens. Arquive o email tratado na caixa dedicada.nMaxBytes: 1048576.nTimeout: 5000 ms.Answer( nSeconds, cId ): 1..3600 segundos, predefinição 30.
O limite conta mensagens não tratadas, não as primeiras posições da caixa: os UIDL já vistos são ignorados e as chamadas seguintes chegam ao restante email. Answer() conserva respostas de outros IDs em aPending para outro Answer() ou Pump(). A fila vive na instância; use uma única instância por caixa e consuma-a antes de fechar. O email fica no servidor: arquive o tratado para evitar consultas longas.