Microsoft sync works, only it doesn't... (multi-tenant)

Hi all and thanks for a great solution! I'm self-hosting on Twenty on an internal server, and finally got the MS integrations going with SSL. Logging in with MS works like a charm, and connecting my account also works - except that nothing actually gets imported. It is stuck on the 'Importing' status, and I can't for the life of me find anything that could indicate what is wrong in any logs. All cron jobs are started as well. All ideas on how to resolve this would be greatly appreciated
No description
44 Replies
Guillaume
Guillaume2w ago
did you pull the latest version from the main branch ? We fixed a lot of issues on this topic this week
El Odve
El OdveOP2w ago
Hi @Guillaume, thanks for the quick response! The install was done on Saturday by the one-click Docker install script, so unsure if it is the latest version or not.
Prastoin
Prastoin2w ago
Hey @El Odve, could you please share the TAG value of your one-click install .env Or execute echo APP_VERSION in your twenty-server container
El Odve
El OdveOP2w ago
Guess I'm running 0.52.6
No description
Guillaume
Guillaume2w ago
it would be great to try on version 52.8 we fixed a couple of issues between 52.7 and 52.8
El Odve
El OdveOP2w ago
Ok, will try. I see now that my worker is down as well, will try to figure out why. The Best Way(tm) to upgrade is to run the one-click installer again?
Prastoin
Prastoin2w ago
@El Odve to upgrade you should update the TAG value in your .env and restart your containers
El Odve
El OdveOP2w ago
Thanks @Prastoin, just figured it out and did that. Up and running with 0.52.8 now, but seems like the issue is still there. According to the health panel the worker is down, but the system works and I can't find any errors in the logs... When restarting the containers, the twenty-server-1 is reported as unhealthy, but I can still access everything as normal and I don't see any error in the logs.
Prastoin
Prastoin2w ago
That's still a step further ! Could you please share your worker's logs ?
El Odve
El OdveOP2w ago
Sure, just tell me what I should to to provide you with the exact log you want! I'm fairly new to docker environments... Also, it seems like the worker never actually starts, as it depends on the server and that is reported as unhealthy when starting - despite actually running... Maybe worth mentioning that it's running using a self-signed SSL certificate, which was a bit of a hassle as the certificate and key had to be manually copied to the server container and I had to turn off ssl in the postgres env string. So possibly something related to that... I have a test version running locally on my computer without SSL, just using localhost as the server URL - this instance is reported as healthy including the worker, but here I the sync fails with the message 'Sync lost with mailbox...' Ok, so I'm getting somewhere here. My main issue is related to SSL and the self-signed CA in combination with the health test in the docker compose file, which tests at http://localhost:3000/healthz. Even though the paths to the certificate and key are specified in the config, they are not copied to the docker image and I have to do that manually. Then the next issue is that the curl command to test is a) using the wrong server address (I have another URL that is also specified in the config) and b) that it will fail anyway because it doesn't like self-signed CAs. After editing the test with the correct URL and adding --insecure to allow for a self-signed CA, the worker is now at least starting. All cron jobs are now also started from the worker, so fingers crossed...
El Odve
El OdveOP2w ago
@Prastoin: Finally an actual error for you to look at: ERROR [CalendarFetchEventsService] Error: Access token is undefined or empty. Please provide a valid token.For more help - https://github.com/microsoftgraph/msgraph-sdk-javascript/blob/dev/docs/CustomAuthenticationProvider.md
GitHub
msgraph-sdk-javascript/docs/CustomAuthenticationProvider.md at dev ...
Microsoft Graph client library for JavaScript. Contribute to microsoftgraph/msgraph-sdk-javascript development by creating an account on GitHub.
El Odve
El OdveOP2w ago
at parseMicrosoftCalendarError (/app/packages/twenty-server/dist/src/modules/calendar/calendar-event-import-manager/drivers/microsoft-calendar/utils/parse-microsoft-calendar-error.util.js:31:20) worker-1 | at MicrosoftCalendarGetEventsService.getCalendarEvents (/app/packages/twenty-server/dist/src/modules/calendar/calendar-event-import-manager/drivers/microsoft-calendar/services/microsoft-calendar-get-events.service.js:42:84) worker-1 | at process.processTicksAndRejections (node:internal/process/task_queues:95:5) worker-1 | at async CalendarFetchEventsService.fetchCalendarEvents (/app/packages/twenty-server/dist/src/modules/calendar/calendar-event-import-manager/services/calendar-fetch-events.service.js:43:47) worker-1 | at async CalendarEventListFetchJob.handle (/app/packages/twenty-server/dist/src/modules/calendar/calendar-event-import-manager/jobs/calendar-event-list-fetch.job.js:53:17) worker-1 | at async MessageQueueExplorer.invokeProcessMethods (/app/packages/twenty-server/dist/src/engine/core-modules/message-queue/message-queue.explorer.js:111:17) worker-1 | at async MessageQueueExplorer.handleProcessor (/app/packages/twenty-server/dist/src/engine/core-modules/message-queue/message-queue.explorer.js:103:13) worker-1 | at async /app/packages/twenty-server/dist/src/engine/core-modules/message-queue/message-queue.explorer.js:79:17 worker-1 | at async Worker.processFn (/app/packages/twenty-server/dist/src/engine/core-modules/message-queue/drivers/bullmq.driver.js:41:13) worker-1 | at async /app/node_modules/bullmq/dist/cjs/classes/worker.js:520:32 {
El Odve
El OdveOP2w ago
...and after disconnecting and reconnecting the account, we're now back to the 'Sync lost' error:
No description
El Odve
El OdveOP2w ago
Which seems to be caused by the above error. Note that logging in using the Microsoft connector works like a charm.
Guillaume
Guillaume2w ago
Note that microsoft requires a paid account in order to have the sync possible. is [email protected] a free account ?
El Odve
El OdveOP2w ago
No, it's a corporate account.
Guillaume
Guillaume2w ago
so a 365 paid account right ? that's good
El Odve
El OdveOP2w ago
That's right. I've set up all the required permissions in azure, the secret is valid, application ID is fine and redirect URIs work.
Guillaume
Guillaume2w ago
To me, you have an issue with your setup that is related to this part of the code where we create the connection to microsoft graph API
const microsoftClient =
await this.microsoftOAuth2ClientManagerService.getOAuth2Client(
connectedAccount.refreshToken,
);
const microsoftClient =
await this.microsoftOAuth2ClientManagerService.getOAuth2Client(
connectedAccount.refreshToken,
);
In my opinion, the refresh token that you can look in the database is not good. I don' t know ehy but maybe you can copy it and test it in Postman or another tool. to find your token, go to your db and look for your connected account, then look at the "refreshToken" related to your account
El Odve
El OdveOP7d ago
How/where do I do that? @Guillaume: I figured out how to test this using Postman, and the refreshToken as copied from the database is valid. Something else is amiss. Could you point me to where in the source code you create the connection? With a bit of luck I might be able to debug something better then.,..
Guillaume
Guillaume7d ago
Sure You can start by having a look at this file /packages/twenty-server/src/modules/connected-account/oauth2-client-manager/drivers/microsoft/microsoft-oauth2-client-manager.service.ts the getOAuth2Client method is the one we use then to instanciate the connections for messaging and calendar
El Odve
El OdveOP7d ago
Thanks! I really want to get to the bottom of this. 🙂 Loving Twenty CRM so far, just need to get this bit sorted and it will be perfect for our purposes!
Guillaume
Guillaume6d ago
Sure !
El Odve
El OdveOP6d ago
Here is a fresh error log from worker-1 upon failed import. This crashed the Connected Accounts service, which then takes a few minutes to get back up. Exception Captured undefined [ 'Unknown error importing messages for message channel 5f45fdcb-a6d6-4f32-9be8-8a426d5c18bd in workspace 2fa67d60-5c17-4a6e-becd-2e70f4434d81: Request failed with status code 401' ] Exception Captured undefined [ MessageImportException [Error]: Request failed with status code 401 at MessageImportExceptionHandlerService.handleUnknownException (/app/packages/twenty-server/dist/src/modules/messaging/message-import-manager/services/messaging-import-exception-handler.service.js:110:15) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async MessageImportExceptionHandlerService.handleDriverException (/app/packages/twenty-server/dist/src/modules/messaging/message-import-manager/services/messaging-import-exception-handler.service.js:62:17) at async MessagingMessageListFetchJob.handle (/app/packages/twenty-server/dist/src/modules/messaging/message-import-manager/jobs/messaging-message-list-fetch.job.js:128:13) at async MessageQueueExplorer.invokeProcessMethods (/app/packages/twenty-server/dist/src/engine/core-modules/message-queue/message-queue.explorer.js:111:17) at async MessageQueueExplorer.handleProcessor (/app/packages/twenty-server/dist/src/engine/core-modules/message-queue/message-queue.explorer.js:103:13) at async /app/packages/twenty-server/dist/src/engine/core-modules/message-queue/message-queue.explorer.js:79:17 at async Worker.processFn (/app/packages/twenty-server/dist/src/engine/core-modules/message-queue/drivers/bullmq.driver.js:41:13) at async /app/node_modules/bullmq/dist/cjs/classes/worker.js:520:32 at async Worker.retryIfFailed (/app/node_modules/bullmq/dist/cjs/classes/worker.js:747:24) { code: 'UNKNOWN' } ]
El Odve
El OdveOP6d ago
These are the API permissions set up in Azure. Note that signing in works.
No description
Guillaume
Guillaume6d ago
still an unauthorized error. Looks like there is. an issue in your token creation / azure permission
El Odve
El OdveOP6d ago
I tested the refreshToken using Postman yesterday, and the token itself seemed fine. Could there be some security setting company wide in Azure that breaks this?
Guillaume
Guillaume6d ago
Not sure at this level sorry. I am quite noob on Azure specification
El Odve
El OdveOP6d ago
...that makes two of us...
Guillaume
Guillaume6d ago
haah
Guillaume
Guillaume6d ago
Me with Microsoft doc lol good luck for your research let me know if you find something
El Odve
El OdveOP6d ago
😆 Will do! BTW, do you keep the response body from the Microsoft Graph API in the logs somewhere so I can look there? If not, I'll try to replicate the call that fails once I locate it in the source code.
Guillaume
Guillaume6d ago
nope, you need to add some logs
El Odve
El OdveOP6d ago
I think I'm getting to the root of this now. The accessToken field in the database is blank. Am I correct in assuming that you use the common access point in OAUTH? I haven't seen any place I can specify the tenant id, so I think that is a safe assumption? If I try to obtain an accessToken manually using curl and the common tenant then this is indeed currently blocked by conditional access. If I try using our tenant ID, I can get the access token without any issues. Do you have any plans to support single tenant applications? So essentialy you're right, it is an unauthorized error. For me the simplest workaround would be to be able to set a TENANT_ID variable in the config which has the default value common
Guillaume
Guillaume6d ago
ah yes good point. we only support multi tenant ! there is. a thread somewhere in discord talking about it but it is not on our roadmap sorry. You can still use twenty as multi tenant or make a clone to change this line if it's a mandatory feature right now for you ! I updated the title for other users to find out 🙂
El Odve
El OdveOP6d ago
For me it would probably be easiest to make a clone, I think. At least there I now know what I need to do. 🙂 Fixing the permissions in Azure is more of an unknown at this point... 😉 Is there more magic to supporting single tenant than having a MICROSOFT_TENANT_ID env variable that is set to 'common' by default and using this value in the url used to fetch the access tokens? I see it is used in two files, packages/twenty-server/src/modules/connected-account/oauth2-client-manager/drivers/microsoft/microsoft-oauth2-client-manager.service.ts and packages/twenty-server/src/modules/connected-account/refresh-tokens-manager/drivers/microsoft/services/microsoft-api-refresh-tokens.service.ts
Guillaume
Guillaume6d ago
i think you got it right nothing more
El Odve
El OdveOP5d ago
Hmmm... There's something else going on as well. I know get an error when importing calendar events, which claims the access token is undefined or empty. When replicating the relevant call from the code manually using the values from the connectedAccount table in the database (which is now successfully populated), I get a valid response including a new accessToken.
El Odve
El OdveOP5d ago
Exception Captured { workspace: { id: '2fa67d60-5c17-4a6e-becd-2e70f4434d81' } } [ CalendarEventImportDriverException [Error]: Access token is undefined or empty. Please provide a valid token.For more help - https://github.com/microsoftgraph/msgraph-sdk-javascript/blob/dev/docs/CustomAuthenticationProvider.md at parseMicrosoftCalendarError (/app/packages/twenty-server/dist/src/modules/calendar/calendar-event-import-manager/drivers/microsoft-calendar/utils/parse-microsoft-calendar-error.util.js:31:20) at MicrosoftCalendarGetEventsService.getCalendarEvents (/app/packages/twenty-server/dist/src/modules/calendar/calendar-event-import-manager/drivers/microsoft-calendar/services/microsoft-calendar-get-events.service.js:42:84) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async CalendarFetchEventsService.fetchCalendarEvents (/app/packages/twenty-server/dist/src/modules/calendar/calendar-event-import-manager/services/calendar-fetch-events.service.js:43:47) at async CalendarEventListFetchJob.handle (/app/packages/twenty-server/dist/src/modules/calendar/calendar-event-import-manager/jobs/calendar-event-list-fetch.job.js:53:17) at async MessageQueueExplorer.invokeProcessMethods (/app/packages/twenty-server/dist/src/engine/core-modules/message-queue/message-queue.explorer.js:111:17) at async MessageQueueExplorer.handleProcessor (/app/packages/twenty-server/dist/src/engine/core-modules/message-queue/message-queue.explorer.js:103:13) at async /app/packages/twenty-server/dist/src/engine/core-modules/message-queue/message-queue.explorer.js:79:17 at async Worker.processFn (/app/packages/twenty-server/dist/src/engine/core-modules/message-queue/drivers/bullmq.driver.js:41:13) at async /app/node_modules/bullmq/dist/cjs/classes/worker.js:520:32 { code: 'UNKNOWN' } ]
GitHub
msgraph-sdk-javascript/docs/CustomAuthenticationProvider.md at dev ...
Microsoft Graph client library for JavaScript. Contribute to microsoftgraph/msgraph-sdk-javascript development by creating an account on GitHub.
El Odve
El OdveOP5d ago
@Guillaume: Don't know why, but rebuilt with 0.53.2, patched the two files in question within the container and restarted and NOW it works. 😄
Guillaume
Guillaume5d ago
❤️
Prastoin
Prastoin5d ago
Well done @El Odve ! Enjoy coding importing !
El Odve
El OdveOP5d ago
Thanks! The least amount of coding I've done to get something working... 😄

Did you find this page helpful?