Basket CRM Interface for Views Bulk Operations

Events happening in the community are now at Drupal community events on www.drupal.org.
moreonion's picture

We've just made the decision to go with Redhen instead of Party CRM as a company. So I thought it would be appropriate to start sharing ideas, drafts and notes here :-)

One of the UX things I've been thinking about for quite some time is how to enable users to do powerful profiling and segmentation without confusing interfaces or too many interface options.

An idea that seems to work quite well is to use the concept of "baskets" like in a web shop. You have to see the "basket" as a sort of extension of views bulk operations.

Instead of just clicking your list together and then performing a bulk operation on the contacts you can filter (or select manually) and then "add the selection to the basket".

Only local images are allowed.

The actual bulk operation is now not on the same page, but the first screen is limited to the task of collecting the right people before you do something with them.

Once you're done selecting, filtering etc. you "go to your basket".

Only local images are allowed.

In here you have the usual views bulk operations. Note that one of those operations is to "save basket". If you do that you'll be able to reuse the basket in future.

The basket itself does not just save the IDs of the selected items (contacts), it also understands if you've added individual people or actually a whole filter (like all contacts tagged with X).

Only local images are allowed.

For more advanced users the formula created remains editable. Particularly if you save a basket you can always remove specific parts of the formula later on.

If you want to edit the basket content you click "edit basket" and land on the same page like the beginning (only that saved baskets have the name of the basket on it).

Only local images are allowed.

All saved baskets end up in a list. To spin the same concept even further on the list of all saved baskets you can create "super baskets" which are a hierarchy above the actual basket. Yes, those are baskets containing baskets.

Only local images are allowed.

Before writing the word basket a few more times (it's starting to confuse me to talk about baskets so much) I'll stop now. I hope that the drafts are straight forward and are easy to understand.

I'd love to hear your thoughts, ideas and if you want to make it happen give us a shout!

We'll probably do some work on this but it will take a few more months until we can get started.

Cheers
Florian

Comments

Awesome

seanberto's picture

First off, I love the screenshots and the concept as a whole. I think that it's easy to understand and presents some really powerful UI options. The ThinkShout team would love to explore it more with you if you have the time. Or, if you're deep into it - we look forward to seeing what you come up with.

Could I ask a few questions?

How do you see "baskets" relating to organizations? Totally different data structure? I ask b/c we've been toying with how to do containers like this as well. One idea was actually to create a new organization bundle that would serve as such a container. Then, contacts would be added to this new "basket" organization bundle as they would a standard organization.

We've also thought about handling basket-like containers as taxonomies. What sort of architectural approach are you considering at this point?

What are you representing with the "basket formula" button? Is the idea there that there would be Rules around dynamically adding contains to different baskets based upon certain business logic?

Again, very cool concept! Can't wait to learn more!!

Thanks

moreonion's picture

Glad to hear you like it :-)

We've also really come to like Redhen and you've really impressed us with answering questions quickly (and the way you actually explain what you're doing). Thumbs up!

I'm happy to provide further input or even have a chat with you folks some time. We're based in CET but a few of our developers will be at drupalcon in munich - maybe you guys can catch up there.

Organisations vs. baskets

I think that organisations should be not more than a term for "non-human" contact entities. Referencing individuals to organisations makes sense.

But I think a basket should be a more abstract grouping of contacts (either individuals OR organisations in semi-random constalation). In a way I see baskets as "dynamic groups" as they can be found in other CRM systems.
A dynamic group in that sense is basically a set of filters that are saved and they can be used to generate a list of contacts for specific use cases.

The only way a basket might be different from a dynamic group is the presentation to the end user (put things in, then do something with those things) and the option to manually add/remove specific contact records on top of various filters.

Architectural approach

I'm not the developer around here so I can't really say a lot about this. But taxonomy is clearly not going to be able to achieve this.
We were more thinking about using views and building on top of the views bulk operations module for actions.

One idea would be to save specific states of a view (depending on the activated filters) into something more lightweight than a view. The basket "stores" these light weight views and also stores the manually added / removed contact records. When the basket is actually being used (because the user wants to perform an action on all the contacts in the basket) the list of contacts is rendered according to the formula.

The problem area here is currently that we don't know whether it will be ok performance-wise. We haven't really looked into all the options here.

Basket formula

The basket formula is what happens in the background. If you are an average user all you do is go to your listing of contacts. Then you filter (e.g. all people where tag=facebook), click "add to the basket". Then you filter all people with tag=volunteer and click "add to the basket".

Afterwards you find a few individuals based on a specific activity in the past (e.g. an event they've participated) and click "remove from basket".

Once you go and visit this basket all you have to do is perform your action. If you click on "basket formula" you basically see what you've done to build the basket and you can remove specific steps. It's more a feature for advanced users since we could also add a weight to this interface (then the formula is executed in the exact order from top to bottom) or even allow AND/OR grouping.

Hope this clarifies the idea :-)

BTW we're working on an activity tracking module, will probably share some code next week.

Nice

seanberto's picture

I want to engage with Lev Tsypin, our technical lead, before getting back to you re: your approach to baskets. Again, it's just awesome that you're looking into making this investment and we wouldn't ever stand if your way of doing something that works for you. But if there are opportunities to work together, that'd be great.

Re: activity tracking, let's definitely talk - as that's an area were we need to focus soon. I think that it's a feature with a straightforward scope, so probably something we should consider together so as to avoid overlap. (And, admittedly, it's a feature that we're going to have strong opinions on b/c it's so deeply tied to everything we're doing.)

In short, we're looking at creating more of a "history" logging tool that allows developers to record certain actions on a contact/organization record to a log. "Scoring" these actions would occur in the engagement scoring feature that we've already developed.

Again, awesome to be working with you. Excited to talk more. Thanks for reaching out.

Re: baskets We wont start

moreonion's picture

Re: baskets

We wont start development on this for quite a while because we have too much other stuff to do. But I think it would be great to exchange ideas and concepts. Our tech lead is torotil and he would probably be a better candidate for tech exchange on the basket idea.

Re: activity
I'll ask one of our developers to send it over as soon as everything is changed to redhen. We started developing it in a quite generic fashion and then wanted to integrate it into party (before we've decided to make the switch).

