Ankündigung

Einklappen
Keine Ankündigung bisher.

Google Calendar - update für "neue" GoogleAPI

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    Google Calendar - update für "neue" GoogleAPI

    Hallo zusammen,

    nach mehrere Gläsern Rotwein und ausgiebigem Googlen (welche Ironie…) ist es mir nun gelungen, die „neue“ Google Calendar API zum Laufen zu bringen.
    Leider sind hier noch ein „paar" manuelle Schritte beim Konfigurieren notwendig, daher ist die Lösung m.E. noch nicht ganz rund.
    Aber das ist zum Glück nur einmalig (!) erforderlich, dann nicht mehr.

    Ich versuche hier mal den Weg aufzuschreiben, jede Vereinfachung ist willkommen…

    Vorarbeiten bei Google:
    1. Anmelden bei der Google Developer console: https://console.developers.google.com
    2. erstellen eines „Projektes“ -> heisst bei mir einfach API Project, ist aber egal
    3. Dann links „APIs“ auswählen und die „Calendar API“ einschalten.
    4. Dann links „Zugangsdaten“ auswählen und „Neue CliendID erstellen"
    5. Wichtig: hier „Installierte Anwendung“ auswählen, NICHT Webanwendung (!) - sonst muss man jedesmal ein Popup bestätigen, was den WAF definitiv nach unten treibt…
    6. dann den „Zustimmungsbildschirm“ so konfigurieren, wie man es möchte - ist aber eigentlich egal, nur ein Projekt muß drinstehen.
    7. Dann wieder „Installierte Anwendung“ und bei Anwendungstyp „sonstige“ auswählen und endlich „Client ID erstellen“.
    8. Damit tauchen jetzt in der Dev.Console die „Client-ID“, „Clientschlüssel“ und „Weiterleitung-URI“ auf - die brauchen wir gleich.


    Der Access an sich ist damit konfiguriert - der Trick ist nun, einen „Authorization Code“ und "RefreshToken“ zu erzeugen:
    1. Die Werte für „ClientID“ und „redirect-URI“ in das script „google_1.php“ eintragen und das script ausführen mit
      Code:
      php -q google_1.php
    2. Zurück kommt eine URL, diese im Browser aufrufen. Es erscheint die berühmte Bestätigungsseite, hier bestätigen und Voila, es erscheint der Auhorization Code.
    3. Den also nun merken und in das script google_2.php als „code“ eintragen (ebenso wie ClientID, ClientKey und redirect_URI)
    4. Das script ausführen mit
      Code:
       php -q google_2.php
      und das Ergebnis ist der ersehnte Refresh Token. Diesen merken, den brauchen wir.


    Die ganze Übung oben muss man zum Glück nur einmal machen, mit dem Refresh Token kann man immer wieder einen AuthorizationToken erzeugen.
    Die scripte also irgendwo hinlegen aber nicht vergessen…
    (Herzlichen Dank auch an Google und diese tolle OAuth. /ironie off )

    Wichtig also nun das googeV3.php, dieses in
    Code:
    /var/www/smartvisu/lib/calendar/service/googleV3.php
    legen und die Werte eintragen (ClientID, ClientSecret, Redirect_URI, RefreshToken). Das googleV3.php basiert auf dem google.php von Martin, ist halt erweitert um die Generierung des AuthTokens.

    Dann in der Smartvisu-Config noch googleV3 statt google auswählen und freuen !

    Zum Glück muss man die Konfig-Orgie oben nur einmal machen (außer man ändert den Authorization Code…), aber eigentlich könnte das auch automatisch gehen.
    Meine Vorstellung wäre, die Werte für ClientID,ClientSecret und WeiterleitungsURI in der Smartvisu-Configseite einzugeben und die berechnung auf Knopfdruck zu machen. Den PopUp kann man dann ja bestätigen.
    Die GUI mit den Feldern kriege ich noch hin, für den Rest fehlt mir aber schlicht und ergreifend das PHP-Knowhow bzw. der smartvisu-Kontext. (Bis vor zwei Tagen konnte ich PHP nichtmal fehlerfrei buchstabieren, geschweige denn verstehen…)

    Noch ein anderer Punkt zum Optimieren und eigentlich wichtiger: Das AuthToken ist eigentlich 3600 sec. gültig - aktuell wird es aber jedes Mal neu angefragt. Das dauert unnötig lang, eigentlich sollte man das cachen und nur bei Bedarf neu anfragen. Auch hier - ich hab’ einfach keine Ahnung, wie das hier gehen könnte…

    Schaut Euch das doch mal an und testet ausführlich - Bei mir funzt es bislang ohne Probleme !

    Viele Grüße - Carsten



    Was also jetzt geht (zumindest bei mir):
    • normale Termine innerhalb eines Tages
    • Ganztagestermine
    • Multi-Day Termine
    • Farbe wird vom Termin im google Calendar übernommen, sofern fort gesetzt. Ist aber in der Beschreibung des Termins @color enhalten, geht das vor.
    • Ein Icon kann über eine Zeile in der Beschreibung gesetzt werden mit @icon
    • Sommer/Winterzeit wird entsprechend berücksichtigt, sofern (WICHTIG!) die Zeitzone auf dem smartvisu stimmt.
    • Der count kann im calenda-widget gesetzt werden und wird ausgewertet
    • Der Kalendername (typischerweise "primary") wird auf der Config-seite der smartvisu gesetzt im Feld "URL"
      • Wichtig dabei: hier wirklich NUR "primary" eintragen, nicht die ganze URL !!!



    PS: Die Anhänge funktionieren irgendwie nicht, hier also der code...

    google_1.php:
    PHP-Code:
    <?php
    $scope         
    =   'https://www.google.com/calendar/feeds/';
    $client_id      =   '';   // insert your client ID from Google Developer console (web)
    $redirect_uri   =   '';   // insert your redirect URI here (first line only)

    $params = array(
                        
    'response_type' =>   'code',
                        
    'client_id'     =>   $client_id,
                        
    'redirect_uri'  =>   $redirect_uri,
                        
    'scope'         =>   $scope
                        
    );
    $url 'https://accounts.google.com/o/oauth2/auth?' http_build_query($params);        
    echo 
    $url."\n";
    ?>

    google_2.php:
    PHP-Code:
    <?php
    $url 
    'https://accounts.google.com/o/oauth2/token';
    $post_data = array(
                        
    'code'          =>   '',    // insert the code here that was shown after calling the URL from google_1.php
                        
    'client_id'     =>   '',    // insert your client ID here
                        
    'client_secret' =>   '',    // insert your client secret here
                        
    'redirect_uri'  =>   '',    //insert your redirect URI here (first line only)
                        
    'grant_type'    =>   'authorization_code',
                        );
    $ch curl_init();

    curl_setopt($chCURLOPT_URL$url);
    curl_setopt($chCURLOPT_POST1);
    curl_setopt($chCURLOPT_POSTFIELDS$post_data);
    curl_setopt($chCURLOPT_RETURNTRANSFERtrue);

    $result curl_exec($ch);
    $token json_decode($result);

    echo 
    $token->refresh_token "\n";
    ?>

    und hier die googleV3.php:
    PHP-Code:
    <?php
    /**
     * -----------------------------------------------------------------------------
     * @package     smartVISU
     * @author      Martin Gleiß, updated by Carsten Gotschlich for google API V3
     * @copyright   2012
     * @license     GPL [http://www.gnu.de]
     * -----------------------------------------------------------------------------
     */

    // Note: for debugging purposes you can execute this script from commandline with    php -q <scriptname>

    require_once '../../../lib/includes.php';
    require_once 
    const_path_system.'calendar/calendar.php';


    /**
     * This class reads a google calenda
     */
    class calendar_google extends calendar
    {

        
    /**
         * initialization of some parameters
         */
        
    public function init($request)
        {
            
    parent::init($request);
            if (
    $this->url == '')
                
    $this->url 'primary';
            if (
    $this->count == 0)
                
    $this->count 10;
        }

        
    /**
         * Check if the cache-file exists
         */
        
    public function run()
        {
            
    //---------------------------------------------------------------------
            // let's define some parameters - they need to be fetched manually
            
    $client_id      =   '';  // put your clientID here - from Google website
            
    $client_secret  =   '';        // put your client Secret here - from Google WebSitr
            
    $redirect_uri   =   '';    // put your redirect URI here from Google Website - only first line !

            
    $refresh_token  =   '';    // Put your google refresh token here - from other PHP script
            
    $calendar_id     =   $this->calendar;    // get it this way: http://googleappstroubleshootinghelp.blogspot.de/2012/09/how-to-find-calendar-id-of-google.html  
            //---------------------------------------------------------------------
            // get access token first
            
    $token_url 'https://accounts.google.com/o/oauth2/token';
            
    $post_data = array(
                            
    'client_secret' =>   $client_secret,
                            
    'grant_type'    =>   'refresh_token',
                            
    'refresh_token' =>   $refresh_token,
                            
    'client_id'     =>   $client_id
                            
    );
            
    $ch curl_init();

            
    curl_setopt($chCURLOPT_URL$token_url);
            
    curl_setopt($chCURLOPT_POST1);
            
    curl_setopt($chCURLOPT_POSTFIELDS$post_data);
            
    curl_setopt($chCURLOPT_RETURNTRANSFERtrue);

            
    $result curl_exec($ch);
            
    $token_object json_decode($result);
            
    $access_token $token_object->access_token;

            
    //---------------------------------------------------------------------
            // so now we have an access-token, let's use it to access the calendar
            
    $context stream_context_create(array('http' => array('method' => "GET"'header' => "Authorization: OAuth " $access_token)));
            
            
    // first let's retrieve the colors
            
    $resturl 'https://www.googleapis.com/calendar/v3/colors';
            
    $content = @file_get_contents($resturlfalse$context);
            
    $colors = array();
            if (
    $content !== false)
            {
                
    $result json_decode($content,true);
                
    $colors $result["event"];
                
    // var_dump($colors);
            
    }
            
            
    // then retrieve the calendar entries
            
    $resturl 'https://www.googleapis.com/calendar/v3/calendars/'$this->url '/events?maxResults='$this->count .'&singleEvents=true&orderBy=startTime&timeMin='.urlencode(date('c'));
            
    $content = @file_get_contents($resturlfalse$context);
            
    $this->debug($content);

            
    // for debugging purposes only
            // echo $content;
            // echo "###########";

            
    if ($content !== false)
            {
                
    $result json_decode($content,true);

                
    $i 1;

                foreach (
    $result["items"] as $entry)
                {
                    
    $startstamp = (string)($entry["start"]["dateTime"]);
                    
    $endstamp = (string)($entry["end"]["dateTime"]);
                    if (
    $startstamp == '')
                        
    $startstamp = (string)($entry["start"]["date"]);
                    if (
    $endstamp == '')
                        
    $endstamp = (string)($entry["end"]["date"]);
                    
    $start strtotime($startstamp);
                    
    $end   strtotime($endstamp);
                            
                    
    $color '';
                    if (((string)(
    $entry["colorId"]))!='')
                        
    $color=$colors[(string)($entry["colorId"])]["background"];
                    
                    
    $this->data[] = array('pos' => $i++,
                        
    'start' => date('y-m-d'$start).' '.date('H:i:s'$start),
                        
    'end' => date('y-m-d'$end).' '.date('H:i:s'$end),
                        
    'title' => (string)($entry["summary"]),
                        
    'content' => (string)($entry["description"]),
                        
    'where' => (string)($entry["location"]),
                        
    'color' => $color,  
                        
    'link' => (string)($entry["htmlLink"])
                    );
                }
                            
            }
            else
                
    $this->error('Calendar: Google''Calendar read request failed!');
        }
    }


    // -----------------------------------------------------------------------------
    // call the service
    // ----------------------------------------------------------------------------

    //

    $service = new calendar_google(array_merge($_GET$_POST));
    echo 
    $service->json();
    ?>
    Angehängte Dateien
    Zuletzt geändert von CarGo; 22.04.2015, 17:22. Grund: aktuelle Versionen angehängt

    #2
    Hallo Carsten,

    wow, jetzt schon danke. Ich befürchte, ich werd erst am Wochenende dazukommen, das bei mir zu testen, aber ich freu mich schon drauf!

    Gruß
    Markus

    Kommentar


      #3
      Jipieeee es funktioniert :-)

      lediglich einen kleinen Fehler hab ich gefunden :-)

      in deiner google2.php

      müssen in Zeile 4 bis 8 keine Semikolons sondern nur Kommas hin :-)

      Ansonsten alles Tippi toppi und vielen Dank dafür

      Kommentar


        #4
        @SachsenTobi,

        supi, danke für den Hinweis - da war ich beim Entfernen meiner Inhalte wohl etwas übereifrig...
        Ich habe den Anhang im ersten Post direkt aktualisert.

        Viele Grüße - Carsten

        Kommentar


          #5
          Jetzt wäre für mich nur noch interessant, wie ich da verschiedene Symbole mit hinbekomme :-)

          Damit es auch ne gelbe Tonne bspw mit anzeigt :-)

          Kommentar


            #6
            Hallo,

            sollte eigentlich kein Problem sein, das wird gesteuert durch den Text im Termin.
            Als Beispiel: Bei mir benutze ich folgende Einträge für die Tonnen (das ist jeweils Betreff und Inhalt eines Kalendereintrags):

            Code:
            Papiertonne
            @icon        icons/ws/message_garbage.png
            @color       #333399
            
            braune tonne
            @icon        icons/ws/message_garbage.png
            @color       #664422
            
            Restmüll - schwarze Tonne
            @icon        icons/ws/message_garbage.png
            @color       #555555
            
            Gelbe Tonne
            @icon        icons/ws/message_garbage.png
            @color       #666600
            
            Biotonne
            @icon        icons/ws/message_garbage.png
            @color       #009900

            Viele Grüße - Carsten

            Kommentar


              #7
              Es funktioniert perfekt.

              Vielen lieben Dank

              Weist du auch zufällig noch, wo ich das Datumsformat welches da angezeigt wird ändern kann? Ich möchte da gern 10. Dezember 2014 stehen haben und nicht 12/10/14

              Danke

              Kommentar


                #8
                Hallo,

                hm, bei mir steht da z.B ."Samstag, 20.12.14 08:00 - 12:00"...
                Schau doch mal, ob Du ein language file für Deutsch hast:
                Code:
                /var/www/smartvisu/lang/lang_de.txt
                Da sollte sich dann folgende Zeile finden, die das Datumsformat definiert:
                Code:
                $lang['format']['short']                        = 'd.m.y H:i';
                Sieht bei Dir aktuell wohl eher nach US-Default aus...
                Hope this helps !

                Viele Grüße - Carsten

                Kommentar


                  #9
                  Das war es tatsächlich,

                  wieder mal vielen Dank.

                  Kommentar


                    #10
                    Zitat von CarGo Beitrag anzeigen
                    1. Zurück kommt eine URL, diese im Browser aufrufen. Es erscheint die berühmte Bestätigungsseite, hier bestätigen und Voila, es erscheint der Auhorization Code.

                    Wenn ich diese URL in den Browser eingebe kommt leider immer ein 401 oder 400 Fehler.


                    EDIT: Funkt schon. Falls das noch wer hat. Habe beim Punkt davor meine E-Mail nicht ausgewählt.

                    Kommentar


                      #11
                      Moin,

                      erst mal vielen Dank für die Umsetzung, ich habe aber ein etwas merkwürdiges Verhalten festgestellt.

                      Ich habe in meinem Google Account mehrere Kalender definiert und habe mir die XML-URL vom "Müllkalender" herauskopiert.
                      Wenn ich die URL direkt im Browser aufrufe bekomme ich auch die richtigen Einträge im XML zurück.

                      Trage ich die URL in meine Smartvisu ein, so bekomme ich ganz andere Termine (aus anderen Kalendern) angezeigt.

                      Kann das jemand nachvollziehen, oder hab ich gerade einfach n Brett vorm Kopf warum das so sein könnte?


                      EDIT: ich glaube ich hab das Problem gefunden, momentan wird immer der "primary" Kalender abgerufen, und der ist natürlich nicht der den ich brauche.
                      Die URL im Smartvisu ist mit der V3 Lösung soweit ich das erkennen kann überflüssig

                      Grüße,

                      Lars

                      Kommentar


                        #12
                        Hallo Lars,

                        wie Du richtig geschrieben hast, wird die URL der ConfigSeite aktuell ignoriert. Relevant ist der Key, den Du wie beschrieben generiert hast...

                        Viele Grüße - Carsten

                        Kommentar


                          #13
                          Der Key ist ja für das OAuth relevant, ich hab mir aber die API mal angesehen und dann die "googleV3" modifiziert so das es jetzt mit dem gewünschten Kalender funktioniert. (siehe: https://developers.google.com/google...ce/events/list)

                          Theoretisch könnte man halt auch das Feld weiter benutzen und die URL aus dem GET Request auf den Service rausholen, aber mir reichte das an der Stelle "quick & dirty". Alternativ noch zusätzlich das Calendar-Widget modifizieren, dass man mehrere verschiedene Kalender einbinden könnte. ;-)


                          Hinzugekommen ist die Konfiguration der Calendar ID (Google Apps Troubleshooting Help: How to find the Calendar ID of a Google Calendar)

                          Welche dann in der API URL Verwendung findet:

                          PHP-Code:
                          <?php
                          /**
                           * -----------------------------------------------------------------------------
                           * @package     smartVISU
                           * @author      Martin Gleiß, updated by Carsten Gotschlich got google API V3
                           * @copyright   2012
                           * @license     GPL [http://www.gnu.de]
                           * -----------------------------------------------------------------------------
                           */


                          require_once '../../../lib/includes.php';
                          require_once 
                          const_path_system.'calendar/calendar.php';


                          /**
                           * This class reads a google calenda
                           */ 
                          class calendar_google extends calendar
                          {

                              
                          /**
                               * initialization of some parameters
                               */
                              
                          public function init($request)
                              {
                                  
                          parent::init($request);
                              }

                              
                          /**
                               * Check if the cache-file exists
                               */
                              
                          public function run()
                              {
                                  
                          //---------------------------------------------------------------------
                                  // let's define some parameters - they need to be fetched manually
                                  //---------------------------------------------------------------------
                                  
                          $client_id      =   '';  // put your clientID here - from Google website
                                  
                          $client_secret  =   '';  // put your client Secret here - from Google WebSite
                                  
                          $redirect_uri   =   '';     // put you redirect URI here from Google Website - only first line !

                                  
                          $refresh_token  =   '';  // Put your google refresh token here - from other PHP script
                                  
                          $calendar_id ''// get it this way: http://googleappstroubleshootinghelp.blogspot.de/2012/09/how-to-find-calendar-id-of-google.html
                                  //---------------------------------------------------------------------
                                  // get access token first 
                                  
                          $token_url 'https://accounts.google.com/o/oauth2/token';
                                  
                          $post_data = array(
                                                  
                          'client_secret' =>   $client_secret,
                                                  
                          'grant_type'    =>   'refresh_token',
                                                  
                          'refresh_token' =>   $refresh_token,
                                                  
                          'client_id'     =>   $client_id
                                                  
                          );
                                  
                          $ch curl_init();

                                  
                          curl_setopt($chCURLOPT_URL$token_url);
                                  
                          curl_setopt($chCURLOPT_POST1);
                                  
                          curl_setopt($chCURLOPT_POSTFIELDS$post_data);
                                  
                          curl_setopt($chCURLOPT_RETURNTRANSFERtrue);

                                  
                          $result curl_exec($ch);
                                  
                          $token_object json_decode($result);
                                  
                          $access_token $token_object->access_token;

                                  
                          //---------------------------------------------------------------------
                                  // so now we have an access-token, let's use it to access the calendar
                                  
                          $context stream_context_create(array('http' => array('method' => "GET"'header' => "Authorization: OAuth " $access_token)));
                                  
                          $resturl 'https://www.googleapis.com/calendar/v3/calendars/'$calendar_id '/events?maxResults=5&singleEvents=true&orderBy=startTime&timeMin='.urlencode(date('c'));
                                  
                          $content = @file_get_contents($resturlfalse$context);
                                  
                          $this->debug($content);

                                  if (
                          $content !== false)
                                  {
                                      
                          $result json_decode($content,true);

                                      
                          $i 1;

                                      foreach (
                          $result["items"] as $entry)
                                      {
                                          
                          $startstamp strtotime($entry["start"]["dateTime"]) + date("Z"$entry["start"]["dateTime"]);
                                          
                          $endstamp strtotime($entry["end"]["dateTime"]) + date("Z"$entry["end"]["dateTime"]);
                                          
                          $this->data[] = array('pos' => $i++,
                                              
                          'start' => date('y-m-d'$startstamp).' '.gmdate('H:i:s'$startstamp),
                                              
                          'end' => date('y-m-d'$endstamp).' '.gmdate('H:i:s'$endstamp),
                                              
                          'title' => (string)($entry["summary"]),
                                              
                          'content' => (string)($entry["description"]),
                                              
                          'where' => (string)($entry["location"]),
                                              
                          'link' => (string)($entry["htmlLink"])
                                          );
                                      }
                                  }
                                  else
                                      
                          $this->error('Calendar: Google''Calendar read request failed!');
                              }
                          }


                          // -----------------------------------------------------------------------------
                          // call the service
                          // ----------------------------------------------------------------------------

                          $service = new calendar_google(array_merge($_GET$_POST));
                          echo 
                          $service->json();

                          ?>

                          Grüße,

                          Lars

                          Kommentar


                            #14
                            Hilfe

                            Servus,

                            vielleicht kann mir jemand von Euch weiterhelfen.

                            Ich komme mit der Anleitung von Post 1 genau bis zur Ausführung vom Google_2.php

                            Also die Google_2.php hab ich mit meinen sachen angepasst.

                            PHP-Code:
                            <?php
                            $url 
                            'https://accounts.google.com/o/oauth2/token';
                            $post_data = array(
                                                
                            'code'          =>   '6/blablabla_blubblubblub.zahlenundbuchstaben',    // insert the code here that was shown after calling the URL from google_1.php
                                                
                            'client_id'     =>   'zahlen-zahlenundbuchstaben.apps.googleusercontent.com',    // insert your client ID here
                                                
                            'client_secret' =>   'blabla-blubblub',    // insert your client secret here
                                                
                            'redirect_uri'  =>   'urn:blub:bla:oauth:2.0:oob',    //insert your redirect URI here (first line only)
                                                
                            'grant_type'    =>   'authorization_code',
                                                );
                            $ch curl_init();

                            curl_setopt($chCURLOPT_URL$url);
                            curl_setopt($chCURLOPT_POST1);
                            curl_setopt($chCURLOPT_POSTFIELDS$post_data);
                            curl_setopt($chCURLOPT_RETURNTRANSFERtrue);

                            $result curl_exec($ch);
                            $token json_decode($result);

                            echo 
                            $token->refresh_token "\n";
                            ?>
                            wenn ich das im Chrome ausführe passiert einfach nichts, und über die Console kommt:

                            Trying to get property of non-objekt in google_2.php line 20

                            Ich hab das Prozedere jetzt schon 5 mal durch, hab auch schon die Client ID gelöscht und ne neue gemacht, dann natürlich mit den neuen Daten die google_1.php befüllt, aber das Ergebnis ist immer das selbe.

                            Bin für jeden Rat dankbar.

                            Gruß Wolfi

                            Kommentar


                              #15
                              probier es wenn möglich mal auf einem anderen system auszuführen

                              Kommentar

                              Lädt...
                              X