PDA

View Full Version : Controlling Girder via e-mail



crisr
May 20th, 2003, 04:02 PM
I have built a GML file to enable controlling Girder via e-mail using Getmail (http://www.interlog.com/~tcharron/getmail.html), without the need for the SMAPI plugin, which needs Outlook installed and configured with a default account.

The GML will check for e-mails on a dedicated mailbox (don't use your personal mailbox, because Getmail will DELETE every mail on the mailbox) every 15 seconds using the TimeServer plugin (http://www.girder.nl/downloadn.php?Link=29). Of course, if someone wants to modify it to share a mailbox, feel free :wink:. Anyway, you will have to edit the GML and configure the parameters for Getmail (username, password, pop server).

The script will parse the e-mail and trigger an event ("mail_process"), passing the sender, subject and the first line of the message body as payloads. It will work even on Outlook Express HTML e-mails, as it looks for the text/plain section.

The GML includes an example "Process_mail" command, which checks if the sender is allowed and then triggers an event with the subject as the eventstring, passing the message body as a payload.

You can test by sending an e-mail to, like, girder@yourserver.com (create a new dedicated account), with subject "winamp" and the file to play in the first line of the message body (in the example the music file has to be on the winamp directory). When it receives the message, winamp will launch and play that music.

I use the script to control Girder via SMS e-mail messages from my cellphone, so i can use commands like "vcr" "51 rec 60" for Tira-1 to power the vcr, tune to channel 51 and record for 60 minutes via another script (I hope I can, my Tira hasn't arrived yet :P ).

If you have other ideas, please share them on this forum.

Now I just need to find out how to upload attachments to this Forum to post the zip file with the GML and readme!

crisr
May 20th, 2003, 04:20 PM
EDITED


See below for instructions on how to build the group.

JimHugh
May 20th, 2003, 05:18 PM
Haven't tried it yet, but wanted to let you and others know that in order to create a valid GML file, I had to use a text editor to replace a number of & characters with & to make it a valid XML file.

Affected areas were the Step Size in the get_mail command and the VMS section in parse_email command.

I dragged the file into Internet Explorer until it successfully parsed the file as xml as I made each edit.

crisr
May 20th, 2003, 06:12 PM
I'm sorry, as you may have noticed I am new to Girder and this forum. As the GML file is a text file, I thought it would work within a BBCode <code> tag, it seems it does not. Do you know of a good place to upload the file for the forum users (it seems Ron turned attachments off a while ago)? Or maybe I'll just put the GVMS sources into <code> tags and instructions on how to assemble the GML group...

JimHugh
May 20th, 2003, 06:50 PM
& should have been & amp ; (no spaces)

Thanks for the effort, it should have worked the way you did it. I have posted GML files before but never with &

JimHugh
May 20th, 2003, 06:50 PM
Sorry for the hiccup it posted twice!

crisr
May 20th, 2003, 06:56 PM
Ok, here you go:

Create a new top-level group and name it email.

Create a multigroup in this group and name it Check_email.

Create a command in this multigroup and name it get_mail; make the action OS->Execute "<path>\getmail.exe" "-u <user> -pw <password> -s <server> -delete" (if in doubt, check Getmail readme), and Hidden in startup options.

Create a command and name it "wait"; set the action Window->wait 500ms (you may need to adjust this depending on the speed of the connection to your server).

Create a command and name it parse_mail; set the action Girder->Variable manipulation script and use the following as source:


fname1=GetDirectory&#40;'PROGRAMFILES'&#41;.."\\Getmail\\MSG"
fname2=".TXT"
i=1
repeat
fname=fname1..i..fname2;
f=openfile &#40;fname,"r"&#41;;
if &#40;f~=nil&#41; then
txt=0;
repeat
st=read &#40;f,"*l"&#41;;
x,x,s=strfind&#40;st,"Return%-Path&#58;%s<&#40;.*&#41;>"&#41;;
if &#40;x~=nil&#41; then mail_from=s; end;
x,x,s=strfind&#40;st,"Subject&#58;%s&#40;.*&#41;"&#41;;
if &#40;x~=nil&#41; then mail_subject=s; end;
x,x,s=strfind&#40;st,"Content%-Type&#58;%stext/plain"&#41;;
if &#40;x~=nil&#41; then txt=1; end;
until &#40;st==nil&#41; or &#40;&#40;st=="" or st==" "&#41; and &#40;txt==1&#41;&#41;;
repeat
mail_body=read &#40;f,"*l"&#41;;
until &#40;&#40;strfind&#40;mail_body,"%S"&#41;&#41; or &#40;st==nil&#41;&#41;;
TriggerEvent &#40;"mail_process",18,mail_from,mail_subject,mail_body&#41;;
closefile &#40;f&#41;;
remove &#40;fname&#41;;
i=i+1;
end;
until &#40;f==nil&#41;;


Learn an event from the TimeServer Plugin and set it to "Every N seconds"; keep it disabled for now.

Add a command to the email group and name it "Process_mail"; set the action to Girder->Variable Manipulation Script and use the following source:


if &#40;pld1=="<youremail@server.com>" or pld1=="<otheremail@server.com>"&#41; then
TriggerEvent&#40;pld2,18,pld3&#41;;
end;


Learn an event from Girder Event and use "mail_process" as the event string (without the quotations marks).

Add a command to the email group and name it winamp; set the action as OS->Execute "<path>\winamp.exe" "<musicpath>\[pld1]".

Learn an event from Girder Event and use "winamp" as the event string (without the quotes).

Enable the "timer" event.

Test by sending an e-mail to girder@yourserver.com with subject "winamp" and the filename to play in the first line of the message body. Winamp should launch and play that music.

That's it. I hope it works for everybody now.

crisr
May 20th, 2003, 08:52 PM
& should have been & amp ; (no spaces)

There's a very interesting article about the ampersand and XML, "Ampersand Attrition in XML and HTML" at:

http://www.itworld.com/nl/xml_prac/07042002/

Apparently, the ampersand can cause all sorts of parsing problems with xml processors...

By the way, it would be cool if someone would make a plugin to do what my script does without using an external program and the burden of spawning a process and creating a file with every e-mail, maybe even using an IMAP connection to avoid polling alltogether...

Liickdude
September 3rd, 2003, 10:32 AM
I have some troubles with this script. The email is downloaded and parsed, but it keeps triggering the event over and over. If I have one message that the subject line is set to run a girder event, it keeps going over and over. I have tried to erase the MSG1.txt file, but it cannot be erased until girder is closed. Ideally, I would like girder to read the file, load the subject line into the variable mail_subject, then close and erase the MSG1.txt file, so the folder will not fill up with files. Is there a way to get girder to let go of the file so it can be deleted without closing girder?

crisr
September 9th, 2003, 10:33 AM
I don't know why your file isn't being deleted... the lines "closefile (f); remove (fname);" on the script are supposed to close the file and delete it after it is parsed and the event triggered, and it works fine on my system.

Have you checked if the current logged-on user has erase permissions on the mail directory?

Liickdude
September 9th, 2003, 03:48 PM
I figured it out, but I had to change your script a little bit. I was sure that it wasnt a window permission error as I always had to close girder, then I could delete the message. I was also getting a script error when I tried running the script in girder, it would read the email and load the mail_subject properly, it would just sit there and not close and remove the file. I shortened the script a bit as the only info I need is the subject line. Then I have girder use a separate command in the multigroup to erase the file. It is working fine now, sorry but I cant recall the exact error I was getting, I have another computer that I use to debug and try this stuff out on, so I will load up your script again and see what it does, maybe there is something missing on my computer. I will let you know what I find.

Liickdude
September 9th, 2003, 07:34 PM
Here is the script I am using and it works for my purposes:

f=openfile ("c:\\Program Files\\Getmail\\MSG1.TXT","r");
if (f~=nil) then
txt=0;
repeat
st=read (f,"*l");
x,x,s=strfind(st,"Subject:%s(.*)");
if (x~=nil) then mail_subject=s;
end;
until (mail_subject~=nil)
closefile (f);
end;

Selyb
September 19th, 2003, 11:11 PM
hey
ive done a little homework on this subject though not to control girder
i wanted an email checker that is invisible to taskbar and system tray
i wanted a program to run in my background and only display a tray icon if i had mail or run my email program
what i used for a while was a vbscript i wrote to run getmail with command line options to not delete emails from the server, if it created any files in the folder with the script the script deleted them then ran my email prog
recently i found a vbscript that creates the connection itself without using an external program
im still trying to edit the script to simply run my email program instead of downloading the emails directly
here is the script

now that i think about it i havent tested this script


Dim pop3 As Object
Dim bUserName As Boolean
Dim bPassword As Boolean
Dim bStat As Boolean
Dim bRetr As Boolean
Dim lMsgCnt As Long
Dim lMsgRetr As Long

Const sUSERNAME = "testuser"
Const sPASSWORD = "testpass"
Const sSERVER = "mail.testdomain.com"

Private Sub Form_Load&#40;&#41;

Set pop3 = CreateObject&#40;"MSWinsock.WinSock.1"&#41;

pop3.RemoteHost = sSERVER
pop3.RemotePort = "110"

pop3.Connect

While pop3.State <> 7
DoEvents
Wend

While pop3.BytesReceived = 0
DoEvents
Wend

pop3_DataArrival pop3.BytesReceived

End Sub

Private Sub pop3_DataArrival&#40;ByVal bytesTotal As Long&#41;

Dim strTemp As String
pop3.GetData strTemp

Debug.Print "got&#58; " & strTemp
Handle_Data strTemp

End Sub

Private Sub Handle_Data&#40;sIncData As String&#41;

If Left&#40;sIncData, 3&#41; = "+OK" Then
If Not bUserName Then
pop3.SendData "USER " & sUSERNAME & vbCrLf
bUserName = True
Debug.Print "Sent Username"
ElseIf Not bPassword Then
pop3.SendData "PASS " + sPASSWORD & vbCrLf
bPassword = True
Debug.Print "Sent Password"
ElseIf Not bStat Then
pop3.SendData "STAT" + vbCrLf
Debug.Print "Sent Stat"
bStat = True
ElseIf Not bRetr Then
lMsgCnt = CLng&#40;Mid&#40;sIncData, 4, InStr&#40;5, sIncData, " "&#41; - 4&#41;&#41;
If lMsgCnt > 0 Then
bRetr = True
lMsgRetr = 1
pop3.SendData "Retr " & lMsgRetr & vbCrLf
Else
pop3.SendData "QUIT" & vbCrLf
pop3.Close
Debug.Print "QUIT"
End If
End If
ElseIf Left&#40;sIncData, 3&#41; = "-ERR" Then
Debug.Print "Error&#58; " & sIncData
Else 'Must be a message!
Debug.Print "MESSAGE&#58; " & sIncData
lMsgRetr = lMsgRetr + 1
If lMsgRetr <= lMsgCnt Then
pop3.SendData "Retr " & lMsgRetr & vbCrLf
Else
pop3.SendData "QUIT" & vbCrLf
pop3.Close
Debug.Print "QUIT"
bUserName = False
bPassword = False
bStat = False
bRetr = False
End
End If
End If

While pop3.BytesReceived = 0
DoEvents
Wend

pop3_DataArrival pop3.BytesReceived

End Sub

paste this to a text file and rename it to something.vbs
on some systems you may need to tell windows to have wscript.exe open it

Luke M.
February 4th, 2004, 01:57 AM
Well it's been a while since anyone posted to this thread, but hopefully I might still be able to get some help from someone who understands what's going on.

I've set up my commands and such using crisr's detailed instructions. The GetMail command works fine, it retrieves the message from the server, parses it, deletes the MSG1.txt file, and then calls my Girder event mail_process. However, at that point it stops.

Mail_process should trigger the following script:



if (pld1=="<youremail@server.com>" or pld1=="<otheremail@server.com>") then
TriggerEvent(pld2,18,pld3);
end;



I don't know a lot about VMS but this is what I've deduced. At the end of the first script, we


TriggerEvent ("mail_process",18,mail_from,mail_subject,mail_body);

The mail_process calls my Girder event of that name, and I guess the "18" means "payloads follow" or something such, with the three payloads: mail_from, mail_subject, mail_body.

In our second script (the first one I quoted), we first check to see if pld1 is equal to my username (I changed "<youremail@server.com"> to my actual username, in quotes). I'm guessing that since mail_from is the first in the list of payloads passed to this script, that we can reference it simply by using the term "pld1" rather than "mail_from". Is this correct? Or am I supposed to change "pld1" to "mail_from"?

If the email is from the right person we then trigger another Girder event named pld2 (this would be the subject of the email, also known as mail_subject). There's that 18 again, and the payload that follows is our pld3 from earlier, also known as mail_body. Again here I don't know if I'm supposed to change the script from pld2 and pld3 to mail_subject and mail_body (but I did try this though, and the script still doesn't run).

So anyway, this is starting to get confusing. I actually have a few other issues with this whole process as well, but I want to start out just making sure I understand what is going on in the script, and if anyone has any ideas why my second script isn't running and triggering my "winamp" event.

crisr
February 4th, 2004, 07:20 AM
Well, it's been a while and even I don't remember why I made some decisions, but let's try:

The action is performed on 3 steps: Step 1 (script 1) checks and parses the e-mail files and triggers the second step. Step 2 (script 2) checks the validity of the sender and triggers the event string on the subject line of the e-mail, passing the body as a payload. Step 3 executes the action, when it's event string is triggered.

There are 2 separate scripts, one parses the e-mail, and the other checks the validity of the sender and triggers the event on the mail subject line. You must learn a girder event with the name "mail_process" in the second script. "18" is the plugin number for Girder internal events. In the first script, the subject and from are in the variables mail_from and mail_subject, which are sent as payloads for the second script. Only then (in the second script) you can (and have to) use pld2, pld3.

Have you did "Learn Event" for the command that needs to be executed?

To debug, try analyzing the e-mail text from msg1.txt before it gets deleted.

Luke M.
February 4th, 2004, 12:49 PM
Ok, well I figured out part of my problem. It wasn't triggering the second script because I had the wrong email address entered: the one I was checking, rather than the email the message was coming from. Duh...

However, I only get the second script to work when I replace the pld1, pld2, etc. with the actual names of the variables those payloads carry. In other words, my second script looks something like this:



if (mail_from=="<youremail@server.com>") then
TriggerEvent(mail_subject,18,mail_body);
end;


This doesn't seem to be the way it's suggested it should work, but since it does, I'm not complaining.

Now, the only other problem I'm having is getting the OS->Execute to run: both in the case of running the getmail program as well as my Winamp app. I can manually go to the C:\ prompt and type in the getmail command and it will go out, check my email, and save it as a MSG1.txt on my hard drive just fine. But when I try to run the same command from a Girder command OS->Execute, I get a windows popup that says, Error, the file you requested could not be found, please check to make sure you entered it correctly, bla bla bla. The command or file it can't seem to find is the exact same string that if I enter manually at the C: prompt works fine. So I'm kind of confused by that.

Any thoughts on what might be wrong there?

Agonostis
February 4th, 2004, 03:47 PM
I have also recently been trying this out, but am having the same problem as Liickdude above...it all works, except Girder (and Windows, when Girder is open) can't delete the file.

Does anyone understand the solution? It doesn't seem like he actually put it up there, just a shortened version of the script that has the same problem.

Thanks for any help!

Liickdude
February 4th, 2004, 05:25 PM
My solution was to remove the line that was supposed to delete the file as it did not delete no matter what I tried with it. Instead, I placed the script in a command in a multigroup, and after the script entry, I put 2 commands, the first was 25 ms wait, and the second was a separate command to delete the file manually. It is working, although I must admit I have not been using it. I am trying to learn all I can about voicexml so I can get a working interactive telephone user interface going, but I am a long way from figuring it out. So far, I have the AT&T Natural Vioces engine installed, thats about it.

Agonostis
February 4th, 2004, 07:25 PM
What exactly is the command to delete the file manually?

Luke M.
February 5th, 2004, 10:06 PM
Ok, everyone else but me seems to be able to figure this out, but I'm going to post what I was doing wrong just in case.

My problem with the OS->Execute command was that I was setting it up wrong. Crsisr gives us this for an example of what to do in order to run GetMail:



"<path>\getmail.exe" "-u <user> -pw <password> -s <server> -delete"


I was entering the entirety of the above string in the "File" section under the "OS" tab. In fact, only the first half, "<path>\getmail.exe" should go in the "File" box. The second half should go in the "Step Size" box. A simple newbie thing. Hopefully this made sense to everyone else right away.

Another thing to note is that in the case of the Getmail OS command, I entered the strings above in the "File" and "Step Size" boxes without the parentheses. This works fine. However, for the very similar arrangement to run Winamp and specify a song, I needed to put quotes around the string that goes into the "Step Size" box for it to work ("<musicpath>\[pld1]". Note also that rather than [pld1] I'm using [mail_body], which is the variable name defined in the script. It should be equal to [pld1] but, for some reason, is not.

A final problem I was having was with the Time Server plugin, which suffers from lack of documentation. The way I got it to work was to learn event-> Time Server event. This brings up the Time Server configuration dialogue. Click "Add" as in add event. Under the "Parameters" section (bottom left), have only the first and last boxes checked, clear the rest (these are "Event is Valid" and "Value for Time is Computing from NOW.")

Under "Generate Event" select "Every N Seconds" then set how many seconds you want this to be. I think on mine I have it set to 5. Click "Insert Event" and it should take you back to the "Time event list" tab. From here you'd think you should click "Send IR Code to Girder" but more than likely Girder isn't in learning mode anymore. Click "OK" then select your timer even in Girder again, and once again click Learn Event->Time Server. Now choose the time event that you created from the list under the "Time event list" tab, and now hit "Send IR Code to Girder." Now it should work.

Hope that helps someone. At any rate, I was able to get it to work, which is nice.