Sounds like our concepts are very similar - we need activity for tracking of interactions and we have to be able to filter it afterwards. In our case activities frequently happen in the context of a campaign (which is a node type in our case).

Possible interactions for our use case are:
* signing a petition
* making a donation
* sending a protest email
* filling out a webform
* receiving a mass email
* opening an email
* clicking on a link in an email

Our rough version is on being discussed on http://drupal.org/node/1689282 if you want to go through the code. But matthias_mo is working on a redhen specific versions starting tomorrow.

Basically we think that it should be possible to log literally anything as activity, although we have a quite clear picture of what we're going for.

Whether these activities will also be represented in a visually appealing way on supporter "profiles" at some stage is open, for now we just need the logging of events (for integration with other database systems and to profile based on activities).

Re: engagement tracking

The engagement scoring is great as well. We use a slightly different concept but it could be combined. In general we take various models of "supporter journey" (from campaigning theory) as basement since we are going to use the CRM functionality mainly for campaigning.

For engagement tracking we will implement something like:
(it's borrowed from our friend Duane Raymond)

  • New subscriber: j < 15d; p = 0
  • Warm subscriber: j > 15d, e < 3x; p = 0
  • Inactive subscriber: j > 15d, e 3x +, c = 0, p = 0
  • Sceptic subscriber: j > 15d, e 3x +, c > 0, p = 0
  • New participant: j < 15d; p > 0
  • Warm participant: j > 15d; e < 3x, p > 0
  • Lapsed participant: j > 15d; e > 3x, c = 0 or c > 120d; p > 0; p > 120d
  • Sceptic participant: j > 15d; e > 3x, c < 120d; p > 0; p > 120d
  • Occasional participant: j > 15d; e > 3x, p > 1; p > 60d and < 120d
  • Regular participant: j > 15d; e > 3x, p > 2; p < 60d

where j=joined; e=emailed; c=clicked; p=participated; d=days ago, x = times

But with those "scores" you're using we could add another parameter to our formulas which is great! :-)

Architectural approach - some ideas

torotil's picture

Hej :)

Here's some thoughts about how to implement it … This is still rather vague.

Dry theory

In theory each basket can be expressed by a set of filters (eg. first name starts with "A", has donated at least once, …) that are combined by AND (and possibly also OR). One set of filters selects a set of entities.
Combining baskets directly maps to set operations.

In SQL the filter expressions would map directly to the boolean operators AND and OR. A simple SELECT cid FROM contact …;-statement using this filters gives us the set of all matching contacts. The set operations can be mapped to:

  • union: the SQL-union operator
  • intersection: INNER JOIN the two sets (or merge them and use AND on the filters)
  • complement: LEFT OUTER JOIN … and WHERE cid2 IS NULL

How far can we push views?

Views exposed filters already solves the problem if we limit ourselfes to conjunctions (AND) and forget about combinations of baskets. So the question is how to expand views exposed filters to also cover OR and how to combine different baskets. My basic idea for doing that is to invoke views query building routine multiple times (once for each branch of OR and each basket) and then combine the queries using the methods mentioned above.

Views exposed filter also provides us with a nice way to represent filters: a simple associative array.

… or to build it all bottom up

The obvious other way is to build it everything from bottom up. Which means defining all possible filters for different field-types and losing all the flexibility of views (customizing filters, and displayed fields via the web interface).

Currently I prefer the hacked/extended views exposed filter approach. But this may change once I'm stuck in views' innards ;)

