Facebook import is no longer fully possible with recent changes and restrictions on their API.
Latest update: v2.0 (January 22nd 2016)
Note: Importing posts from users from a Facebook group into your Discourse install might be frowned upon. They never signed up for their data to be exported to a new location. Read: privacy concerns.
Three years after the initial release by @Sander78 there is a huge update, written by @meriksson. A huge thanks to him for this, because it’s not just a little update, it’s a complete rewrite of my original script with a lot more options. And it’s battle tested.
Thanks! I’ll be trying this out once I get a local discourse up on my VM.
I’d love to see a cross-directional feature. Bots that do this type of thing were what made google-wave pretty awesome. I’d love to see a facebook group cross-poster app.
Still need to test that part though. Hypothetically a user should be able to login using Facebook, even if the script created a non existing email address.
The login feature made this #2 in what I’m going to do with my Hyper-V cluster, where #1 is getting discourse to run to begin with.
I still need to clear out some of my personal files on the secondary machine before I have my VM cluster up and running. But your script will defiantly be tested
Unfortunately there is something wrong with the import script: it breaks oneboxes.
I have no idea what is causing this. But after using this script, new oneboxes (ones that point to another post on the same forum) will onmly show the name of the forum and no contents at all.
So better not use it until it’s fixed. Since the API is not yet officially supported and since I’m not even using it , I doubt it will be fixed soon.
Unless @sam or someone else has the time to see what I am doing wrong here:
# Import Facebook posts into Discourse
# fb_ is Facebook related stuff, dc_ is Discourse related stuff.
# @fb_writers is an array of all the writers of posts and comments in the
# Facebook group
def fb_import_posts_into_dc(dc_category)
post_count = 0
@fb_posts.each do |fb_post|
post_count += 1
# Create a new topic
dc_topic = Topic.new
# Get details of the writer of this post
fb_post_user = @fb_writers.find {|k| k['id'] == fb_post['actor_id'].to_s}
# Get the Discourse user id of this writer
dc_user_id = dc_get_user_id(fb_username_to_dc(fb_post_user['username']))
# Facebook posts don't have a title, so use first 50 characters of the post as title
dc_topic.title = fb_post['message'][0,50]
# Remove new lines and replace with a space
dc_topic.title = dc_topic.title.gsub( /\n/m, " " )
# Set ID of user who created the topic
dc_topic.user_id = dc_user_id
# Set topic category
dc_topic.category_id = dc_category.id
# Set topic create and update time
dc_topic.created_at = Time.at(fb_post['created_time'])
dc_topic.updated_at = dc_topic.created_at
progress = post_count.percent_of(@fb_posts.count).round.to_s
puts "[#{progress}%]".blue + " Creating topic '" + dc_topic.title.blue + "' (#{dc_topic.created_at})"
# Everything set, save the topic
if dc_topic.valid? then
dc_topic.save!
# Create the contents of the topic (the first post), using the Facebook post
dc_post = Post.new
dc_post.user_id = dc_topic.user_id
dc_post.topic_id = dc_topic.id
dc_post.raw = fb_post['message']
dc_post.created_at = Time.at(fb_post['created_time'])
dc_post.updated_at = dc_post.created_at
if dc_post.valid? then
dc_post.save!
puts " - First post of topic created".green
else # Skip if not valid for some reason
puts "Contents of topic from Facebook post #{fb_post['post_id']} failed to import, #{dc_post.errors.messages[:base]}".red
end
# Now create the replies, using the Facebook comments
unless fb_post['comments']['count'] == 0 then
fb_post['comments']['comment_list'].each do |comment|
# Get details of the writer of this comment
comment_user = @fb_writers.find {|k| k['id'] == comment['fromid'].to_s}
# Get the Discourse user id of this writer
dc_user_id = dc_get_user_id(fb_username_to_dc(comment_user['username']))
dc_post = Post.new
dc_post.user_id = dc_user_id
dc_post.topic_id = dc_topic.id
dc_post.raw = comment['text']
dc_post.created_at = Time.at(comment['time'])
dc_post.updated_at = dc_post.created_at
if dc_post.valid? then
dc_post.save!
else # Skip if not valid for some reason
puts " - Comment (#{comment['id']}) failed to import, #{dc_post.errors.messages[:raw][0]}".red
end
end
puts " - #{fb_post['comments']['count'].to_s} Comments imported".green
end
else # In case we missed a validation, don't save
puts "Topic of Facebook post #{fb_post['post_id']} failed to import, #{dc_topic.errors.messages[:base]}".red
end
end
end
I know what it is, you need to port it to use PostCreator (in lib) there is a comment in that specifies the params you need and some specs.
@eviltrout has started a transition phase to service objects, that way we avoid a lot of the callback soup we have today. It makes diagnosing issues and testing much simpler.
Facebook won’t send the mail address when importing, so all users get a unique fake address. However, since there Facebook username is in the database, they can simpy login using their Facebook login.
Caveat is that you need to tell all your users to change their email address in Discourse if they want to be able to receive digests, etc.
Haven’t tested the 6000 users yet, cause the group I wanted to test has grown to 10000 now and I think that starting a new forum in that case is a lot better.
I’m planning importing 900 + user group with thousands of posts and replays (very active) into my install, any known issues i should take into consideration?
and thanks for this amazing plugin