Mingle - An Introductions Plugin

Mingle is normally a verb in English so “You’ve been invited to mingle” would be even better.

5 Likes

Okay, I’ve done a little bit of stuff here. Here is a list of stuff I did.

  • There’s now a ‘mingle group size’ option which will allow you to create group sizes of your choosing (2 or more, of course)
  • I made the default messaging translatable in client.en.yml. If you have an idea for a better default message (title or message body), please PR it.
  • I’ve added a toggle to the mingle admin panel, which will allow you to specify the exact date and time of the next event at any time.
    37%20PM
    45%20PM
    (NB: this is waiting on a PR to core to add the plugin outlet, so it won’t show up today.)

So you can now go “I want the events to happen every 4 weeks”, and then change the time of the next event to be, say, Tuesday at 2pm or whatever you fancy.

  • I’ve made it so that the group input can accept multiple group names delimited by |. So you can put
    marketers|engineers
    
    And get matches from both groups (note that there will still be inter-group matches, this simply takes users from both groups and mixes them up)
  • I merged a PR to translate it into Russian, thanks @Stranik!

Some thoughts on other feedback:

  • Re having multiple templates. Yes? But I’m not totally convinced of the right method here yet. As an admin, I think I’d much rather update my single template and know what’s going out, rather than having three templates that could go out. Also, since it’s a topic with an edit history, if I want to go back to a previous version, it’s really easy to do so, meaning you don’t gain a whole ton from having multiple templates; a single topic can currently hold multiple templates through the edit history.
  • I’m not certain about a recency threshold just yet, but I’m considering it.

Also, could you make this a Wiki topic plz @codinghorror? [Side note, I wonder if there’s appetite for a setting which allows all topics in a category to be wiki topics automatically]

8 Likes

That already is part of Discourse :slight_smile:

In this case, since this is your plugin, it makes sense for people to suggest content and for you to own the edit, but this is a good idea

Enjoying the development overall

2 Likes

I am so excited for this! I’m now wondering what’s the easiest way for people to move in and out of being paired for a mingle. For example, is there a way to pre-message people in a group and say something like:

Get ready to mingle! If you want to be paired up with another member of the community on August 27th, click here to sign up. If you want to wait until next time, no action needed.

Note: Not interested in mingling anymore? Click here to opt-out of these emails

This would also address the issue @nexo brought up re: inactive users.

Or, maybe a workaround is for the group admin to clear out the group each time and have people add themselves back in? That sounds like a lot of work, though…

5 Likes

I think you can totally handle this manually for the time being.

  • Create a new group, minglers for example, and set it to be public and anyone can join and leave
  • Send out a message to trust_level_1 (or everyone, or people you care about), introducing the program and explaining that it’s opt-in. Include a link to yoursite.com/groups/minglers, and instruct them to click ‘Join’ if they want to be a part.

One-click opt-out seems like a thing we could consider, but for now you could customize your PM template to have something like

Not interested in mingling in the future? Click [here](yoursite.com/groups/minglers) and select ‘Leave’ to opt-out.

2 Likes

Mingle is continually adding admin themes when I rebuild Discourse:

This also seems to be related to “oops” page crashes, in that mingle and the Iconified Header Links theme somehow conflict. When both are active my rebuild always fails. To fix it I have to:

  1. enter safe-mode
  2. disable Iconified Header Links
  3. load index page
  4. re-enable Iconified Header Links

This only happens when Mingle is installed and active.

1 Like

@FoohonPie Do you know the error that is being thrown? (should be able to see it by visiting /logs)

This is pretty neat - thanks for creating this plugin and sharing it with the community! Is anyone using it with success? How is it going?

I was just talking with some colleagues in my community about bringing people together around themes of shared interest. E.g. people we know to have shared interest who we think should meet. We already do it on an ad hoc basis, but this plugin came to mind as a means to systematize it and not create more opportunities for connecting and engaging.

I wonder if there might be scope and interest to combine this with the Events Plugin 📆 by @angus, to allow for the creation of scheduled mingle events. The events modal when creating an event topic could have a “this is a mingle!” option, which when selected opens up options to set it up including the message template.

Other ideas that spring to mind:

  • ability to customize the “host” user who sends the mingle messages, e.g. it could be a moderator in charge of the mingle event.
  • ability to include a group in the message and add tags for coordinating any followup, which would work well with the Tickets Plugin 🎟 by @angus
  • ability to specify user fields for matching for a specific mingle event, e.g. to connect up people from same country or who share some datapoint in user custom fields

Separately from this it’s occurring to me that it would be interesting to be able to grab a list of users in a particular topic or message, and add them to a discourse group to use for various purposes like this. I suspect there’s already a data explorer query for this (is there?) but some UI method for admins would be neat. Being able to take the people who have contributed to an active topic and obviously have shared interest and starting a mingle event for them would be super interesting.

And finally, I’d love to see the Voice recording plugin by @pawel get some love, which would really make mingling a heck of a lot more dynamic and fun… letting people save recorded messages to each other.

3 Likes

