188} How can I send email or newsgroup messages from the command-line?
Please use command line email responsibly only.
This is a reasonably complicated task. The current item owes to
several sources of information. Some given at the end in the
references.
@echo off & setlocal enableextensions
::
:: The username and the password need to be available
set missing_=
if not defined username set missing_=true
if not defined userpass set missing_=true
if defined missing_ (
echo The environment variables username and userpass must be predefined
echo Preferably outside this script before running it
goto :EOF)
::
:: The script path
set temp_=%temp%
if defined mytemp if exist "%mytemp%\" set temp_=%mytemp%
set vbs_=%temp_%\SendCmdfaqMail.vbs
::
:: The mail server (SMTP = Simple Mail Transfer Protocol)
set smtp_=
smtp.server.net
::
:: The header and the message, note the quotes
set From_=
"FirstName LastName <
myid@myisp.net>
"
set To_="
FirstName LastName <
yourid@yourisp.net>"
set Cc_="
FirstName LastName <
myid2@myisp.net>"
set ReplyTo_="
devnull@nowhere.net"
set Cc_=
set ReplyTo_=
set Subj_="Testing FAQ 188"
set Body_="This is a test at %date% %time%"
:: A potential attachment, full path required
set Attach_=
::
:: Ask before sending
call :ShowMessage
echo.
call :AskQuestionWithYdefault "Send [Y/n]?" reply_
if /i "%reply_%"=="n" goto _CleanUp
::
:: Make the VBScript and then execute it
call :SendCmdfaqMailVBS
cscript //nologo "%vbs_%"
::
:_CleanUp
for %%f in ("%vbs_%") do if exist %%f del %%f
endlocal & goto :EOF
:: ............... The main ends here ....................
::
:: Build a Visual Basic Script, note the quotes in the last section
:: CDO = Collaboration Data Objects
:SendCmdfaqMailVBS
setlocal
set cdoSchema=http://schemas.microsoft.com/cdo/configuration
echo > "%vbs_%" On Error Resume Next
echo >>"%vbs_%" Set objEmail = CreateObject("CDO.Message")
echo >>"%vbs_%" objEmail.From = %From_%
echo >>"%vbs_%" objEmail.To = %To_%
if defined Cc_ (
echo >>"%vbs_%" objEmail.Cc = %Cc_%)
if defined ReplyTo_ (
echo >>"%vbs_%" objEmail.Replyto = %ReplyTo_%)
echo >>"%vbs_%" objEmail.Subject = %Subj_%
echo >>"%vbs_%" objEmail.Textbody = %Body_%
if defined Attach_ (
echo >>"%vbs_%" objEmail.AddAttachment "%Attach_%")
::
echo >>"%vbs_%" objEmail.Fields("urn:schemas:mailheader:X-Command-Line-Script") = "SendCmdfaqMail.cmd"
echo >>"%vbs_%" objEmail.Fields.Update
::
echo >>"%vbs_%" with objEmail.Configuration.Fields
echo >>"%vbs_%" .Item ("%cdoSchema%/sendusing") = 2
echo >>"%vbs_%" .Item ("%cdoSchema%/smtpserver") =
"%smtp_%
"
echo >>"%vbs_%" .Item ("%cdoSchema%/smtpserverport") = 25
echo >>"%vbs_%" .Item ("%cdoSchema%/smtpauthenticate") = 1
echo >>"%vbs_%" .Item ("%cdoSchema%/sendusername") = "%username%"
echo >>"%vbs_%" .Item ("%cdoSchema%/sendpassword") = "%userpass%"
echo >>"%vbs_%" .Item ("%cdoSchema%/smtpusessl") = True
echo >>"%vbs_%" .Item ("%cdoSchema%/smtpconnectiontimeout") = 25
echo >>"%vbs_%" .Update
echo >>"%vbs_%" end with
echo >>"%vbs_%" objEmail.Send
::
echo >>"%vbs_%" If Err = 0 Then
echo >>"%vbs_%" WScript.Echo "OK"
echo >>"%vbs_%" Else
echo >>"%vbs_%" WScript.Echo "Err.Number " ^& Err.Number
echo >>"%vbs_%" WScript.Echo Err.Description
echo >>"%vbs_%" End If
endlocal & goto :EOF
::
:: Display the values that were given to the VBScript
:ShowMessage
echo Server %smtp_%
echo From: %From_%
echo To: %To_%
echo Cc: %Cc_%
echo ReplyTo: %ReplyTo_%
echo Subject: %Subj_%
echo Text: %Body_%
echo Attachment: %Attachment_%
goto :EOF
::
:: A subroutine for asking questions
:AskQuestionWithYdefault
setlocal enableextensions
:_asktheyquestionagain
set return_=
set ask_=
set /p ask_="%~1"
if "%ask_%"=="" set return_=y
if /i "%ask_%"=="y" set return_=y
if /i "%ask_%"=="n" set return_=n
if not defined return_ goto _asktheyquestionagain
endlocal & set "%2=%return_%" & goto :EOF
Test output:
C:\_D\TEST>SendCmdfaqMail.cmd
Server smtp.server.net
From: "FirstName LastName <myid@myisp.net>"
To: "FirstName LastName <yourid@yourisp.net>"
Cc:
ReplyTo:
Subject: "Testing FAQ 188"
Text: "This is a test at 13.07.2012 19:06:09.98"
Attachment:
Send [Y/n]?
OK
At the receiving end the arriving message and some of its headers
will look something like this:
Return-Path: <myid@myisp.net>
X-Original-To: yourid@yourisp.net
Delivered-To: yourid@yourisp.net
Thread-Topic: Testing FAQ 188
thread-index: Ac1hEWwMNGFJbgLKTcCEKam0ndeYzA==
X-Command-Line-Script: SendCmdfaqMail.cmd
From: "FirstName LastName" <myid@myisp.net>
To: "FirstName LastName" <yourid@yourisp.net>
Subject: Testing FAQ 188
Date: Fri, 13 Jul 2012 19:06:11 +0300
Message-ID: <9B1696AB68B04D6CA097483ACE144627@hupu>
MIME-Version: 1.0
Content-Type: text/plain
Content-Transfer-Encoding: 7bit
X-Mailer: Microsoft CDO for Exchange 2000
Content-Class: urn:content-classes:message
Importance: normal
Priority: normal
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.6157
This is a test at 13.07.2012 19:06:09.98
The next, rather obvious question is
how to send a file as the body of a message.
Rather than just the minimalistic one-liner
"This is a test at %date% %time%"
which was put into an environment variable in the example above.
Consider the earlier line
echo >>"%vbs_%" objEmail.Textbody = %Body_%
replace it with
echo >>"%vbs_%" Set fso = CreateObject("Scripting.FileSystemObject")
echo >>"%vbs_%" set ostream = fso.OpenTextFile("C:\MyMailData\MyMessage.txt",1)
echo >>"%vbs_%" objEmail.TextBody = ostream.ReadAll()
How can I post a message to a Usenet
newsgroup from the command line?
Please use command line posting responsibly only.
Note that whether this works at your ISP and location is highly
environment dependent. There are no guarantees. Furthermore, I have
(so far?) failed to get this newsgroup part work beyond XP.
@echo off & setlocal enableextensions
rem C:\_F\XTOOLS\SendCmdNewsmsg.cmd
::
call :ProgramTitle
::
:: The script paths
set temp_=%temp%
if defined mytemp if exist "%mytemp%\" set temp_=%mytemp%
set vbs_=%temp_%\SendCmdNewsmsg.vbs
::
:: An optional file containing the body of the newsposting
set MsgFile_=C:\_M\Message.txt
::
:: Help
if "%~1"=="?" (call :ProgramHelp & goto _CleanUp)
if "%~1"=="/?" (call :ProgramHelp & goto _CleanUp)
::
:: The news server (NNTP = Network News Transfer Protocol)
set nntp_=nntp.aioe.org
::
:: The newsgroup
set Newsgroup_="aioe.test"
::
:: The header and the message, note the quotes
set From_=
"FirstName LastName <
myid@myisp.net>
"
set Subj_="Test ignore"
set Body_="A single line message"
set Org_="
A private user"
::
:: Allow for the option to bypass the default subject
if not "%~1"=="" if /i not "%~1"=="/d" set Subj_="%~1"
::
:: Is the body of the message to be taken from a file
:: Check the file's existence
set bodyfromfile_=
if /i "%~2"=="/f" (
set bodyfromfile_=true
if not exist "%MsgFile_%" (
echo.
echo Exiting: File "%MsgFile_%" not found
goto _CleanUp))
::
:: Ask for confirmation before sending
echo.
call :ShowMessage
echo.
call :AskQuestionWithYdefault "Send [Y/n]?" reply_
if /i "%reply_%"=="n" goto _CleanUp
::
:: Make the VBScript and then execute it
call :SendCmdfaqNewsmsgVBS
cscript //nologo "%vbs_%"
::
:_CleanUp
for %%f in ("%vbs_%") do if exist %%f del %%f
if not defined cmdbox if defined PauseIfFromDesktop pause
endlocal & goto :EOF
:: ............... The main ends here ....................
::
:: The Visual Basic Script, note the quotes
:SendCmdfaqNewsmsgVBS
setlocal
set cdoSchema=http://schemas.microsoft.com/cdo/configuration
echo > "%vbs_%" On Error Resume Next
echo >>"%vbs_%" Set objMsg = CreateObject("CDO.Message")
echo >>"%vbs_%" objMsg.From = %From_%
echo >>"%vbs_%" objMsg.Subject = %Subj_%
echo >>"%vbs_%" objMsg.Organization = %Org_%
echo >>"%vbs_%" objMsg.Newsgroups = %Newsgroup_%
::
if defined bodyfromfile_ goto _ostream
echo >>"%vbs_%" objMsg.Textbody = %Body_%
goto _xheaders
:_ostream
echo >>"%vbs_%" Set fso = CreateObject("Scripting.FileSystemObject")
echo >>"%vbs_%" Set ostream = fso.OpenTextFile("%MsgFile_%",1)
echo >>"%vbs_%" objMsg.TextBody = ostream.ReadAll()
::
:_xheaders
echo >>"%vbs_%" objMsg.Fields("urn:schemas:mailheader:X-Command-Line-Script") = "SendCmdfaqNewsmsg.cmd"
echo >>"%vbs_%" objMsg.Fields("urn:schemas:mailheader:X-No-Archive") = "yes"
echo >>"%vbs_%" objMsg.Fields.Update
::
echo >>"%vbs_%" with objMsg.Configuration.Fields
echo >>"%vbs_%" .Item ("%cdoSchema%/postusing") = 2
echo >>"%vbs_%" .Item ("%cdoSchema%/nntpserver") = "%nntp_%"
echo >>"%vbs_%" .Item ("%cdoSchema%/nntpserverport") = 119
echo >>"%vbs_%" .Item ("%cdoSchema%/nntpauthenticate") = 1
echo >>"%vbs_%" .Item ("%cdoSchema%/nntpusessl") = False
echo >>"%vbs_%" .Item ("%cdoSchema%/nntpconnectiontimeout") = 25
echo >>"%vbs_%" .Update
echo >>"%vbs_%" end with
echo >>"%vbs_%" objMsg.Post
::
echo >>"%vbs_%" If Err = 0 Then
echo >>"%vbs_%" WScript.Echo "OK"
echo >>"%vbs_%" Else
echo >>"%vbs_%" WScript.Echo "Err.Number " ^& Err.Number
echo >>"%vbs_%" WScript.Echo Err.Description
echo >>"%vbs_%" End If
endlocal & goto :EOF
::
:ProgramTitle
echo +-----------------------------------------------------+
echo ¦ SendCmdNewsmsg Post a message from the command line ¦
echo ¦ By Prof. Timo Salmi, Last modified Sat 14-Jul-2012 ¦
echo +-----------------------------------------------------+
goto :EOF
::
:ShowMessage
echo NntpServer %nntp_%
echo Newsgroup %Newsgroup_%
echo From: %From_%
echo Subject: %Subj_%
if not defined bodyfromfile_ (
echo TextLine: %Body_%)
if defined bodyfromfile_ (
echo MsgFile: %MsgFile_%
) else (
echo MsgFile: %MsgFile_% Not invoked)
echo Attachment: %Attach_%
goto :EOF
::
:AskQuestionWithYdefault
setlocal enableextensions
:_asktheyquestionagain
set return_=
set ask_=
set /p ask_="%~1"
if "%ask_%"=="" set return_=y
if /i "%ask_%"=="y" set return_=y
if /i "%ask_%"=="n" set return_=n
if not defined return_ goto _asktheyquestionagain
endlocal & set "%2=%return_%" & goto :EOF
::
:ProgramHelp
echo.
echo Usage:
echo SendCmdNewsmsg [Subject] [/F]
echo /F = Message body from file
echo %MsgFile_%
echo or
echo SendCmdNewsmsg [/D^(efault^)] [/F] ^(in this order^)
goto :EOF
Test output:
C:\_D\TEST>SendCmdNewsmsg.cmd
echo +-----------------------------------------------------+
echo ¦ SendCmdNewsmsg Post a message from the command line ¦
echo ¦ By Prof. Timo Salmi, Last modified Sat 14-Jul-2012 ¦
echo +-----------------------------------------------------+
NntpServer news.eternal-september.org
Newsgroup "eternal-september.test"
From: "FirstName LastName <myid@myisp.net>"
Subject: "Test ignore"
TextLine: "A single line message"
MsgFile: C:\_M\Message.txt Not invoked
Attachment:
Send [Y/n]?
If successful, the posting in the newsgroup will look something like
this, somewhat depending on where you read it:
Path: eternal-september.org!mx04.eternal-september.org!feeder.eternal-september.org!aioe.org!.POSTED!not-for-mail
From: "FirstName LastName" <myid@myisp.net>
Newsgroups: aioe.test
Subject: Test ignore
Date: Sun, 15 Jul 2012 05:28:07 +0300
Organization: A private user
Lines: 1
Message-ID: <2F7F6B1EE2DF43248C77876C5CE5D46E@hupu>
NNTP-Posting-Host: Ka6yGpmGZFPSf6AX3tD5MA.user.speranza.aioe.org
Mime-Version: 1.0
Content-Type: text/plain
Content-Transfer-Encoding: 7bit
X-Complaints-To: abuse(ät)aioe.org
X-No-Archive: yes
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.6157
thread-index: Ac1iMXgnZC5EI8ziQ1Obe2f7KAKc4A==
X-Command-Line-Script: SendCmdfaqNewsmsg.cmd
Content-Class: urn:content-classes:message
X-Notice: Filtered by postfilter v. 0.8.2
X-Newsreader: Microsoft CDO for Exchange 2000
Importance: normal
Thread-Topic: Test ignore
Priority: normal
Xref: mx04.eternal-september.org aioe.test:1551
A single line message
How to post to more than one newsgroup?
(
Mind the news netiquette: Do not
multipost.
Do not
crosspost excessively!
)
Answer: In the
Newsgroup_ environment
variable put the newsgroups on the same line, separated by commas (,).
How to set the Followup-To: header?
Insert:
echo >>"%vbs_%" objMsg.FollowUpTo = %Newsgroup_%