通过运行php脚本(CI控制器)作为cronjob在特定用户的Google日历中插入新事件(使用PHP API)>> [

问题描述 投票:2回答:1
我正在开发一个小型应用程序,一旦初始日期更改,该应用程序需要更新某些事件(法院开庭)。用户可以通过访问其应用程序帐户将此类事件手动插入其Google日历中。插入后,该应用程序将监视任何更改(针对公共API),并且一旦发生更改,它将更新数据库,并将向用户发送电子邮件通知该更改并将此类新事件插入其Google日历中。 >

我正在使用PHP和CodeIgniter 3.11。

每天都会根据公共API验证任何更改,并且很明显,当发生更改时,用户就不会出现在计算机前。这是在特定时间运行的cronjob的帮助下完成的。

事件在用户的Google日历中的初始插入可以正常运行,就像用户从浏览器中手动进行的一样。但是我在运行用于监视cronjob下的更改的控制器时插入此类事件时遇到问题。我正在使用自己的Gmail帐户对其进行测试。

cronjob确实起作用,因为控制器执行了其他两项任务(更新数据库和发送电子邮件),没有任何问题。但是更新日历永远不会发生。仅当通过浏览器再次运行控制器时,日历才会更新。进行监视的控制器负责设置oauth url并重定向到该url。然后,我有另一个控件(位于redirect_uri后面),应该接收访问代码和状态。

我已将访问类型设置为离线,如Google文档所建议的Google PHP API Docs

$client->setAccessType('offline');

并且我已经保存并使用了刷新令牌,当根据Google文档不存在用户时,该令牌可用于获取访问代码。

在我看来,以cronjob身份运行时,从未更新负责更新日历的控制器(在Google oauth客户端配置中设置为redirect_uri)。有人说我的问题是:

    是否有可能实现此目的,即,当用户不在浏览器中时,在用户的Google日历中插入新事件? Google文档暗示了这种可能性,但没有详细说明如何实现。引用文档:

  1. 对于不存在用户时需要访问Google API的任何应用程序,要求进行离线访问。例如,在用户不存在时执行备份服务或在预定时间执行操作的应用需要能够刷新其访问令牌。


    1. 我的方法基于使用刷新令牌是正确的,还是我需要执行其他任务才能实现Google日历的更新?

  2. [当以cronjob身份运行时,如何找到我的控制器正在重定向到google服务器?
  3. 是否有任何服务器日志可以检查Monitor.php中设置的重定向是否正常工作?我有检查了Apache日志,但似乎没有出现任何错误。 codeigniter日志不显示任何还是有错误。

  4. 我如何才能找到负责更新的控制器,是由Google发送的响应到达的服务器,那有访问代码?如果Google响应到达控制器,是否有任何方法可以调试在redirect_uri后面?
  5. 如果您对如何实现此目标还有其他建议,则非常欢迎。

    非常感谢!

    下面是我的一些代码:Monitor.php(控制器作为cronjob运行)

    <?php defined('BASEPATH') or exit('No direct script access allowed'); /** * Class Monitor */ class Monitor extends CI_Controller { public function __construct() { parent::__construct(); $this->load->helper("utilities", "url"); $this->load->model("users"); $this->load->model("files"); // $this->load->library("portal"); require_once APPPATH . 'libraries/Portal.php'; require_once 'vendor/autoload.php'; } public function index() { if (!is_cli()) { return; } $files_query = $this->files->get_all_files(); if (is_array($files_query)) { $files = array(); foreach($files_query as $file_query) { array_push($files, $file_query['file_number']); } $files = array_values(array_unique($files)); //print_r($files); foreach ($files as $file) { $email_body = ""; $portal = new Portal($file); $portal->set_courtfile_data(); if (empty($portal->error)) { $court_file = $portal->court_file; //obtaining the court file $termen = $portal->get_last_hearing(); // obtaining the hearing $solutie = $portal->get_solutie(); //obtaining the existing solutions if (is_array($solutie)) { $solutie = $solutie['final']; } $court = $portal->get_court(); //obtaining the court $stadiu = $portal->get_courtfile_stage(); //obtaining the stage if (!$stadiu["apel"]) { $stadiu = $stadiu["stadiu"]; } else { $stadiu = $stadiu["apel"]; } ####--- various checks made against the result retrieve from the public API ---#### ...... if ($email_body !== "") { $emails = $this->get_user_email($file); // Sending the e-mail to the user; $template_id = $this->config->item('sendgrid_change_template'); $dynamic_data = [ "file" => $file, "change_body" => $email_body ]; foreach ($emails as $email) { send_grid_email($email, $template_id, $dynamic_data); } if ($hearing_query) { ###--- function for setting the google auth url ---#### $url = $this->set_google_url($court_file); try { header('Location: ' . $url); //redirect($url); } catch (Exception $e) { log_message('error', $e['message']); } } } } // End of foreach loop } else { $error = $this->db->error(); log_message("error", $error["message"]); } }// End of index function #### -- function used to set the google oauth url ---### protected function set_google_url($file) { $client = new Google_Client(); try { $client->setAuthConfig(APPPATH . 'credentials.json'); $client->setApplicationName('Monitor App'); $client->setRedirectUri($this->config->item('update_calendar_url')); $client->setScopes(Google_Service_Calendar::CALENDAR); $client->setState($file); $client->setAccessType('offline'); $client->setApprovalPrompt('auto'); $auth_url = $client->createAuthUrl(); return filter_var($auth_url, FILTER_SANITIZE_URL); } catch (Exception $e) { log_message('error', $e['message']); return false; } }

Update_google.php(redirect_uri后面的控制器)

<?php defined('BASEPATH') or exit('No direct script access allowed'); class Update_google extends CI_Controller { public function __construct() { parent::__construct(); $this->load->helper("utilities"); $this->load->model(array("files", "users")); require_once 'vendor/autoload.php'; } public function index() { $query = $this->users->get_user_by("[[email protected]]", "email"); if ($query) { $refresh_token = $query[0]["refreshToken"]; } try { $client = new Google_Client(); $client->setAuthConfig(APPPATH . 'credentials.json'); $client->setRedirectUri($this->config->item('update_calendar_url')); if (isset($_GET['state']) && isset($_GET['code'])) { $token = $client->fetchAccessTokenWithAuthCode($_GET['code']); } else { if ($refresh_token != null) { $token = $client->fetchAccessTokenWithRefreshToken($refresh_token); } } $client->setAccessToken($token); $file = filter_var($_GET['state'], FILTER_SANITIZE_STRING); $query = $this->files->get_file_by($file, "file_number"); if (is_array($query)) { $service = new Google_Service_Calendar($client); $event = new Google_Service_Calendar_Event(array( 'summary' => 'Termen instanță', 'location' => $query[0]['court'], 'description' => 'Termen în dosarul ' . $query[0]['file_number'], 'start' => array( 'dateTime' => $query[0]['last_hearing'] . 'T08:30:00', 'timeZone' => 'Europe/Bucharest', ), 'end' => array( 'dateTime' => $query[0]['last_hearing'] . 'T12:00:00', 'timeZone' => 'Europe/Bucharest', ), )); $calendarId = 'primary'; $service->events->insert($calendarId, $event); } } catch (Exception $e) { log_message('error', $e['message']); } } }

我正在开发一个小型应用程序,一旦初始日期更改,该应用程序需要更新某些事件(法院开庭)。用户可以通过手动访问其应用程序帐户来进行操作...

我知道您想使用Calendar API在另一个用户日历中创建事件。我假设您的G Suite account中没有domain wide delegation。在这种情况下,要在另一个用户日历中创建事件,则需要service account。您可以看到here有关如何使用Calendar API在PHP中设置凭据的示例,您只需要使用新服务帐户中的凭据更改示例凭据。对于事件创建,您可以使用Events.insert(),但请记住,用户以前应该已经与服务帐户共享了日历。他们共享日历后,您应该使用日历标识符使用以前的方法创建它们。用户找到其日历标识符的一种方法是进入Events.insert(),查看

我的日历上的日历列表,然后单击其右侧和Calendar homepage。请问我是否需要进一步的帮助。

php codeigniter google-calendar-api google-oauth2
1个回答
0
投票
我知道您想使用Calendar API在另一个用户日历中创建事件。我假设您的G Suite account中没有domain wide delegation。在这种情况下,要在另一个用户日历中创建事件,则需要service account。您可以看到here有关如何使用Calendar API在PHP中设置凭据的示例,您只需要使用新服务帐户中的凭据更改示例凭据。对于事件创建,您可以使用Events.insert(),但请记住,用户以前应该已经与服务帐户共享了日历。他们共享日历后,您应该使用日历标识符使用以前的方法创建它们。用户找到其日历标识符的一种方法是进入Events.insert(),查看

我的日历上的日历列表,然后单击其右侧和Calendar homepage。请问我是否需要进一步的帮助。

© www.soinside.com 2019 - 2024. All rights reserved.