Auto Google Synctonization by Cron Job project

604 views
Skip to first unread message

Craig Tucker

unread,
Sep 30, 2015, 12:10:56 PM9/30/15
to Easy!Appointments - Support Group
One problem with syncing recurring appointments from google is that you need to have a daily update of the google calendar.  This must be done by a cron job.

For an example of how to set up EA to accurately sync recurring appointments see the build I am working on here:

In theory this should be easy.  Alex has a button for this on the back end.  I thought I could just run the function for that by command line but, I have not been successful with this.  So, I would appreciate any tips in how to get the sync sequence to start outside of the browser environment. 

Alex Tselegidis

unread,
Sep 30, 2015, 5:31:04 PM9/30/15
to easy-app...@googlegroups.com
Hi Craig, if you open the application/controllers/google.php file you will see that there is a "sync" method, which is actually the one called when pressing the button from the backend. 

What you can do is call a URL like "http://url-to-ea-installation.com/google/sync/<provider-id>/<secret-token>" where secret token is a string you can validate within the function like the following example: 

public function sync($provider_id = NULL, $secret_token) {
   
// Comment the following check ...
   
// $this->load->library('session');
   
// if ($this->session->userdata('user_id') == FALSE) return;    
   
   
if ($secret_token !== 'your expected secret token') return;


   
// continue with the sync code





Craig Tucker

unread,
Oct 1, 2015, 10:52:37 AM10/1/15
to Easy!Appointments - Support Group

I have restructured the function and tried When I try to pass it this way, apparently it clears the function and moves on to input.php but is missing the REMOTE_ADDR

Message:  Undefined index: REMOTE_ADDR
Filename: core/Input.php
Line Number: 352

Message:  Cannot modify header information - headers already sent by (output started at /volume1/web/craigtuckerlcsw/easy/system/core/Exceptions.php:186)
Filename: libraries/Session.php
Line Number: 691

Looking on StackOverflow I found a suggestion to change
 $_SERVER['REMOTE_ADDR'] with $this->server('remote_addr') at the line that generates the notice. - modify /system/core/Input.php line 351

With this change it appears to work. 

Regarding the secret_token, should this be a randomly generated token that I create each time I run the sync?  Is the token necessary if I run this sequence within google.php?
For example if I set up a function like this (I know It is not complete):

public function syncall() {
 //get the array of providers:
  $this
->load->model('providers_model');
  $providers
= $this->providers_model->get_available_providers();
 //for each providers as provider run google sync
 
foreach ($providers as $provider) {
   $this->config->base_url().'sync/'.$provider
 }
 
}


 

Craig Tucker

unread,
Oct 2, 2015, 2:19:48 PM10/2/15
to Easy!Appointments - Support Group
This works.  It does not integrate the token yet.  I am not sure how to do that.  I will need to educate myself.  I am sure it would make the process more secure but for now this will work:

I created three levels of syncronization, one that is a full sync by button (slow, for me about 1:30 to cover 61 days of a full calendar), one that will just sync the appointment (fast, the one Alex started with), and one that will sync all providers for the automatic CLI cron job.  I am also making that 61 days (slow) but I am keeping it flexible. I choose 61 because it is one day beyond the view for my clients.  If there is an error in my server then I have a day of padding. 

The following changes were necessary:

To allow for CLI to talk to the server, modify /system/core/Input.php line 351
$_SERVER['REMOTE_ADDR'] with $this->server('remote_addr').

In  /assets/js/backend_calendar.js I changed this portion of code to sync with sync2 instead of sync, for example:      

$('#google-sync').click(function() {
           
var getUrl = GlobalVariables.baseUrl + '/index.php/google/sync2/' + $('#select-filter-item').val();

In /application/libraries/google_sync.php
Under:  $params = array(
Add:   'singleEvents' => true,  //allows recurring appointments to show up as individual appointments

I added a function to providers_model.php
     function get_all_provider_ids() {
  $results
= array('id' =>
   $this
->db->select('id as id')
   
->from('ea_users')
   
->where('id_roles', 2)
   
->get()
   
->row()
   
->id
   
);
 
return $results;
 
}

I have made significant changes to /application/controllers/google.php.  I am attaching that file.

To launch by command line:
php /<path to EA installation>/index.php google/sync3
in crontab (which for me is at /etc/crontab) you will add the following line for auto sync at 11:30 pm:  It can sync every hour if you like. 
30  23  *   *   *   php   /<path to EA installation>/index.php google/sync3


Things left to be done:
adding a secret token for security

As it is, the worst that could happen is that someone could make it sync more often.  So, as is I can deal with this.

Craig Tucker

unread,
Oct 2, 2015, 2:21:44 PM10/2/15
to Easy!Appointments - Support Group
This is a copy of the modifications I made to google.php
google.php

Gideon Duwel

unread,
Oct 14, 2015, 9:16:39 AM10/14/15
to Easy!Appointments - Support Group
Hello Craig,

Thanx for your explanation. I made the changes, the only thing i don't understand is the cronjob setting. Is it possible to call an url to test the auto-sync? (i mean wwithout logging in to the admin-section)

Craig Tucker

unread,
Oct 15, 2015, 10:35:29 PM10/15/15
to Easy!Appointments - Support Group
Yes, if you log in to your server with a terminal like PuTTY.  On my system I execute a line that looks something like this where path to EA is your path:

bash-3.2# php /<path to EA>/index.php google/sync3


This will execute the sync3 function in the google.php controller.

I also modified my sync3 function even more with this to make it a much more secure.  This allows it only to be called from the server.  Also I added an email code to tell me if the sync was completed that night you will need to enter your email address for this to work.  This may help you.


 public function sync3() {
  if(!$this->input->is_cli_request()) {
   echo "This script can only be accessed via the command line" . PHP_EOL;
   return;
  }
  $this->load->library('email');

  $this->load->model('providers_model');
  $providers = NULL;
  $provider_id = NULL;
  $providers = $this->providers_model->get_all_provider_ids();
  
     /**
  * Variables for full sync with google caldnear when CLI initiates sync from cron job.
  * Based on Amine Hamdi  https://groups.google.com/forum/#!searchin/easy-appointments/sync_past_days/easy-appointments/
  */
  $full_sync_past_days = 0;  //limits sync x# of days to prior to today
  $full_sync_future_days = 62; //Limits the sync period to x# of days after today 
  foreach ($providers as $provider_id) {
   $this->syncgoogle($provider_id, $full_sync_past_days, $full_sync_future_days);
  }
   $config['mailtype'] = 'text';
  $this->email->initialize($config);
  $this->email->to('<put your to email address here>');
  $this->email->from('<put your from email address here>', 'Sync Update');
  $this->email->subject('sync complete');
  $this->email->message('sync db completed '. date('h:i:sa'));
  $this->email->send();
 }


Reply all
Reply to author
Forward
0 new messages