There is also the possibility of combining those two approaches somehow. Like using views for the field-selection and sorting and building the filtering bottom-up.

Entity Field Query

levelos's picture

Thanks for sharing @torotil. Another tool to consider EntityFieldQuery (EFQ), which we already use heavily throughout RedHen. It's a better approach than straight SQL in most cases when dealing with entities. Our very high level thinking on this is to create saved queries, which are collections of EFQ field and property filters, along with some metadata, including items per page, sorting, etc.

The only limitation is handling "or" queries as EFQ struggles with this a bit.

Lev Tsypin


ThinkShout, Inc.
thinkshout.com | twitter.com/levelos

Sounds good

seanberto's picture

I'd definitely like to connect on the activity tracking and engagement scoring soon. Could we do something on skype or take scheduling something to email? (sean at thinkshout . com)?

I think that having history, activity tracking, and engagement scoring tightly bundled with the core RedHen modules is important. I think that we're close enough to a shared vision for this that we can work together w/o too much difficulty - or at least make sure that RedHen CRM has the core APIs in place to support slightly divergent workflows.

Make sense? Again, we'd never want to dampen someone's interest on building their own solutions on top of RedHen. But since this is such a core component, we'd like to collaborate with stakeholders such as your team to make sure that we build something abstract and reusable.

Awesome!

Activity tracking

jessehs's picture

I didn't really delve into any of the code in the issue you posted, but I wanted to interject a reference to (yet another) activity tracking module you might be able to leverage. At Drupalcon in Denver, I had the privilege of sitting in on a presentation by Amitaibu about his Message module directed towards the maintainers of Drupal Commons, and it seems like a fantastic and open-ended way of tracking user activity. It might work well for tracking contact activity as well. Certainly worth a look.

Message

levelos's picture

Thanks for brining up the Message module, Jesse. It's definitely on our radar, and we plan on using for the upcoming RedHen logging/activity component. The placeholder approach it uses will be really useful, for example, in ensuring that the contact names in a log entry is current.

Our engagement scoring system is pretty specific in its approach and business logic. Message might make sense for the narrative part of that system, and we'll look into that after we see how it works for logging. Chat soon, Lev

Lev Tsypin


ThinkShout, Inc.
thinkshout.com | twitter.com/levelos

I've just gotten a chance to

jtbayly's picture

I've just gotten a chance to play with the example Redhen install profile. Very cool. But I found myself wondering about how to create "groups" of people. Then I remembered this conversation. If I'm understanding things right, the plan is to implement groups (or baskets if you prefer) at some point in the future, right?

I'm looking forward to it!

-Joseph

Organizations

levelos's picture

Joseph - Really depends on what you mean by groups of people. RedHen currently ships with organizations that can have contacts added to them. Organizations can further be 'groupified' if the redhen_org_group module is enabled. This allows organizations to act much as organic groups do, with access controlled content and notifications to contacts that are within the given organization.

The basket discussion is around the best way to collate temporary collections of contacts do act upon in different ways, E.g., sending a message.

Lev Tsypin


ThinkShout, Inc.
thinkshout.com | twitter.com/levelos

Controlled Content?

jhoffmcd's picture

Controlled Content - Does this mean we could also create fields conditional only to these 'Grouped' contacts? Or is just a way to serve these contacts with proprietary content? It would be great to be able to attach conditional fields to a contact depending on that 'Grouping' they are in, especially if you had contact types that switch groups periodically. You could change the contacts group, thereby 'switching' on/off certain fields.

Try Party?

jtbayly's picture

I could be wrong, but my memory is that the Party CRM was shooting for a system exactly like what you are describing, with people able to wear various different "hats" within an organization (such as teacher or student). Then, there would be various fields on somebody's profile dependent on which hats were assigned to them.

I'm talking dynamic groups

jtbayly's picture

I'm talking primarily about dynamic groups based on a set of criteria that can be saved. In other words, not temporary.

In terms of the purpose of these "groups", I'm basically just thinking that when you go to the hassle of building up a query of exactly the group of people you want to interact with, you want to be able to save that query. If I send an email every week to every contact that has donated at least $100 in the last year, and is younger than 35, and is living in Indiana or Pennsylvania I don't want to rebuild that query ever week. I just want to go to my saved "group" and have it dynamically update with the correct list so I can simply send the email.

As for using organizations as static groups, I'll need to try that. Organizations is a complete misnomer for what I would be doing with static groups, so I didn't even consider it.

Baskets / dynamic groups

torotil's picture

That's exactly what we're heading for with baskets: Making selections (queries), saving them, combining them and acting on them. I'd like to make it also support static groups. ATM this is only an interface concept so don't expect results soon.

RedHen CRM

Group organizers

Group notifications

This group offers an RSS feed. Or subscribe to these personalized, sitewide feeds:

Hot content this week