How best to import users to migrate a mailing list to Discourse


(Tobias Eigen) #5

Yes, that’s an excellent suggestion. Do you know how to do this and if so can you share the steps?


(phil) #6

I am in the same boat, the problem is that discourse is not based on Mysql but Postgre instead
And I have no clue about Postgre :frowning:
I am surprised nobody build ap login to IMPORT USERS.

I mean there is a perfectly good EXPORT button in the admin / user page

If only we could import user using a structured file, that would be an IMPORTANT feature I think…


(blaumeer) #7

Unfortunately I don’t know how to do it. I would start connecting to the DB as explained here and then explore the db structure and see where user data are stored.

There is a meta or github page examples interacting with D pgsql, but I do not recall it right now.


(Dave McClure) #8

Rather than hack the database directly, I think you should take a look at what other import scripts do for importing users.

I would look at that and the code for the bulk invite system that @techAPJ worked on to see what can be pieced together:

It may be worth opening a separate feature request topic for this since other mailing list systems have this ability:


(Alessio Fattorini) #9

Could you open a feature request? It worth for me, I have the same issue


(Tobias Eigen) #10

I think there are actually good design reasons NOT to have user import available within the UX alongside the invite feature, and value the invite feature to encourage/facilitate the best, most civilized behavior by discourse admins as they ramp up their new forums. Discourse is still best for starting new communities and inviting people is better than just adding them.

So making admins do a little work as they migrate their mailing lists to discourse is a Good Thing. What I’d be very happy with (and perhaps contribute some dollars and attention of my (volunteer) developers to) is an import script and HOWTO for importing users from the command line using a prepared CSV.

That said, if someone else develops an optional plugin to add a tickbox on the invite dialogs to “import instead of invite” I wouldn’t say no to that either. :speak_no_evil:


(phil) #11

Everybody has their own reason wanting to add users.

For example, I want to be able to create a couple of key user and reserve some specific usernames before they are taken, so that my staff can have uniform names.

If I ask my staff to register, then I’ll have to explain each one of them what I need, and I know it will not be done right the first time.

As simple as that.


(Kane York) #12

Keep in mind that admins can change the usernames of users, and delete users, with impunity. It’ll be a bit damaging to do it often, and at all with established accounts, but it’s very available to you.


(Tobias Eigen) #13

… and I think this is a prime example of what I mean when I say it is ok to make admins do a bit of work to set up users. It’s not that much effort to edit the settings of a few users.

I have found so far that most issues can be resolved using existing features and some long handed manual steps, and I am ok with that.


(Vincent Oord) #14

For what it’s worth, I’ve created a fairly simple importing script for importing users based on a CSV file. It’s written mostly for my own requirements (which were very simple), but I’ll happily receive contributions to this script. If anyone wishes to do so, just create a pull request.


Adding members to groups via CSV
Force mods to be watching or tracking all or some categories - how to?
(Stefan) #15

@vindia your script is really useful for simple user migrations from other forum platforms as well (IP.Board in my case). But I was wondering if there any way to handle banned user. I’m not a ruby/rails developer, but I think I can change it to handle this if somebody points me in the right direction.

In IP.Board, banned users are basically part of a group. In Discourse it seems things work a bit different because you don’t have negative permissions. So even if I create a banned group, there is no easy way to limit the access for that group. Of course I could limit access for the banned group by not assigning permission to “everyone” and assign permissions to individual groups. But is obvious this is not feasible. So my question is, what should I do to your script to also add some users as banned? An easy solution I guess would be to have approved set to false, but it would be better if I could add them as banned in the real sense.

I need to import banned users because I don’t want to leave those out and then somebody else can come and register a username that was banned in my old forum platform.

[later edit]

Looking at other import scripts I’ve found StaffActionLogger.new(system_user).log_user_suspend(user, b['ban_give_reason']) So maybe something like this in an if statement?

system_user = Discourse.system_user
StaffActionLogger.new(system_user).log_user_suspend(user, 'Imported banned user')

I’ll probably try it out this weekend.


(Kane York) #16

You want to set the suspended_at and suspended_till fields on the user.


(Vincent Oord) #17

Yeah, what @riking says: in the User.new method you should add two lines for suspended_at and suspended_till and you should file them with a type of Date, for instance the Date of today which you get in Ruby with the method Date.today.

suspended_at: Date.today,
suspended_till: Date.today + 100 // 100 days in the future

You might want to use a date way in the future if you want to suspend someone “for ever”.


#18

Awesome! Do you have instructions on how to use this script (commands etc) within the docker container? For example, I don’t know how to access lib/tasks


(Vincent Oord) #19

Yeah it’s a basic Rake task as used in any Rails application.

From the root dir of your app, inside the docker container, just do

rake user_importer:check[/path/to/users.csv]

#21

@vindia Thanks for responding! I was referring to your initial instruction on adding the script to lib/tasks. Thus far I’ve only been adding plugins through nano containers/app.yml.

How exactly do I add your script to lib/tasks?


(Vincent Oord) #22

Ah I see. You should add them to the /shared/standalone folder in your Docker image. When you login to the Docker image from your server with ssh (with the command ./launcher ssh app, you can then access lib/tasks and copy the files from the shared folder.

(Exact paths might be a little different as it has been a while I’ve administrated a Discourse install and I do this from memory).


(Tobias Eigen) #23

Hey @vindia - I see you haven’t contributed for a while so not sure you’ll get this. For another project I finally tried out your importer and it works great! :rocket: However my test user account is not active. The username is greyed out and the admin page indicates email is not verified and the account is not active. Buttons are available to send an activation email or to activate account. Elsewhere I see the test user doesn’t show up in user lists or when searched.

I suppose this functionality is new since you wrote your importer script. Do I need to go through and activate each of the accounts via the admin, or is there a way around this step?

Are there any downsides to using this script?


(Vincent Oord) #24

Hey Tobias. I’m not very active on this anymore but luckily email notifications exist ;-).

To be honest, I’m not sure how to fix this and probably some stuff has changed in Discourse since I wrote the initial script. However, when I take a quick look at the source code of the user model on GitHub, I see a attribute named :active and a method named activate that you can use.

The best way to fix this is to update my script to set this :active attribute to true or to use the activate method after saving the user, by adding the line u.activate after u.save in my script. If you create a pull request for this on my script I’m happy to merge it in.

Also, I noticed there’s now a method named approve on the User model, so you could replace the two keys in the new user hash approved: true and approved_by_id: -1 to the method call u.approve(-1) too. Again, I will happily accept a pull request for this one (but please test it first yourself).


(Jérémy Frere) #25

Thanks a bunch, you just saved me a lot of time :slight_smile:
Have a great day !