mirror of
https://github.com/SuiteCRM/SuiteCRM.git
synced 2026-03-02 19:16:58 -05:00
Google Calendar Sync only works while the access token has not expired #5322
Labels
No labels
Area: API
Area: Campaigns
Area: Cases
Area: Clean Up
Area: Clean Up: Performance
Area: Dashlets
Area: Databases
Area: Developer Tools
Area: Elasticsearch
Area: Elasticsearch
Area: Emails
Area: Emails:Campaigns
Area: Emails:Cases
Area: Emails:Compose
Area: Emails:Config
Area: Emails:Templates
Area: Environment
Area: Installation
Area: Language
Area: Mobile
Area: Module
Area: PDFs
Area: PHP8
Area: Reports
Area: Studio
Area: Styling
Area: Upgrading
Area: Workflow
Area:Activity Stream
Area:Calls
Area:Import
Area:Projects
Area:Search
Area:Surveys
Area:Themes
Area:Users
Branch:Hotfix
Good First Issue
Hacktoberfest
Help Wanted
PR:Community Contribution
PR:Type:Enhancement
Priority:Critical
Priority:Important
Priority:Moderate
Severity: Major
Severity: Minor
Severity: Moderate
Status: Requires Code Review
Status: Requires Updates
Status: Stale
Status: Team Investigating
Status:Assessed
Status:Fix Proposed
Status:Needs Assessed
Status:Requires Automated Tests
Type: Bug
Type:Deprecated
Type:Discussion
Type:Duplicate
Type:Invalid
Type:Question
Type:Suggestion
Type:Suggestion
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/SuiteCRM-SuiteCRM#5322
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @Guiferreira2000 on GitHub (May 13, 2025).
Issue
https://community.suitecrm.com/t/google-calendar-sync-only-works-once/91880/7
I’m experiencing the following critical issue with Google Calendar sync in SuiteCRM 8.8 on PHP 8.3, and I want to clarify that this is not related to scheduler misconfiguration — the scheduled sync is running perfectly every minute.
The core issue:
The OAuth access token is being refreshed successfully and appears to be saved using setPreference() and savePreferencesToDB(). But despite this, every subsequent run treats the token as expired, resulting in the same cycle:
Scheduler runs and loads the access token from user preferences
isAccessTokenExpired() returns true
A new token is fetched and logged as successfully saved
On the next run, it repeats — never reusing the token just saved
What I’ve discovered:
This isn’t just a logic bug — it appears to be tied to SuiteCRM’s session behavior, particularly in CLI (cron) context:
Either the token isn’t actually saved to the DB despite the success log, or
The session data ($_SESSION[...]) used to track preference state is reset or not properly restored when cron runs again
So even though setPreference() sets the value and savePreferencesToDB() reports success, the system still loads an outdated or blank token on the next run. This suggests the refreshed token isn’t truly being persisted or is being lost between runs — possibly because SuiteCRM stores preferences in session and relies on session state even in CLI mode.
Why this matters:
This did not happen in SuiteCRM 8.3 under the same environment. It only started after upgrading to 8.8. So this looks like a regression, possibly due to session changes or stricter behavior introduced in 8.8 or triggered by PHP 8.3.
Possible Fix
The OAuth logic needs to force-load preferences from the database explicitly during cron execution and not rely on session state to persist values between runs.
Steps to Reproduce the Issue
Context
No response
Version
SuiteCRM 8.8
What browser are you currently using?
Chrome
Browser Version
No response
Environment Information
MySQL, php 8.3
Operating System and Version
Debian 12
@SuiteBot commented on GitHub (May 13, 2025):
This issue has been mentioned on SuiteCRM. There might be relevant details there:
https://community.suitecrm.com/t/google-calendar-sync-only-works-once/91880/10
@techsurrusr commented on GitHub (May 14, 2025):
Confirm issue on my side as well with a scratch installation of v8.8.0: https://community.suitecrm.com/t/google-calendar-integration-sync-issues/99313/1
@Guiferreira2000 commented on GitHub (May 20, 2025):
Solution for Sessions for Google sync users
Issue 1
The proposed fix suggested on https://github.com/salesagility/SuiteCRM/issues/10637 still won’t work, because in reloadPreferences() in the modules/UserPreferences/UserPreference.php that inner if
will never be true for your Google‐Sync user when run under cron, since current_user is always the admin. As a result, the sync user’s session bucket never gets populated—instead it falls through to the “else” and gets reset to an empty array. That change was introduced in commit
ea756b13f0(“Add check for current user on session preferences”) and has broken Google‐Sync usersFix
Or remove the condition completely
Or add an extra condition like
Whenever PHP is invoked from the command‐line (for example by your cron job), its “Server API” string (PHP_SAPI) is set to cli. In contrast, when PHP runs as an Apache module it might be apache2handler, or under PHP‐FPM it’s fpm‐cgi, etc.
This will always be true in the cron context, because you’re literally calling php -f cron.php (the CLI binary), not going through the web server. That guarantees your session‐reload logic fires under cron even though current_user is still “admin.
Issue 2
On the other hand, the function getGoogleClient in the file include/GoogleSync/GoogleSyncBase.php needs also a small fix for code optimization so it does not refresh the Google API token every minute. To fix this, pass the “no-session” flag (0) as the third argument and the category as the fourth:
By changing from
to
you are making sure that the generated GoogleApiToken is actually saved under the user preference GoogleSync and not Global
If you make this change the token is saved under the GoogleSync category, so subsequent runs will load the existing token and only refresh when it’s actually expired.
The current behaviour means that the function getGoogleClient always perceives the GoogleApiToken as expired and forces the token to be reloaded because it cannot find it in the GoogleSync preference.