TInstinct
source/classes/tinstinct.prg
Prototype email transport for an application to talk to its user's own Instinct. This is not an official API. A separately configured receiver is required; sending email does not authorize actions.
Configuration
cFrom: Application sender mailbox.cToken: Shared secret agreed through a secure means; keep it out of source code.cTo: The user's assistant mailbox. Ask the assistant for its address; there is no default destination.
Only a local relay (127.0.0.1 or localhost) is accepted. The external hop must use TLS and validate certificates. Default ports are SMTP 25 and POP 110; override nSmtpPort and nPopPort as needed. Set cPopUser/cPopPassword for a dedicated reply mailbox.
Examples
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() waits and blocks. OnAnswer() registers a callback; Pump() polls once from a timer, but the connection can take up to nTimeout. It does not start a background thread.
samples/instinct/tinstinct.prg: INSTINCT_FROM, INSTINCT_TOKEN, INSTINCT_TO, INSTINCT_POP_USER, INSTINCT_POP_PASSWORD.
State and limits
cError: last error.cLog: activity log.SaveLog( cFile ): save the log.Send( cText, cId ): .T. means relay acceptance, not delivery. Do not retry blindly after a final timeout.ParseReply( cRaw, cExpectedId ): validates simple text/plain MIME, complete JSON and id/text types. Parsing does not authenticate the sender.PollOnce( nLimit ): new replies, up to 20 messages by default (1..100). UIDL state is stored incUidlFile; no messages are deleted. Archive processed mail in the dedicated mailbox.nMaxBytes: 1048576.nTimeout: 5000 ms.Answer( nSeconds, cId ): 1..3600 seconds, default 30.
The limit counts unprocessed messages, not the first mailbox positions: seen UIDLs are skipped and later calls reach the remaining mail. Answer() retains other-ID replies in aPending for another Answer() or Pump(). That queue lives in the instance; use one instance per mailbox and drain it before closing. Mail is kept on the server: archive processed mail to avoid long scans.