Skip to main content

Querying GitHub Issues from Google App Script

I'm currently exploring different integrations that can be done between Google App Script and Git. This is part of a bigger attempt to integrate Git data into my project management system. I'll post more on that later. GitHub supports a number of very nice sub-systems. One of them is the GitHub Issues ticket tracking system. It's fairly robust and comes with GitHub - which means it's highly integrated out-of-the-box. Integration with Google's App Script is done via the fetchURL command and JSON object manipulation.  After a good bit of experimentation, I've settled on querying GitHub Issues with an "on open spreadsheet event" to avoid issues with Google's quota system. Essentially, Google prevents you from calling the fetchURL command more than X times (see the quota limits ) per day. That's not great if you have people actively working and changing data in a spreadsheet. Some of my other App Script routines are running thousands of times per d...

Gmail, POP3 and Indy

In my ever expanding need for dealing with the outside world, I've discovered a quirky little thing about Indy 10. When using the TIdPOP3 component with Gmail, you have to manually call DisconnectNotifyPeer or delete commands are ignored. I suppose this isn't quirky as much as not really documented any place I was able to find. Let's backup and start at the beginning, shall we?

I have a Windows service that polls a POP3 account looking for messages that it can import into a DB. It has all sorts of fun rules that can be assigned to discover what needs to be imported, what database it goes into, etc. At any rate, this code has been merrily chugging away on both Yahoo and SmarterMail servers with nary a hiccup. I recently needed to watch a Google domain app e-mail address and didn't think much of it.

Of course, in order to do so you have to implement SSL for POP3. As I've posted in the past, this is not really much of an issue, you simply create the TIdSSLIOHandlerSocketOpenSSL object and assigned it to the IOHandler like so:
Pop3Srv.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(Pop3Srv);
Pop3Srv.UseTLS := utUseImplicitTLS;


Anyway, all was proceeding swimmingly until I retrieved the first message. In my case, I automatically delete any e-mail that matches my rules so it will not be imported a second time. This works fine with Yahoo and SmarterMail. You just call DeleteMessage(msgNumber) and voila, away it goes. With Gmail, no such luck.

Gmail actually has a three different settings under POP3. One keeps messages in the inbox after reading via POP, one archives it and one deletes it. Thinking this option was set wrong, I tried all three options... repeatedly... still no luck. I tried searching pretty extensively on this one and finally found the clue with RFC 1939. Gmail honors the "you must notify me you are quitting or I will not delete anything" rule that 1939 dictates.
When the client issues the QUIT command from the TRANSACTION state, the POP3 session enters the UPDATE state. (Note that if the client issues the QUIT command from the AUTHORIZATION state, the POP3 session terminates but does NOT enter the UPDATE state.) If a session terminates for some reason other than a client-issued QUIT command, the POP3 session does NOT enter the UPDATE state and MUST not remove any messages from the maildrop.


After checking the code for the IdPOP3, it turns out calling Free does not issue the QUIT command. It makes sense for it not to do so. What if you wanted to avoid the UPDATE state? It was just surprising that some mail servers worked without this command and some required it.

At any rate, I hope this helps someone else who's working with POP3 commands.

Comments

GunSmoker said…
Thanks for the hint!

I worked with GMail, Indy and POP3 recently, but didn't discover this issue yet. Looks like you saved my time :D Thanks.
LDS said…
The Indy implementation is correct. Free may be called due to an exception, and IMHO it would be wrong to call QUIT as if the connection was closed cleanly. Far better to have the server "rollback" any change.
GMail also implements the POP3 protocol correctly - the other implementations are flawed. Check it with "real" POP3 servers (under Windows you can try Mercury/32 and hMailServer, for example), and you will see the GMail bheaviour.
Marshall Fryman said…
@LDS: I agree. I'm not complaining just noting the different behaviors between mail servers. I don't think it's well documented one way or the other from what I've seen. The RFC states it... but I doubt many of us have read the POP RFC all the way through.

Popular posts from this blog

SMTP Mail and Indy (again)

Having spent a lot of time recently working on a ping scanner using Indy, I noticed that there's a lot of questions still on using SMTP with Indy. Let me first say that I am not an Indy expert. I get along with it successfully but find I still have to research things frequently. With the disclaimer out of the way, we can get to the offering. A while back I wrote a handy little unit to simply send a mail message with or without attachments and with or without providing authentication. It even has support for OpenSSL. I use this unit in a number of applications and have seen it successfully send hundreds of e-mails without issue. I recently added support for threaded message sending to take advantage of the multi-core system I'm now running on. This code has had a few additions (like the logger) that I've gleaned over time from various newsgroup postings, but I didn't record the authors so let me credit the anonymous Internet authors who support Indy. It's really amaz...

Detecting a virtualized environment

CubicDesign on delphi-talk.elists.org recently asked the question: "How do I know/detect if my software is running under Windows [or a virtual environment]?" Well, it turns out that it's a lot harder to tell than you would think. Apparently, the VM (VMware, Xen, Wine, etc.) doesn't really want you to be able to do this. At least not easily. For VMware, there is a decent little C routine called jerry.c that does the trick. Jerry actually uses a simple communication channel that VMware left open. It's not 100% foolproof since the admin can change the channel, but that's not likely going to happen unless the system is specifically designed to be a honeypot. If you're running on a honeypot and still have a legitimate reason for detection, you could look at the much more complex scoopy implementation which inspects how the system is actually virtualized using the SIDT CPU instruction instead of a communication channel. Another reference (red pill) is here . F...

Delphi Case with Strings

Zarko Gajic posted about this topic on his Delphi Tips recently showing how one could use a case statement with strings. His solution basically passes in an array on the stack and then iterates through it providing the index number of the matching string. I don't often want to do this, but the idea comes up occassionally enough that I thought I'd play with it a little. The first thing that struck me with this is that passing things on the stack is bound to be slow. Any time you can avoid memory allocation in your routines, do it. The way Zarko wrote his StringToCaseSelect routine created a COPY of the information on the stack. In my testing, just changing the CaseList: array of string to CaseList:const array of string improved the performance of the code by almost 30% for his example. Mind, I'm not using hyper-precise counters; however, it definitely makes a difference. Secondly, I was curious how the performance changed if I used the old stand-by: If then else. Using the ...

Copyright 2008-2022, Marshall Fryman