Plugin development-- Event fired if email address is changed?

I’m working on a plugin that will add users to a group if their email address matches a whitelist.

I have it working for new users with:

  DiscourseEvent.on(:user_created) do |user|
    GroupDomain.add_to_group_if_in_whitelisted_domain(user)
  end

What I want to do next is have it move users to the group if they change their address to a matching domain. I would think that

  DiscourseEvent.on(:user_updated) do |user|
    GroupDomain.add_to_group_if_in_whitelisted_domain(user)
  end

would do the trick, but it doesn’t. (Then I thought that if they changed their email address and then changed anything else in their user record that it would work, and it does!)

Is there some event that I can call/watch (I’m just a caveman) that will fire if their email address is changed?

5 Likes

The more I think about it, the more I think that :user_updated not being triggered when an email address is changed seems like a bug. Back before we had a user_email model, changing the email address would trigger :user_updated.

But having UserEmail ` do

after_update :trigger_user_updated_event

and with

  def trigger_user_updated_event
    user = User.find(self.user_id)
    DiscourseEvent.trigger(:user_updated, user)
    true
  end

triggers more often than it should (like when logging in via email link) and also causes a

PG::UniqueViolation - ERROR:  duplicate key value violates unique constraint "index_group_users_on_group_id_and_user_id"

For a few minutes, I thought I knew something. :crying_cat_face:

It is not because it is a different model, as you found out. Since @LeoMcA changes where merged, User and UserEmail are different models, and changing an instance of UserEmail won’t trigger an watcher in a User instance.

1 Like

Can you tell me the best way to have my conditionally_add_to_group function called when the email address changes?

1 Like

I think something like this in plugin.rb will do

after_initialize do

  add_model_callback(UserEmail, :after_commit, on: :update) do
     # Group.add blablabla
  end

end
11 Likes

Hooray! IT works!

  self.add_model_callback(UserEmail, :after_commit, on: :update) do
    puts "#{'-'*50}\nEMAIL YES ADDRESS IS UPDATED for #{self.user_id}!!!!\n#{'-'*50}\n"
    user = User.find(self.user_id)
    GroupDomain.add_to_group_if_in_whitelisted_domain(user)
  end

Thanks a million, @Falco!

6 Likes