i'am building standalone app based on Sarah Reichelts smtp library but now i'am facing the problem then i want to send email with Lithuanian symbols like (ąčęėįšųūž). Then i receive an email it not recognizing Lithuanian chars and displays ???. My source code:
Code: Select all
on mouseUp
start using stack "sSMTPlibrary1"
sSMTPconnectToServer mail.kggroup.eu, "sendEmails"
/*
disable me
disable btn "Uždaryti"
disable btn "Kategorija ComboBox"
disable btn "Subkategorija ComboBox"
disable field "Tekstas"
disable btn "Padaryti nuotrauką"
*/
end mouseUp
on sendEmails pState
put the label of btn "Kategorija ComboBox" into pasirinkimasKategorija
put the label of btn "Subkategorija ComboBox" into pasirinkimasSubkategorija
put the text of field "Tekstas" into incidentoTekstas
put "<topdesk>" & cr & "<incident>" & cr & "<callerlogin>nvappsrv</callerlogin>" & cr & "<category>" & pasirinkimasKategorija & "</category> <subcategory>" & pasirinkimasSubkategorija & "</subcategory> <request> <![CDATA[ " &\
incidentoTekstas & cr & "Hostname:" & the hostName & cr & "]]>" & cr & "</request>" & cr & "</incident>" & cr & "</topdesk>" into test
--Pirmas nurodytas el. pašto adresas yra gavėjo adresas, antras el. pašto adresas yra deklaruotinas siuntėjo adresas (realiai siuntejas gali buti betkas@kggroup.eu)
sSMTPsendMessage , z.girdauskas@kggroup.eu,, sSMTPbuildEmailText(z.girdauskas@kggroup.eu,, nfc_tag, \
test), "messageSent"
sSMTPsetTranscriptField the long name of fld "Log", transcriptSet
sSMTPsetStatusField the long name of fld "Status"
answer pasirinkimasSubkategorija, pasirinkimasKategorija
-- end if
end sendEmails
on messageSent pState
if pState <> "OK" then answer "Klaida registruojant incidentą: " & pState
sSMTPdisconnectFromServer
enable me
end messageSent
Code: Select all
--> all handlers
local sConnectOK, sSocketAddr, sSmtpUser, sSmtpPass, sAuthNeeded
local transcriptPlain, transcriptVerbose
local callBackHandler, callBackTarget
local transcriptField, transcriptType, statusField
-- connect to SMTP server, authenticating if necessary
-- and return to the callback function
--
on sSMTPconnectToServer pServer, pCallBack, pUseAuth, pUser, pPass
sSMTPshowStatus "Connecting to SMTP server..."
put false into sConnectOK
put empty into transcriptPlain
put empty into transcriptVerbose
put pCallBack into callBackHandler
put the long name of the target into callBackTarget
if pUser is not empty and pPass is not empty and pUseAuth = true then
put true into sAuthNeeded
put pUser into sSmtpUser
put pPass into sSmtpPass
else
put false into sAuthNeeded
end if
-- close any open sockets - resetAll if there are any problems
repeat until the opensockets is empty
close socket line 1 of the opensockets
if the result is not empty then
resetAll
exit repeat
end if
end repeat
-- get account address & convert to numeric IP address
-- hostnameToAddress function just returns the number
-- if the entered server was already a number, so either will work
-- hostnameToAddress() may return more than one line, so just pick a random one
put any line of hostnametoaddress(pServer) into smtpServer
if smtpServer is empty then
sSMTPaddToTranscript "SMTPerror" && smtpServer & " could not be found", "all"
sSMTPshowStatus ""
sSMTPexitSMTP "noconnect"
end if
-- set up timeout check in case connection fails
set the sockettimeoutinterval to 20000 -- 20 seconds
send "sSMTPcheckTimeout" to me in 10 seconds
-- open SMTP port, using port number 25 if no port number has been specified
if smtpServer contains ":" is false then put ":25" after smtpServer
put smtpServer into sSocketAddr
open socket to sSocketAddr with message "sSMTPsocketConnected"
if the result is not empty then
sSMTPaddToTranscript "SMTPerror can't make connection to " & sSocketAddr, "all"
put empty into sSocketAddr
sSMTPexitSMTP "noconnect"
end if
end sSMTPconnectToServer
function sSMTPbuildEmailText pSender, pRecip, pSubject, pBody, pAttach, pUseHTML
-- if pUseHTML is true, pBody will contain htmlText only (no plain text)
sSMTPshowStatus "Constructing email: " & pSubject
put empty into emailText
if pUseHTML = true or pAttach is not empty then
-- multipart divider headers
put "_NextPart_" & the seconds & "." & the ticks into partMarker
put "_NextPart_" & the seconds+1 & "." & the ticks into partMarker2
if pUseHTML = true then
put "Content-Type: multipart/alternative; boundary=" & partMarker & CRLF into attachHeaders
put "Content-Type: multipart/mixed; boundary=" & partMarker2 & CRLF into tExtraHeader
else
put "Content-Type: multipart/mixed; boundary=" & partMarker & CRLF into attachHeaders
put empty into tExtraHeader
end if
put "" & CRLF after attachHeaders
put "This is a multipart message in MIME format." & CRLF after attachHeaders
put "" & CRLF after attachHeaders
put "--" & partMarker & CRLF after attachHeaders
else
put empty into attachHeaders
end if
repeat for each line L in pRecip
if L is empty then next repeat
put "To: " & L & CRLF after toHeaders
end repeat
put "Mime-Version: 1.0" & CRLF after emailText
put "X-Mailer: sSMTPlibrary1 (" & the cVersionNum of stack "sSMTPlibrary1" & ")" & CRLF after emailText
put toHeaders after emailText
put "From: " & pSender & CRLF after emailText
put "Subject: " & pSubject & CRLF after emailText
put "Date: " & the internet date & CRLF after emailText
put attachHeaders after emailText
-- if using HTML text, assemble the plain text form & the html form with the appropriate dividers
if pUseHTML = true then
-- plain text
put "Content-Type: text/plain; charset=US-ASCII; format=flowed" & cr after tNewBody
put "Content-Transfer-Encoding: 7bit" & cr & cr after tNewBody
set the htmltext of the templatefield to pBody
put the text of the templatefield into tPlain
put tPlain & cr after tNewBody
if pAttach is not empty then
-- indicate switching from alternative to mixed, with change of part marker
put cr & cr & "--" & partMarker & cr after tNewBody
put tExtraHeader & cr & cr after tNewBody
put partMarker2 into partMarker
end if
-- formatted text
put cr & cr & "--" & partMarker & cr after tNewBody
put "Content-Type: text/html; charset=US-ASCII" & cr after tNewBody
put "Content-Transfer-Encoding: 7bit" & cr & cr after tNewBody
if char 1 to 6 of pBody <> "<html>" then put "<html>" before pBody
if char -7 to -1 of pBody <> "</html>" then put "</html>" after pBody
put pBody & cr after tNewBody
put tNewBody into pBody
else
put "Content-Type: text/plain; charset=US-ASCII" & CRLF after emailText
put "Content-Transfer-Encoding: 7bit" & CRLF after emailText
put "" & CRLF after emailText
end if
-- period is the terminating character, so make sure it doesn't occur singly
repeat for each line L in pBody
if char 1 of L = "." then put "." & L & CRLF after emailText
else put L & CRLF after emailText
end repeat
repeat for each line L in pAttach
put "" & CRLF after emailText
put CRLF & "--" & partMarker & CRLF after emailText
set the itemdel to "/"
put last item of L into shortName
set the itemdel to comma
put "Content-Disposition: attachment; filename=" & quote & shortName & quote & CRLF after emailText
put "Content-Transfer-Encoding: base64" & CRLF after emailText
put "Content-Type: application/octet-stream; name=" & quote & shortName & quote & CRLF after emailText
put "" & CRLF after emailText
open file L for binary read
read from file L until EOF
put base64encode(it) after emailText
close file L
end repeat
if pAttach is not empty then put "" & CRLF & "--" & partMarker after emailText
put "" & CRLF after emailText
return emailText
end sSMTPbuildEmailText
on sSMTPsendMessage pSender, pRecip, pSubject, pBody, pCallback, pAttach
sSMTPshowStatus "Sending email: " & pSubject
put pCallBack into callBackHandler
put the long name of the target into callBackTarget
-- check that email text has been formatted OK
if pBody contains "Content-Type:" is false then
sSMTPexitSMTP "TextNotFormatted"
end if
sSMTPsendReceive "MAIL FROM: <" & sSMTPextractEmail(pSender) & ">"
repeat for each line L in pRecip
if L is empty then next repeat
sSMTPsendReceive "RCPT TO: <" & sSMTPextractEmail(L) & ">"
end repeat
sSMTPsendReceive "DATA"
-- pBody has been pre-formatted with correct encoding, headers etc
sSMTPsendOnly pBody
-- or if you want to send the data in segments
-- repeat until pBody is empty
-- sSMTPsendOnly line 1 to 5000 of pBody
-- delete line 1 to 5000 of pBody
-- end repeat
sSMTPsendReceive CRLF & "."
sSMTPsendCallback "OK"
end sSMTPsendMessage
-- stop if user has clicked a stop button
--
on sSMTPcancelConnection
-- cancel timeout message
sSMTPcancelTimeout
sSMTPshowStatus ""
put empty into sSocketAddr
resetAll
sSMTPaddToTranscript "SMTPerror socket connection stopped", "all"
sSMTPexitSMTP "cancel"
end sSMTPcancelConnection
-- disconnect from SMTP server
--
on sSMTPdisconnectFromServer
sSMTPexitSMTP "disconnect"
end sSMTPdisconnectFromServer
-- diagnostic functions to set where to display a transcript
-- from the server (either verbose or short)
-- and a status line for each operation
--
on sSMTPsetTranscriptField pField, pType
if there is a pField then
put pField into transcriptField
else
put empty into transcriptField
end if
if pType = "verbose" then
put "verbose" into transcriptType
else
put "plain" into transcriptType
end if
end sSMTPsetTranscriptField
on sSMTPsetStatusField pField
if there is a pField then put pField into statusField
else put empty into statusField
end sSMTPsetStatusField
-- PRIVATE FUNCTIONS AND HANDLERS CALLED BY HANDLERS ABOVE
-- USERS DO NOT NEED TO USE THESE ROUTINES DIRECTLY,
-- BUT THEY DO NEED TO BE KEPT WITH THE REST OF THE LIBRARY
-- check socket connection after opening
--
on sSMTPsocketConnected
-- cancel timeout message
sSMTPcancelTimeout
-- read the welcome message from the server
read from socket sSocketAddr until CRLF
sSMTPaddToTranscript it, "all"
if char 1 of it = "2" then
put true into sConnectOK
sSMTPsendHello
else
sSMTPexitSMTP "badconnect"
end if
end sSMTPsocketConnected
-- once connection is made, cancel any pending timeout mesage
--
on sSMTPcancelTimeout
put the pendingmessages into pendMess
repeat for each line L in pendMess
if L contains "sSMTPcheckTimeout" then cancel item 1 of L
end repeat
end sSMTPcancelTimeout
-- add information to server transcript
--
on sSMTPaddToTranscript pData, pSet
if last char of pData <> cr then put cr after pData
put pData after transcriptVerbose
if pSet = "all" then put pData after transcriptPlain
if transcriptField is not empty then
if transcriptType = "verbose" then do "put transcriptVerbose into " & transcriptField
else do "put transcriptPlain into " & transcriptField
set the vscroll of transcriptField to 999999
end if
end sSMTPaddToTranscript
-- display current status line
--
on sSMTPshowStatus pStatus
if statusField is not empty then do "put pStatus into " & statusField
end sSMTPshowStatus
-- send EHLO or HELO message and read server capabilities
--
on sSMTPsendHello
sSMTPsendOnly "EHLO " & hostaddress(sSocketAddr)
put empty into firstRead
repeat
read from socket sSocketAddr until CRLF
sSMTPaddToTranscript it
if firstRead is empty then put it into firstRead
if it contains "AUTH" then put it into authHeader
put it into tRead
if char 4 of tRead <> "-" then exit repeat
end repeat
if char 1 of firstRead <> 2 then
-- use old HELO instead
sSMTPsendReceive "RSET"
sSMTPsendReceive "HELO " & hostaddress(sSocketAddr)
end if
if sAuthNeeded = true and authHeader is not empty then
sSMTPsendAuthMethod authHeader
else
sSMTPsendCallback "OK"
end if
end sSMTPsendHello
-- function to return the stripped email address
-- e.g. if sent "Joe Bloggs" <joe.bloggs@isp.com>
-- returns joe.bloggs@isp.com
--
function sSMTPextractEmail pAddress
put wordoffset("@", pAddress) into wordNum
put word wordNum of pAddress into tEmailAddress
replace "<" with "" in tEmailAddress
replace ">" with "" in tEmailAddress
return tEmailAddress
end sSMTPextractEmail
-- check what sort of authorisation is supported
-- encode data if necessary, then start sending
--
on sSMTPsendAuthMethod pMethod
sSMTPshowStatus "Authenticating..."
put empty into authMethod
if pMethod contains "LOGIN" then
put "AUTH LOGIN" into authMethod
put base64encode(sSmtpUser) into sSmtpuser
put base64encode(sSmtpPass) into sSmtpPass
else if pMethod contains "PLAIN" then
put "AUTH PLAIN" into authMethod
put space & base64encode(sSmtpUser & numtochar(0) & sSmtpUser & numtochar(0) & sSmtpPass) after authMethod
end if
-- authentication method not supported
if authMethod is empty then sSMTPsendCallback "NotAuthenticated"
sSMTPaddToTranscript "-> " & authMethod
if word 2 of authMethod = "PLAIN" then
-- PLAIN contains the login data in the method line sent
-- so don't need to send user & password after sending method
write authMethod & CRLF to socket sSocketAddr with message sSMTPauthDataSent
else
write authMethod & CRLF to socket sSocketAddr with message sSMTPsendUser
end if
end sSMTPsendAuthMethod
-- send user data
--
on sSMTPsendUser
sSMTPshowStatus "Sending user name..."
sSMTPreadData "Method" -- reading response to METHOD, only gets back if data OK
sSMTPaddToTranscript "-> " & sSmtpUser, "all"
write sSmtpUser & CRLF to socket sSocketAddr with message sSMTPsendPass
end sSMTPsendUser
-- read response from user data sent
-- if not OK, readData exits, so once it gets back here, continue with sending password
--
on sSMTPsendPass
sSMTPshowStatus "Sending password..."
sSMTPreadData "User" -- reading response to USER, only gets back if data OK
sSMTPaddToTranscript "-> ********", "all"
-- sSMTPaddToTranscript "-> " & sSmtpPass, "all"
write sSmtpPass & CRLF to socket sSocketAddr with message sSMTPauthDataSent
end sSMTPsendPass
-- authentication data has now all been sent
-- read the next message from the server ,
-- it will exit automatically if there was an error
-- otherwise send an OK to the connection callback handler
--
on sSMTPauthDataSent
-- read response to password
-- if wrong, it won't return
sSMTPreadData "Pass" -- reading response to PASS
sSMTPsendCallback "OK"
end sSMTPauthDataSent
-- this handler uses the callback message to report the number of emails
-- if there is an error, it is used to send back a 0
-- so that subsequent checks can be scheduled
--
on sSMTPsendCallback pState
put "send " & quote & callBackHandler && pState & quote & " to " & callBackTarget into cmd
try
do cmd
catch errMsg
sSMTPaddToTranscript "SMTPerror callback error: " & errMsg, "all"
sSMTPexitSMTP "badcallback"
end try
end sSMTPsendCallback
-- this routine sends data to the server and reads the response
-- SMTP responses always start with +OK or -ERR
--
on sSMTPsendReceive pData
if pData contains "PASS" then
sSMTPaddToTranscript "-> PASS ********"
else
sSMTPaddToTranscript "-> " & pData
end if
write pData & CRLF to socket sSocketAddr
sSMTPreadData word 1 of pData
end sSMTPsendReceive
-- this routine is for sending only, with no response expected
--
on sSMTPsendOnly pData
if the number of lines in pData < 10 then
sSMTPaddToTranscript "-> " & pData, "all"
end if
write pData & CRLF to socket sSocketAddr
end sSMTPsendOnly
-- this routine is for reading only
-- if there is an error, it closes the port & exits
--
on sSMTPreadData pWhat
repeat
read from socket sSocketAddr until CRLF
sSMTPaddToTranscript it, "all"
if char 4 of it <> "-" then exit repeat
end repeat
if it is empty or char 1 of it is in "54" then
sSMTPaddToTranscript "SMTPerror closing socket due to error reading " & pWhat, "all"
-- don't allow infinite loop of unanswered QUITs
if pWhat = "QUIT" then put empty into sSocketAddr
sSMTPexitSMTP "badread"
end if
end sSMTPreadData
-- close socket if still open,
-- tell callback handler unless it is an expected closure
--
on sSMTPexitSMTP pReason
sSMTPcancelTimeout
sSMTPshowStatus ""
if sSocketAddr is not empty and pReason <> "noconnect" then
sSMTPsendReceive "QUIT"
close socket sSocketAddr
put empty into sSocketAddr
end if
put empty into sSmtpUser
put empty into sSmtpPass
if pReason <> "disconnect" and pReason <> "cancel" and pReason <> "badcallback" then
sSMTPsendCallback pReason
exit to top
end if
end sSMTPexitSMTP
-- these handlers are just to catch any connection failure
--
on sSMTPcheckTimeout
put empty into sSocketAddr
resetAll
sSMTPaddToTranscript "SMTPerror timeout opening socket", "all"
sSMTPshowStatus ""
sSMTPexitSMTP "noconnect"
end sSMTPcheckTimeout
on socketTimeOut
put empty into sSocketAddr
resetAll
sSMTPaddToTranscript "SMTPerror socket time out", "all"
sSMTPshowStatus ""
sSMTPexitSMTP "timeout"
end socketTimeOut
on socketError sockID, errMsg
put empty into sSocketAddr
resetAll
sSMTPaddToTranscript "SMTPerror socket error: " & errMsg, "all"
sSMTPshowStatus ""
sSMTPexitSMTP "error"
end socketError
on socketClosed sockID
put empty into sSocketAddr
end socketClosed
-- for information display formatting only
--
on preOpenCard
if the short name of this stack = "sSMTPlibrary1" then set the scroll of fld "Docs" to 0
pass preOpenCard
end preOpenCard
-- these handlers are not part of the library
-- but are here to allow for stack resizing
--
on changeRect pObj, newL, newT, newR, newB
put the rect of pObj into tRect
if newL is not empty then put newL into item 1 of tRect
if newT is not empty then put newT into item 2 of tRect
if newR is not empty then put newR into item 3 of tRect
if newB is not empty then put newB into item 4 of tRect
set the rect of pObj to tRect
end changeRect
on resizeStack newW, newH
if the short name of this stack = "sSMTPlibrary1" then
changeRect the long name of btn "Tabs", , ,newW - 10, newH - 10
changeRect the long name of fld "Docs", , ,newW - 20, newH - 20
end if
end resizeStack
when i receive email from my app and check the source code of the email i have this:
but then i send a test message from my gmail i got this format, and it displays Lithuanian chars perfectly:X-TNEFEvaluated: 1
Content-Transfer-Encoding: 7bit
Content-Type: text/plain; charset=US-ASCII
<topdesk>
<incident>
<callerlogin>nvappsrv</callerlogin>
<category>Technika - Vilniaus paukÜtynas?????Ü??×</category> <subcategory>Technin? ?ranga (skerdimas)</subcategory> <request> <![CDATA[ Testinis tekstas?????Ü??×
Hostname:kg-itt-it1
]]>
</request>
</incident>
</topdesk>
the question in that i need to change/include in my source code to display unicode chars in subject ant mail body text ?X-TNEFEvaluated: 1
Content-Type: multipart/alternative; boundary="001a1145a18e936d9605600d428f"
--001a1145a18e936d9605600d428f
Content-Transfer-Encoding: base64
Content-Type: text/plain; charset="UTF-8"
xIXEjcSZxJfEr8WhxbPFq8W+DQo=
--001a1145a18e936d9605600d428f
Content-Transfer-Encoding: base64
Content-Type: text/html; charset="UTF-8"
PGRpdiBkaXI9Imx0ciI+xIXEjcSZxJfEr8WhxbPFq8W+PC9kaXY+DQo=
--001a1145a18e936d9605600d428f--
Thank you.
also i attached my code.