Had a quick glance at this, in the context of this topic

@gdpelican I think the issue is here:

https://github.com/gdpelican/mingle/blob/master/app/extras/theme_component_seed.rb#L20-L28

This snippet will return the ID of the theme_field, not the ID of the theme.

6 Likes

Here are the /logs errors from hitting it again earlier today:

ArgumentError (comparison of Integer with nil failed) /var/www/discourse/app/models/theme.rb:132:in `sort!'
3:24 pm
Failed to handle exception in exception app middleware : comparison of Integer with nil failed
3:24 pm

backtrace
/var/www/discourse/app/models/theme.rb:132:in `sort!'
/var/www/discourse/app/models/theme.rb:132:in `block in transform_ids'
/var/www/discourse/app/models/theme.rb:88:in `get_set_cache'
/var/www/discourse/app/models/theme.rb:123:in `transform_ids'
/var/www/discourse/app/models/theme.rb:206:in `lookup_field'
/var/www/discourse/app/controllers/application_controller.rb:544:in `custom_html_json'
/var/www/discourse/app/controllers/application_controller.rb:525:in `preload_anonymous_data'
/var/www/discourse/app/controllers/application_controller.rb:350:in `preload_json'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.2/lib/active_support/callbacks.rb:426:in `block in make_lambda'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.2/lib/active_support/callbacks.rb:198:in `block (2 levels) in halting'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.2/lib/abstract_controller/callbacks.rb:34:in `block (2 levels) in <module:Callbacks>'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.2/lib/active_support/callbacks.rb:199:in `block in halting'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.2/lib/active_support/callbacks.rb:513:in `block in invoke_before'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.2/lib/active_support/callbacks.rb:513:in `each'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.2/lib/active_support/callbacks.rb:513:in `invoke_before'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.2/lib/active_support/callbacks.rb:131:in `run_callbacks'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.2/lib/abstract_controller/callbacks.rb:41:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_controller/metal/rescue.rb:22:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_controller/metal/instrumentation.rb:34:in `block in process_action'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.2/lib/active_support/notifications.rb:168:in `block in instrument'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.2/lib/active_support/notifications/instrumenter.rb:23:in `instrument'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.2/lib/active_support/notifications.rb:168:in `instrument'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_controller/metal/instrumentation.rb:32:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_controller/metal/params_wrapper.rb:256:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/activerecord-5.2.2/lib/active_record/railties/controller_runtime.rb:24:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.2/lib/abstract_controller/base.rb:134:in `process'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/actionview-5.2.2/lib/action_view/rendering.rb:32:in `process'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/rack-mini-profiler-1.0.2/lib/mini_profiler/profiling_methods.rb:104:in `block in profile_method'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_controller/metal.rb:191:in `dispatch'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_controller/metal.rb:252:in `dispatch'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_dispatch/routing/route_set.rb:52:in `dispatch'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_dispatch/routing/route_set.rb:34:in `serve'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_dispatch/routing/mapper.rb:18:in `block in <class:Constraints>'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_dispatch/routing/mapper.rb:48:in `serve'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_dispatch/journey/router.rb:52:in `block in serve'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_dispatch/journey/router.rb:35:in `each'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_dispatch/journey/router.rb:35:in `serve'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_dispatch/routing/route_set.rb:840:in `call'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/rack-protection-2.0.5/lib/rack/protection/frame_options.rb:31:in `call'
/var/www/discourse/lib/middleware/omniauth_bypass_middleware.rb:32:in `call'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/rack-2.0.6/lib/rack/tempfile_reaper.rb:15:in `call'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/rack-2.0.6/lib/rack/conditional_get.rb:25:in `call'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/rack-2.0.6/lib/rack/head.rb:12:in `call'
/var/www/discourse/lib/content_security_policy/middleware.rb:12:in `call'
/var/www/discourse/lib/middleware/anonymous_cache.rb:216:in `call'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/rack-2.0.6/lib/rack/session/abstract/id.rb:232:in `context'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/rack-2.0.6/lib/rack/session/abstract/id.rb:226:in `call'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_dispatch/middleware/cookies.rb:670:in `call'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_dispatch/middleware/callbacks.rb:28:in `block in call'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.2/lib/active_support/callbacks.rb:98:in `run_callbacks'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_dispatch/middleware/callbacks.rb:26:in `call'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_dispatch/middleware/debug_exceptions.rb:61:in `call'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/logster-2.0.1/lib/logster/middleware/reporter.rb:30:in `call'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/railties-5.2.2/lib/rails/rack/logger.rb:38:in `call_app'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/railties-5.2.2/lib/rails/rack/logger.rb:28:in `call'
/var/www/discourse/config/initializers/100-quiet_logger.rb:16:in `call'
/var/www/discourse/config/initializers/100-silence_logger.rb:29:in `call'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_dispatch/middleware/remote_ip.rb:81:in `call'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_dispatch/middleware/request_id.rb:27:in `call'
/var/www/discourse/lib/middleware/enforce_hostname.rb:17:in `call'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/rack-2.0.6/lib/rack/method_override.rb:22:in `call'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_dispatch/middleware/executor.rb:14:in `call'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/rack-2.0.6/lib/rack/sendfile.rb:111:in `call'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/rack-mini-profiler-1.0.2/lib/mini_profiler/profiler.rb:281:in `call'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/message_bus-2.2.0/lib/message_bus/rack/middleware.rb:57:in `call'
/var/www/discourse/lib/middleware/request_tracker.rb:182:in `call'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/railties-5.2.2/lib/rails/engine.rb:524:in `call'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/railties-5.2.2/lib/rails/railtie.rb:190:in `public_send'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/railties-5.2.2/lib/rails/railtie.rb:190:in `method_missing'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/rack-2.0.6/lib/rack/urlmap.rb:68:in `block in call'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/rack-2.0.6/lib/rack/urlmap.rb:53:in `each'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/rack-2.0.6/lib/rack/urlmap.rb:53:in `call'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/unicorn-5.4.1/lib/unicorn/http_server.rb:606:in `process_client'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/unicorn-5.4.1/lib/unicorn/http_server.rb:701:in `worker_loop'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/unicorn-5.4.1/lib/unicorn/http_server.rb:549:in `spawn_missing_workers'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/unicorn-5.4.1/lib/unicorn/http_server.rb:142:in `start'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/unicorn-5.4.1/bin/unicorn:126:in `<top (required)>'
/var/www/discourse/vendor/bundle/ruby/2.5.0/bin/unicorn:23:in `load'
/var/www/discourse/vendor/bundle/ruby/2.5.0/bin/unicorn:23:in `<main>'

The weird thing is, even after removing mingle entirely, including the themes it adds, my site remains broken until I disable Iconified Header Links. Yet, it only ever happens when mingle starts off in the mix. I’m not sure what to make of that, but it seems worth noting.

Thanks, I’ll patch that up over the weekend. :slight_smile:

EDIT: Alright, that issue with the theme id should now be patched up.

6 Likes

Any chance you will further develop this plugin to ensure that mingle matches are not from within the same group, when mingling groups? I’m creating a discourse community that will have several user types, all related with one another in the same industry of engineering, and I’d like to mingle them in ways that will be mutually beneficial. It would be less beneficial to mingle those of the same group, at least for my use case. Thoughts?

2 Likes

Circling-back on this. My forum has a focus on humanitarian engineering, and I will have groups of mentors and proteges, as well as those seeking and providing help. It would be great to connect these folks in a targeted way. Has there been any development in ensuring that mingle will not match folks within the same group?

hi Joshua! I haven’t looked at this plugin for a while, but it seems to me you can get what you want just by creating a new group to use for mingling. This group does not need to be used for any other purpose or be publicly visible to members. Add whoever you want to your minglers group from your other groups and allow them to mingle!

2 Likes

It looks like this wasn’t made specifically for that use case but I think I see where you’re going @Joshua_Kogan, i may have had a similar idea in mind.

@tobiaseigen, i think the reason what you mentioned wouldn’t work is because the quote above. (I’m also assuming that @gdpelican may have meant intra-group matches?)
you could get protege + protege mingle matches, but the admin wants to exclusively facilitate mentor + protege mingle matches.

To take that idea a bit further, I could see the usefulness (selfishly) of also allowing boolean type logic in facilitating targeted matches.

Consider a not-that-hypothetical forum with groups for different majors at a university & groups for the years members graduated in like this:

  • ChemE-Major
  • CS-Major
  • co-2015
  • co-2021

As an admin I might want to pair current students who study Computer Science with alumni who studied Computer Science and do the same for Chemical Engineering majors. In which case I might specify my mingle configuration to target people with mutual/intersecting membership in certain groups as follows:

(ChemE-Major & co-2015) | (ChemE-Major & co-2021)
(CS-Major & co-2015) | (CS-Major & co-2021)

I may have snuck in an extra feature explanation here for allowing you to set up multiple configurations at once, but that would really only make sense if you could target matches to exclusively have members from specific groups.

Curious if anyone sees value in such a feature/extension of this plugin?

1 Like

Just curious is this plugin broken for anyone else?

I opened a pull request here for some the issues i encountered when running it on my forum

https://github.com/gdpelican/mingle/pull/6

Usually it is the new users with trust level 0 who just join the forum that need to introduce themselves and get to know others. Can I basically just setup a Mingle between users of only trust level 0? Or maybe, it’d be a bit more fun to setup a mingle between a user with trust level 0 and any other user.

I can see some other purposes of this. In gaming forum, auto pairing two people every defined interval could be a random duel or challenge.

From what i understand, the current feature set only allows you to define matches amongst a group or combination of groups but doesn’t offer any guarantee that matches will be between people in different groups.

So you could make all trust level 0 people match together, but you couldn’t guarantee all trust level 0 people match with any other user.

to answer in short:

Yes

lol agree would be more fun, but no, its not currently an option

2 Likes

I got this in my logs and seems to be something deprecated in Mingle?

1 Like

oh, true, yes. i just added that to the open PR as well, thanks