Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Receive email notification in my language #323

Open
virgile-dev opened this issue Oct 11, 2024 · 8 comments · May be fixed by #401
Open

Receive email notification in my language #323

virgile-dev opened this issue Oct 11, 2024 · 8 comments · May be fixed by #401
Assignees
Labels
backend bug Something isn't working i18n

Comments

@virgile-dev
Copy link
Collaborator

virgile-dev commented Oct 11, 2024

Bug Report

Problematic behavior
Even though my interface is in french I'm receiving notification emails in english.
Right the emails are sent in the language setting the sender using on the app. It should be the opposite.

@virgile-dev virgile-dev changed the title I'm receiving notification emails in english Receive email notification in my language Oct 11, 2024
@AntoLC AntoLC added the backend label Oct 15, 2024
@virgile-dev virgile-dev removed the todo label Oct 17, 2024
@rvveber
Copy link
Collaborator

rvveber commented Oct 17, 2024

I observed the same.
User A sends invite to user B -> user B get's email in language of user A
We need to store/set the language for the user B in the backend.

With my PR from #333 we will have the same language in the backend that we have in the frontend, because of sharing the language cookie impress_language.

We just need to read that cookie on the backend when the user B makes any request to it, and if it changed, update the language attribute on the user enttity for user B.

Then we always have up to date preferred language for the user B.
And when user B is supposed to receive an invite/mail, we can translate based on his stored language, no matter who invited him.

@virgile-dev virgile-dev added the bug Something isn't working label Oct 17, 2024
@rvveber
Copy link
Collaborator

rvveber commented Oct 21, 2024

@lindenb1 and i would like to work on this issue next.

To do this, we would like to remove the current usage of the Content-Language Headers in both frontend and backend.

Instead we would update language via the users API endpoint on language selection in the frontend.

Then we would adapt the code that sends invitation emails, to associate the email-address with the receiving user, and use their language for translation of the email.

@sampaccoud
Copy link
Contributor

sampaccoud commented Oct 21, 2024

associate the email-address with the receiving user,

@rvveber in the backend the email is sent to a user if we have one, so you will have access to user.language. If we have no user an invitation is sent to an email address but in this case we have no real way to determine a language... We could use the default language of the instance (settings.LANGUAGE_CODE) or the language of the requesting user like now? In the case of a governmental instance like us, the instance default language is paradoxically our best bet!

@rvveber
Copy link
Collaborator

rvveber commented Oct 21, 2024

in the backend the email is sent to a user if we have one, so you will have access to user.language

Oh great! Even better

If we have no user an invitation is sent to an email address

I didn't see that we could add any email address!
Totally agree then to use the standard language as fallback

@sampaccoud
Copy link
Contributor

sampaccoud commented Oct 21, 2024

You said:

With my PR from #333 we will have the same language in the backend that we have in the frontend, because of sharing the language cookie impress_language.

We just need to read that cookie on the backend when the user B makes any request to it, and if it changed, update the language attribute on the user enttity for user B.

But then you proposed:

Instead we would update language via the users API endpoint on language selection in the frontend.

Am I correct if I say this is in contradiction? If we update the field value on the user each time the cookie changes, we don't want to offer modifying it via the frontend because it will be confusing?

I would expect the value to be set the first time I login, and then being editable in my settings via the frontend. This means that we can set it in the authentication backend and not via a middleware and the cookie?

@sampaccoud
Copy link
Contributor

I didn't see that we could add any email address!

@virgile-dev may not be obvious enough?

@rvveber
Copy link
Collaborator

rvveber commented Oct 21, 2024

You said:

With my PR from #333 we will have the same language in the backend that we have in the frontend, because of sharing the language cookie impress_language.
We just need to read that cookie on the backend when the user B makes any request to it, and if it changed, update the language attribute on the user enttity for user B.

But then you proposed:

Instead we would update language via the users API endpoint on language selection in the frontend.

Am I correct if I say this is in contradiction? If we update the field value on the user each time the cookie changes, we don't want to offer modifying it via the frontend because it will be confusing?

I would expect the value to be set the first time I login, and then being editable in my settings via the frontend. This means that we can set it in the authentication backend and not via a middleware and the cookie?

The cookie determines the backend django language for the request as per LocaleMiddleware.
(It also determines the frontend i18n language)
But it is not persistet on the user.
I believe, the language attribute on the user is not used for translation:
https://docs.djangoproject.com/en/5.1/topics/i18n/translation/#how-django-discovers-language-preference
And it make sense, because most of the time you want to display something, you have LocaleMiddleware between the user and the backend, but not in this case, where the user is not making the request.

My original idea was to take that backend language which is (determined by cookie as of #333) for the user and persist it on his user entity. Because it would be a minimal solution.

But maybe doing it on each request is unnecessary stress, if it only changes on language switch(set) anyways.

Since there is also an existing user endpoint to update language, i revised the most minimal solution might be to instead update user.language on language switching via Header.

Both would change to the same lang

  • Cookie (for translating frontend- & backend text)
  • user.language (for meta and translating e.g. email text)

@rvveber
Copy link
Collaborator

rvveber commented Oct 23, 2024

After external discussion with @sampaccoud we could agree on the process.

Currently the frontend detects its language in this order:

  1. cookie
  2. browser-lang

And stores the detected language in a cookie.
(Which then results in translation)

I will add a detection strategy after the cookie, that will get the users language attribute:

  1. cookie
  2. user.language
  3. browser-lang

This way, when accessed from a new browser that has no cookie, or the cookie expired, we still get the users choosen language for the new cookie.

On language switch, i will update user.language asynchronously via API - then everything should be kept in sync, while still switching and loading instantly.

And of course finally, i will adapt to send the email in the users.language with fallback to djangos default language (settings.LANGUAGE_CODE).


Additional considerations:
@sampaccoud mentioned, that it would be better to have an account settings page, where to change user settings such as language.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend bug Something isn't working i18n
Projects
Status: In Progress
Development

Successfully merging a pull request may close this issue.

4 participants