Ankündigung

Einklappen
Keine Ankündigung bisher.

Plugin gesucht um IMAP Mails auszuwerten

Einklappen
Dieses Thema ist geschlossen.
X
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    [wiregate] Plugin gesucht um IMAP Mails auszuwerten

    Hallo zusammen,

    ich suche ein Plugin, das einen IMAP-Mail-Account überwacht. Leider habe ich nichts dazu gefunden.
    Da ich mich mit der Plugin-Programmierung auch nicht groß auskenne und gerade mal in der Lage bin, fertige Plugins ein wenig anzupassen, wäre es für mich leider auch ein hoffnungsloses Unterfangen, ein komplett eigenes zu schreiben.

    Gibt es vielleicht schon ein Plugin, dass Mails per IMAP liest, den Betreff, bzw. den Mail-Inhalt nach bestimmten Begriffen durchsucht und dann einen Schaltbefehl auf einer Gruppenadresse auslöst?

    Schon mal vielen Dank im Voraus

    Lieben Gruß

    Alex

    #2
    Gibt es m.W. nichts fertiges, sollte aber problemlos möglich sein.
    https://sourceforge.net/p/openautoma...lugin/generic/ gibts viele Beispiele (z.B. SMTP) und das Repository freut sich immer über neue Plugins

    Tipp: ich mach das immer so:
    - erstmal sep. in Perl (muss nicht auf dem WG sein)
    - wenn ein Perl-Modul fehlt (was ich bei IMAP nicht glaube) kann man darüber reden
    - testen + 90% Copy&Paste ins Plugin

    Makki
    EIB/KNX & WireGate & HS3, Russound,mpd,vdr,DM8000, DALI, DMX
    -> Bitte KEINE PNs!

    Kommentar


      #3
      Hallo Makki,

      vielen Dank für deine Antwort.

      Gerne würde ich mich da einbringen und ein Plugin zusammenstricken. Leider hab ich von Perl recht wenig Ahnung und was noch viel schlimmer ist, viel um die Ohren, so dass es für mich aktuell leider nicht möglich ist, mich in die Materie tief genug einzuarbeiten.

      Ich werde mein Projekt dann wohl erst mal auf Eis legen und mich vielleicht im Winterurlaub mal drauf einlassen.

      Lieben Gruß

      Alex

      Kommentar


        #4
        Hi,

        nun wenn du verrätst, was du konkret vorhast (?)
        -> Gibts sowas evtl. schon fast (ist in der Form nur nicht "gesellschaftsfähig") deswegen bin ich mir aber auch sicher, das es geht

        Die grösste Herausforderung ist nicht IMAP, sondern Stati, also merken, was man schon prozessiert hat.. Wenn man anpassen kann was in der eMail steht (sequenz-nummer o.ä.), sollte das kein Problem sein - ansonsten wirds etwas komplizierter..
        (Merken, was man schon hat, vergleichen, ...)

        Makki
        EIB/KNX & WireGate & HS3, Russound,mpd,vdr,DM8000, DALI, DMX
        -> Bitte KEINE PNs!

        Kommentar


          #5
          Hallo Makki,

          vielen Dank für deine Unterstützung. Ich muss dir Recht geben, das Rad sollte man nicht zwei mal erfinden und ich habe auch nichts gegen ein paar unvollständige Codeschnipsel, an denen ich mir was abkupfern kann ;-)

          Allso mal konkret zu meinem Projekt:
          Ich habe einen GPS-Tracker, der in meinem Auto verbaut ist und der mir bei Bewegung des Gerätes (oder des Autos) etwa alle 2 Minuten einheitliche Datenpakete in Form von E-Mails verschickt. Den Mailinhalt kann ich leider nicht beeinflussen. Er sieht in etwa so aus:

          itakka tracking service reports from imei-device 35477xxxxxxxxxx:time: 2014-11-17 03:08:51 lat: N 50.127520 Grad (= N 50 Grad 9.5512 Minuten ) lon: E 8.184761 Grad (= E 8 Grad 6.2657 Minuten ) speed: 1.22 course: 336.10 height: 383.8 battery: F:4.32V charging: yes satellites: 06 yesIch wollte nun diese Mails auswerten und die Koordinaten auslesen und einen Bereich um mein Haus definieren, in dem das Auto stehen darf, wenn ich zu Hause bin. Fährt mein Auto unerlaubt weg und der Autoschlüssel hängt noch im Kasten (ibutton), dann soll eine Lichtszene ausgelöst werden.

          Lieben Gruß

          Alex

          Kommentar


            #6
            Hmm, spannende Aufgabe

            Also, es gibt bestimmt 10 einfachere und bessere Möglichkeiten, das zu realisieren..
            Ein Smartphone für 100€ ins Auto, Prey (z.B.) drauf, fertig.
            Oder einen "Ankeralarm", der eMails/SMS schreibt, gibts auch 100 Apps - oder willst du nach auslösen der Lichtszene dann den Täter in 1km Entfernung persönlich stoppen? Oder nur aufgeweckt werden, um zu wissen das dein Auto vor 2min geklaut wurde und du morgen S-Bahn fährst

            Bitte nicht böse verstehen, aber für ein Beispiel (IMAP ausm Plugin ist wiegesagt kein Problem!) brauche ich einen nutzbaren Anwendungsfall..
            GPS-Koordinaten + Entfernungen ausrechnen ist eher ziemlich anstregend.

            Makki
            EIB/KNX & WireGate & HS3, Russound,mpd,vdr,DM8000, DALI, DMX
            -> Bitte KEINE PNs!

            Kommentar


              #7
              Hallo zusammen,

              ich hätte vielleicht einen Anwendungsfall der auf Interesse stoßen könnte.
              Unser lokaler Müllentsorger hat einen Benachrichtigungsservice, wann welche Tonne abgeholt wird. Hierzu wird 1-2 Tage zuvor eine E-mail verschickt, in der die Art der Tonne und das Datum steht. Ich würde nun gerne diese Information an einem Taster und einem RGB-Strip visualisieren, um am Vortag erkennen zu können, dass ich abends die entsprechende Tonne rausstellen muss. Zusätzlich habe ich vor, die Tonnen mit einem mechanischen Schalter und einem Mutli-IO abzufragen. Sobald die Tonne nicht mehr an ihrer Position steht, kann ich davon ausgehen, dass ich Sie rausgestellt habe und die Meldung kann gelöscht werden.

              Sollte hierfür Interesse bestehen, werde ich mal eine entsprechende Mail anhängen. Geht gerade nicht, da ich nicht zuhause bin und die Mails zur Zeit bei meiner Frau aufschlagen.

              Wäre echt super, wenn das machbar wäre. Damit könnte ich daheim echt punkten und die ewigen Diskussionen, warum ich es nicht schaffe die Tonnen rauszustellen (Ich weiss ja nicht wann) hätten endlich ein Ende.

              Grüße

              Sven

              EDIT: Mit ist gerade noch aufgefallen, dass die E-Mail natürlich nach der Auswertung gelöscht werden kann. Ich denke das macht das ganze einfacher, da man nicht analysieren muss welche E-Mail schon abgefragt wurde.

              Kommentar


                #8
                Hallo,

                oh ja. Das wäre super. Den gleichen Anwendungsfall wie Sven könnte ich mir auch super vorstellen. Ich will auch irgendwann die Müllentsorgungstermine auf dem Bus haben und hatte schon mal überflogen, dass ich mich mit google-Kalender oder externen Schaltlisten beschäftigen muss (Homeserver)... Aber da wir auch Mails vom Entsorger erhalten, wäre das ja viel praktischer. Dann müsste ich nie per Hand die Listen pflegen und bin immer up-to-date :-)

                Wenn es da was gibt, hätte ich sofort Interesse (Wiregate ist vorhanden). Für Entwicklungsbeteiligung fehlt mir aber leider auch das Perl-Wissen und im Moment die nötige Zeit. Beta-Tester könnte ich mir aber vorstellen :-)

                Gruß, Rico

                Kommentar


                  #9
                  Wir sind wohl gerade bei "Wünsch Dir was..."

                  Wenn's kein IMAP idle braucht, könnt Ihr folgende Module verwenden (sind imho auch im wiregate aktuell genug):
                  Net::IMAP::Simple (bzw. Net::IMAP::Simple::SSL) und Email::Simple

                  Hab das mal kurz mit gmx und gmail getestet... Abruf von Mails funktioniert wie in der verlinkten Übersicht beschrieben (code kann einfach kopiert werden).

                  Im Prinzip müsst Ihr dann nur noch nach Betreff/Absender filtern und den Inhalt parsen (ggf. timestamp merken oder wie bereits erwähnt Mail zum Schluss löschen).

                  Ein Großteil der notwendigen Arbeit ist tatsächlich schon in der verlinkten Dokumentation mit schönen Code-Beispielen aufbereitet!

                  Kommentar


                    #10
                    Hallo XueSheng,

                    Es dauert zwar noch ein bisschen bis Weihnachten ist, aber wenn die Leute jetzt schon alle ihre Weihnachtsdeko draußen haben, können wir ja schon mal mit "wünsch dir was" anfangen ;-)
                    Besten Dank für den Link. Da schaue ich dann am Wochenende mal genauer rein.

                    Gruß, Rico

                    Kommentar


                      #11
                      Das Net::IMAP::Simple des wiregate unterstützt leider noch kein Suchen von Mails. Müsste man also entweder aktualisieren oder eben "manuell" die Mails durchsuchen.

                      Nachfolgend mal ein proof of concept als wiregate plugin. Eigentlich als Plugin nicht wirklich geeignet, da die Laufzeit recht hoch sein kann (Reaktionszeit IMAP Server, etc.). Daher sollte man bei zyklischem Aufruf besser cron verwenden!
                      Das Plugin macht nichts anderes als die ungelesenen Mails zu prüfen und den Betreff von Mails mit gültigem Absender ins plugin_log zu schreiben.

                      Code:
                      ###############################################################################
                      ## Mail_imap.pl
                      ## v0.1 (2015-01-09), by XueSheng
                      ## 
                      ## Description:
                      ## Proof of concept. Fetch mails using imap.
                      ## Print Subject of unseen mails of allowed sender.
                      ##
                      ## Input:    - n.a.
                      ##
                      ## Output:   - n.a.
                      ###############################################################################
                      ## 
                      ## Dependencies:    - libnet-imap-simple-perl
                      ##                          - libnet-imap-simple-ssl-perl
                      ##                          - libemail-simple-perl
                      ##
                      ###############################################################################
                      ## ToDo:
                      ## - Find useful application ;)
                      ## - Documentation
                      ##
                      ###############################################################################
                      
                      # COMPILE_PLUGIN
                      
                      #$plugin_info{$plugname.'_cycle'} = 0;
                      #return "deactivated";
                      
                      ######################
                      ## begin definition ##
                      ######################
                      
                      # run cycle (daily)
                      $plugin_info{$plugname.'_cycle'} = 86400;
                      
                      # debug messages (0: off, 1: basic, 2: all)
                      my $debug = 2;
                      
                      # settings of mail account
                      my $user = 'user@domain.tld';
                      my $pass = 's3cuR3paSs';
                      my $server = 'imap.domain.com:993';
                      
                      # Filter for allowed sender of mails
                      my @allowed_from = ('sender1@domain.com', 'sender2@domain.com');
                      
                      ######################
                      ##  end definition  ##
                      ######################  
                      
                      use Net::IMAP::Simple::SSL;
                      use Email::Simple;
                      use Encode qw(decode);
                      
                      # Connect to imap server
                      my $imap = Net::IMAP::Simple::SSL->new($server, timeout => 5) || die "Unable to connect to IMAP: $Net::IMAP::Simple::errstr\n";
                      
                      # Login
                      if (!$imap->login($user, $pass)) {
                         die "Login failed: " . $imap->errstr . "\n";
                      }
                      
                      # Get number of messages in INBOX
                      my $total_messages = $imap->select('INBOX');
                      plugin_log($plugname, "total messages: $total_messages") if ($debug >= 2);
                      
                      # Print subjects
                      for (my $i = 1; $i <= $total_messages; $i++){
                          # skip seen messages
                          next if ($imap->seen($i));
                      
                          # parse mail header
                          my $es = Email::Simple->new(join '', @{ $imap->top($i) } );
                          my $subject = decode('MIME-Header', $es->header('Subject'));
                          my $from = $es->header('From');
                          plugin_log($plugname, "[$i] from: $from, subject: $subject") if ($debug >= 2);
                      
                          # check allowed sender and print subject of mail
                          my $pattern = join('|', @allowed_from);
                          if ($from =~ /$pattern/) {
                             plugin_log($plugname, "Mail allowed!") if ($debug >= 2);
                          }
                      }
                      
                      # Quit imap connection (Logout)
                      $imap->quit;
                      
                      plugin_log($plugname, "The End") if ($debug >= 2);
                      
                      return;
                      Mehr Hilfestellung kann ich aktuell nicht leisten (Zeit und Geld sind knapp ).

                      Kommentar


                        #12
                        Zunächst mal vielen dank für die Hilfestellung.
                        Leider bekomme ich dein Beispiel, nicht zum Laufen.

                        Ich bekomme folgende Fehlermeldung:

                        Can't locate Net/IMAP/Simple/SSL.pm in @INC (@INC contains: /usr/lib/perl-wiregate ../lib/perl-wiregate /etc/perl /usr/local/lib/perl/5.10.0 /usr/local/share/perl/5.10.0 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.10 /usr/share/perl/5.10 /usr/local/lib/site_perl .) at (eval 32371) line 52. BEGIN failed--compilation aborted at (eval 32371) line 52.

                        Kannst du weitere Tips geben was da los ist. Ich hoffe ich muss da nichts nachinstallieren und mit root-Zugang rummachen. Bin da nämlich der absolute DAU.

                        Grüße Sven

                        Kommentar


                          #13
                          Es scheint, als hättest Du die Abhängigkeiten nicht berücksichtigt. Folgende Pakete müssen auf dem wiregate installiert sein (sind im Repo, jedoch nicht default installiert).
                          Zitat von XueSheng Beitrag anzeigen
                          ## Dependencies: - libnet-imap-simple-perl
                          ## - libnet-imap-simple-ssl-perl
                          ## - libemail-simple-perl
                          Update:
                          Nur mal so am Rande... Pakete kannst Du auch über die Update Seite des Wiregate WebInterface installieren (ganz oben in die Textzeile die Paketnamen kopieren und auf den "Paket installieren" button drücken.). So schwer ist das eigentlich nicht.

                          Kommentar


                            #14
                            Das mit den Paketen hat super funktioniert. Habe es sogar geschafft den E-mail-Text in einen String zu bringen und hab den dann zerpflückt um bestimmte Wörter zu suchen. Was leider nicht funktioniert hat, ist die E-Mail dann zu löschen. Anscheinend ist die delete-Methode nicht in der...::SSL. In der Basisklasse ist sie aber vorhanden. Kann ich die Methode irgendwie benutzten? Das wird doch nach unten vererbt, oder nicht.
                            Weiter fehlen noch Prüfungen zum Datum. Da die Mail aber immer einen Tag vor Abholung kommt ist das mal nicht so schlimm. Werde auf jedenfalls noch weiter daran tüfteln.
                            Für Verbesserungsvorschläge bin ich dankbar, da ich vom programmieren nicht soviel Ahnung habe.

                            Code:
                            ###############################################################################
                            ## Mail_imap.pl
                            ## v0.1 (2015-01-09), by XueSheng
                            ## 
                            ## Description:
                            ## Proof of concept. Fetch mails using imap.
                            ## Print Subject of unseen mails of allowed sender.
                            ##
                            ## Input:    - n.a.
                            ##
                            ## Output:   - n.a.
                            ###############################################################################
                            ## 
                            ## Dependencies:    - libnet-imap-simple-perl
                            ##                          - libnet-imap-simple-ssl-perl
                            ##                          - libemail-simple-perl
                            ##
                            ###############################################################################
                            ## ToDo:
                            ## - Find useful application ;)
                            ## - Documentation
                            ##
                            ###############################################################################
                            
                            # COMPILE_PLUGIN
                            
                            #$plugin_info{$plugname.'_cycle'} = 0;
                            #return "deactivated";
                            
                            ######################
                            ## begin definition ##
                            ######################
                            
                            # run cycle (daily)
                            $plugin_info{$plugname.'_cycle'} = 86400;
                            
                            # debug messages (0: off, 1: basic, 2: all)
                            my $debug = 2;
                            
                            # settings of mail account
                            my $user = '********;
                            my $pass = '********';
                            my $server = 'imap.*******.com:993';
                            
                            # Filter for allowed sender of mails
                            my @allowed_from = ('', '');
                            
                            #GAs
                            my $GA_Restmuell = '6/5/0';
                            my $GA_gelbeTonne = '6/5/1';
                            my $GA_Altpapier = '6/5/2';
                            my $GA_Biomuell = '6/5/3';
                            ######################
                            ##  end definition  ##
                            ######################  
                            
                            use Net::IMAP::Simple;
                            use Net::IMAP::Simple::SSL;
                            use Email::Simple;
                            use Encode qw(decode);
                            
                            # Connect to imap server
                            my $imap = Net::IMAP::Simple::SSL->new($server, timeout => 5) || die "Unable to connect to IMAP: $Net::IMAP::Simple::errstr\n";
                            
                            # Login
                            if (!$imap->login($user, $pass)) {
                               die "Login failed: " . $imap->errstr . "\n";
                            }
                            
                            # Get number of messages in INBOX
                            my $total_messages = $imap->select('INBOX');
                            plugin_log($plugname, "total messages: $total_messages") if ($debug >= 2);
                            
                            # Print subjects
                            for (my $i = 1; $i <= $total_messages; $i++){
                                # skip seen messages
                                next if ($imap->seen($i));
                            
                                # parse mail header
                                my $es = Email::Simple->new(join '', @{ $imap->get($i) } );
                                my $subject = decode('MIME-Header', $es->header('Subject'));
                                my $from = $es->header('From');
                                plugin_log($plugname, "[$i] from: $from, subject: $subject") if ($debug >= 2);
                            
                                # parse mail body
                                my $text = $es->body;
                                #plugin_log($plugname, "[$i] Inhalt: $text") if ($debug >= 2);
                                my @words = split(' ', $text);
                                foreach my $word (@words) {
                            	#plugin_log($plugname, "$word") if ($debug >= 2);
                                    if ($word =~ /Restm/){
                            		plugin_log($plugname, "RESTMÜLL!!") if ($debug >= 2);
                            		knx_write($GA_Restmuell, 1, 1.001);
                            		last;
                            	}
                            	if ($word =~ /Gelbe/){
                            		plugin_log($plugname, "GELBE TONNE!!") if ($debug >= 2);
                            		knx_write($GA_gelbeTonne, 1, 1.001);
                            		last;
                            	}
                            	if ($word =~ /Biom/){
                            		plugin_log($plugname, "BIOMÜLL!!") if ($debug >= 2);
                            		knx_write($GA_Biomuell, 1, 1.001);
                            		last;
                            	}
                            	if ($word =~ /Altpapiertonne/){
                            		plugin_log($plugname, "ALTPAPIER!!") if ($debug >= 2);
                            		knx_write($GA_Altpapier, 1, 1.001);
                            		last;
                            	}	       
                                 }
                            
                                # check allowed sender and print subject of mail
                                my $pattern = join('|', @allowed_from);
                                if ($from =~ /$pattern/) {
                                   plugin_log($plugname, "Mail allowed!") if ($debug >= 2);
                                }
                                ################################
                                # delete e-mail after parsing
                                #$imap->deleted( $i );
                                ################################
                            }
                            
                            # Quit imap connection (Logout)
                            $imap->quit;
                            
                            plugin_log($plugname, "The End") if ($debug >= 2);
                            
                            return;

                            Kommentar


                              #15
                              Super, sieht doch garnicht schlecht aus.

                              Ein paar Anmerkungen von meiner Seite:
                              1. delete funktioniert deswegen nicht, weil Du es falsch geschrieben hast! So wird es gehen:
                                Code:
                                $imap->delete($i);
                                Falls Du die gelöschten Mails im Papierkorb sehen willst, musst Du vorher ein $imap->copy($i, 'Name des Papierkorbs'); durchlaufen lassen. Am besten immer mit Prüfung des Erfolgs und Ausgabe des "errstr", falls notwendig.
                              2. Die Prüfung des Absenders hast Du zum Teil rausgenommen (etwas halbgar). Entweder Du nimmst es ganz raus (config+code) oder Du implementierst es wieder an der richtigen Stelle.
                                Da die Mails vom Abfallverbund vermutlich immer von der gleichen Mailadresse stammen, würde ich die Überprüfung drin lassen! Dann aber bitte die Prüfung vor das Parsen des Mailtextes!
                                z.B.:
                                Code:
                                my $pattern = join('|', @allowed_from);
                                next if ($from !~ /$pattern/);
                              3. Bitte beim nächsten Update auch den Header des Plugins anpassen. Deine Anpassung ist nicht auf meinem Mist gewachsen, daher nimm ruhig Deinen Namen rein (gerne mit Verweis auf meine Vorarbeit) und aktualisiere eine fortlaufende Versionsnummer, damit es nicht zu Verwirrungen kommt.
                              4. Den täglichen Aufruf zu einer bestimmten Uhrzeit könntest Du so lösen (geht auch einfacher, aber damit deckst Du auch den Aufruf nach Speichern oder wiregated restart ab):
                                Code:
                                # run cycle
                                $plugin_info{$plugname.'_cycle'} = 0;
                                use POSIX 'strftime', 'mktime';
                                # Notification time (HH:MM)
                                my $notification_time = '18:00';
                                # get current time
                                my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();
                                
                                # update cycle time
                                my $timestamp_cycle;
                                my $cycle;
                                
                                if (($notification_time =~ /(\d+):(\d+)/) and (($timestamp_cycle = mktime(30,$2,$1,$mday,$mon,$year)) > time())) {
                                   $plugin_info{$plugname.'_cycle'} = $cycle = (sprintf('%.0f', $timestamp_cycle - time()) + 1);
                                   plugin_log($plugname, "[if] new cycle: $cycle, next run: ".localtime($timestamp_cycle)) if ($debug >= 2);
                                } else {
                                   $plugin_info{$plugname.'_cycle'} = $cycle = (sprintf('%.0f', $timestamp_cycle + 86400 - time()) + 1);
                                   plugin_log($plugname, "[else] new cycle: $cycle, next run: ".localtime($timestamp_cycle + 86400)) if ($debug >= 2);
                                }
                                
                                # stop evaluation if notification_time doesn't match (default 18:00)
                                if (($plugin_info{$plugname.'_lastsaved'} > $plugin_info{$plugname.'_last'}) or (!$plugin_initflag)) {
                                   # don't return on config update or wiregated restart
                                   plugin_log($plugname, "Force update (config update or wiregated restart)");
                                } elsif (($notification_time =~ /(\d+):(\d+)/) and ($hour != $1) or ($min != $2)) {
                                   plugin_log($plugname, "Notification time doesn't match ($notification_time), return") if ($debug >= 1);
                                   return;
                                }
                                Config und Code musst Du natürlich noch trennen. Der Code gehört dann an den Anfang vor den Abruf der Mail!



                              Update:
                              Net::IMAP::Simple::SSL läd übrigens Net::IMAP::Simple gleich mit! Daher musst Du nur eins davon laden! In Deinem fall also nur:
                              Code:
                              use Net::IMAP::Simple::SSL;

                              Kommentar

                              Lädt...
                              X