What is OfficeMedium?

A web-based collaborative suite and office intranet providing you and your team with a centralized solution for most of your daily business and communication needs. OfficeMedium is also the first-ever, Drupal-based SaaS offering.

Built with efficiency and convenience in mind, OfficeMedium offers a secured, hosted platform for:

  • Contact Information Management
  • Task and Event Coordination
  • Personal and Group Calendars
  • File Sharing, Storage, and Organization
  • Resource Repository
  • Secured Client and Outsider Integration
  • Automated Organization and Archiving
  • A Suite of Social and Communication Functions

OfficeMedium aims to offer businesses all of these critical functions, in a single, secured, web-accessible, easy-to-use, inexpensive software package that removes the reliance of email, individual desktop computers, and expensive servers and networked software.

Challenges

As long time Drupal developers and innovators, the decision to build on Drupal was an easy one. By utilizing the incredible contributed modules, Views, CCK, and Panels, and some of your own magic, just about anything can be accomplished. Initially we were faced with three main challenges:

  1. Developing the core software and features needed
  2. Handling a multi-company / multi-user / multi-role environment
  3. Charging and invoicing each company

Confident in our abilities, challenge #1 didn't seem like a matter of ability, but rather time. So we began with #2...

The Subinstance Module Package (SaaS Platform)

By design, each company has their own intranet, each with a number of user accounts, each user account holding up to three roles: Client, Employee, Superuser. Our first plan was to somehow utilize Organic Groups or something similar to be able to achieve this architecture while using a single database and single codebase. But that quickly became too confusing and too insecure. Also, we wanted each company to be accessible via companyname.officemedium.com. Our next focus was on the incredible AEgir hosting system. We thought we could create installation profiles that could be spawned for each company. But the hosting system was too complexed and not nearly as automated as we needed it to be. The next idea was to simply start from scratch. And that's how Subinstance.module was born.

Essentially, the Subinstance module allows for the completely automated spawning of subdomain sites, otherwise known as instances. The module can be given a custom SQL dump of an existing Drupal installation. This SQL template is our Intranet software, completely ready to go. From the admin's side, after actually configuring the module with all the needed server information, you can enter the subaddress and title of the site, press a button, and you now have a completely new, independant subsite - different database, shared codebase. The spawning is possible by passing some information to a few custom shell scripts, creating and filling the new database, entering the subsite into the sites directory, and creating a custom settings.php file.

Still, some issues existed, such as how to communicate with these instances, how to determine how many users existed on them, how to block access, delete them, invoke cron, detect problems, charge money based on their usage, etc. So the Subinstance package was created:

  • Subinstance: Automatically spawn subinstance Drupal installations
    • Replicates SQL dump of Drupal installation
    • Extensive configuration settings to work with most servers
    • Determine percentages of instances to invoke cron and fetch data from on each cron run
    • Admin panel to view all available instances. Each instance lists the current users, data usage, user account owner, and links to check the instance, fetch data, block/restore access, invoke cron, or delete the instance.
    • Optional email alert to notify on non-responsive instances
    • Block access to instances by directly altering the maintenance variable in their database
    • Hooks:
      • hook_subinstance_launch()
      • hook_subinstance_fetch()
      • hook_subinstance_lock()
      • hook_subinstance_delete()
  • Subclient: Active on each instance. Communicates with instance host
    • Required to be active on each instance
    • Receives initialization call from instance host to allow other modules to perform actions upon instance creation
    • Gathers user account and memory consumption data and passes it to instance host upon request
    • Receives request to invoke cron.
    • Hooks:
      • hook_subclient_initialize()
      • hook_subclient_fetch()
  • Subfinancial: Plugs into Subscribe.module (see below). Handles pricing of instance
    • Utilizes Subscribe.module's API (see below)
    • Set amount to charge per user account and gigabyte used
    • Set free amount of users and gigabytes used
    • Provide Subinstance form on Sign Up page
    • Block instance on failed payments
    • Optional 'Instance Trash' on cancelled subscriptions. If user cancels subscription, instance can be blocked but stored for X amount of days.
    • If trash is enabled, users have the option to restore their instance upon signing up again, if it's still available.

The Subscribe Module Package

Now that we've handled everything else, we need a proper way to charge users for their instances, invoice them, keep track of payments, securely handle credit card information, and issue recurring payments. After spending over a week searching for a simple Drupal subscription payment handler, and trying to reverse-engineer Ubercart, we, again, decided to start from scratch. Sometimes that's just the easiest way to go.

We wanted to create a subscription handler that was independent of any specific site features, so, Subscribe.module was made to be completely open, allowing other modules to plug-in and handle what the subscription offers. We also needed to decide on what payment gateway and method to use. Authorize.net was chosen because it seems the most developer-friendly and there are a lot of code examples out there already. Authorize.net offers ARB (Automatic Recurring Billing) and CIM (Customer Information Management). We needed rebilling, but ARB focuses more towards fixed subscription prices - and we needed to be flexible. CIM securely stores customer payment profiles in compliance of PCI standards. Also, you can easily tell Authorize.net to charge a CIM profile for any amount needed; very easily. So we decided to only use CIM, and build the module to handle rebilling and invoicing. And now we have a full subscription module package:

  • Subscribe: Handles user subscriptions, issuing payments, and invoicing
    • Set the payment interval at 1 day, 7 days, 14 days, 1 month, 3 months, etc.
    • Set a fixed price or allow module hooks to determine the price (any amount of modules can add or subtract from the price)
    • Set a max amount of payments to issue per cron run
    • Max Payment Errors: Set an amount of allowable consecutive payment errors before blocking a subscription. If a subscription's payment attempt fails, it will be retried every 24 hours, the amount set here. Once blocked, the user will be prompted and can submit for an unblock request in which their credit card will be tried again and unblocked only if successful.
    • Send configurable emails for all payment actions: Success, Fail, Blocked.
    • Provide the sign up form, and billing information change form.
    • Keeps track of every payment attempt made and invoicing
    • Optionally allow the first period to be free of charge (free trial)
    • Optionally allow billing information to not be required on free trial
    • Currently only supports the Authorize.net module (see below)
    • Hooks:
      • hook_subscribe_payment_api() [based on result or to fetch amount]
      • hook_subscribe_confirm_message()
      • hook_subscribe_cancel_message()
  • UC_Authorizenet: Implementation of Authorize.net CIM API (recycled from Ubercart)
    • Modified from Ubercart module to work without Ubercart, and with Subscribe.module
    • Handles the creation, deletion, updating, and charging of CIM profiles
    • Links CIM profile ID's to Subscription ID's

Creating the Intranet

As stated before, that was the most time-consuming, but not the most difficult. The software underwent radical changes almost every week or two. We did not have a set plan to begin with - more of like just seeing all of the great features we could implement that made sense, then working off of those. Also as stated before, the majority of the functionality stems from Views, Panels, and CCK. We used CCK to create 9 important content types which seemed to fit the needs of a business intranet:

  • Blog Entry
  • Company
  • Contact
  • Event
  • File
  • Poll
  • Private
  • Resource
  • Task

We created 3 simple user roles: Client, Employee, and Superuser. Every view, panel, page, and block use these roles to strictly keep certain users from viewing important information. Client accounts are a handy feature to have in an intranet, because having your clients be able to log in and submit events, tasks, and files, is an amazing productivity booster - and makes the software that much more useful.

To keep owners from rambling through settings, and most importantly, altering the Subclient settings (which effect price), the admin account was created and blocked, so no user has full administrator control of the Intranets.

Important Non-Core Modules Used

  • Views
  • Panels + Delegator
  • CCK
  • Activity (modified)
  • Calendar + Date
  • Privatemsg
  • Messaging + Notifications
  • Pathauto
  • Securepages (modified)
  • Popups
  • Node Access User Reference
  • RoleAssign (modified)
  • Content Access
  • Facebook Statuses (modified)
  • Shoutbox (modified)

More Information and a Demo of OfficeMedium

Homepage: http://www.officemedium.com

Screenshots: http://www.officemedium.com/screenshots

Live Demo: https://demo.officemedium.com

Features: http://www.officemedium.com/features

Solutions: http://www.officemedium.com/solutions

About Us: http://www.officemedium.com/about

Conclusion

This was an amazing accomplishment and project for all of us. It was extremely exciting to see it finally come to life, as we are now open for business. We are currently charging a monthly fee of $6/user, $1/gig, with a free 512MB of storage space, and your first month completely free (recently reduced by 25%).

These amazing Drupal modules will be shared with the community soon, just as all of you have shared your great software with us. We still need to go over them to make sure they are completely safe to share, as well as add a handful of features that we feel would make great additions.

Please leave any comments or questions below and I will answer them all. Check back for changes, as I will be adding and editing this page.

I hope you all enjoyed this post.

Thank you,

OfficeMedium

Comments

OfficeMedium’s picture

Now how do I add images to this?

EDIT: Forget that, I came across the book page about getting your case study promoted.

OfficeMedium’s picture

Great reviews of OfficeMedium:

OfficeMedium: Intranet for the Small Business User
http://www.readwriteweb.com/enterprise/2009/10/officemedium-intranet-for...

Could OfficeMedium be the SME portal of the future?
http://www.accmanpro.com/2009/10/12/could-officemedium-be-the-sme-portal...

OfficeMedium’s picture

Our pricing has been reduced by 25%: $6/user, $1 GB (free 512 MB).

Also, your first month is completely free so try it out.

No one has any questions or comments?

orniter’s picture

Thanks for the great write up! Your software is clean and performance is snappy -- hope it's very successful.

We're also developing a SaaS based on Drupal and look forward to your community contributions for multisites and billing.

Best wishes

OfficeMedium’s picture

Thank you very much for the compliments. It was my pleasure to provide this writeup. I will always be continuously adding to and updating it. I wanted to bring a ton of pictures into it but it needs to be promoted by a Drupal.org admin first, and I'm not sure how to go about doing that.

Do you have any details to share about your SaaS project? I'm always excited to hear about Drupal improvements and innovation.

I'm not sure when our modules will be ready for contribution, but it shouldn't be too far away. Being that they're relatively new, we're updating them on a weekly basis, and most importantly, making sure they are viable for any use.

Thanks again.

jaochoo’s picture

Thanks for sharing your story. The showcase is definitely one of the best community features of the Drupal community as it is a good practical learning source.

We are currently re-developing our corporate intranet using Drupal so your story is interesting for us. Our main focus is on social networking aspects, in particular some Facebook-like status/wall/activities thing (but not only including the social conversation but also updates and comments made to the more business-related features). What changes did you make to following modules (as you wrote above) and will these be part of the costum modules which you want to share with the community?
# Activity (modified)
# Facebook Statuses (modified)
# Shoutbox (modified)

Furthermore, I so far did not see a Facebook-like status or wall feature which includes the (imho) very important possibility of sharing links, photos, and YouTube (or maybe even other) videos. Did you expand achieve this? Otherwise, I am at the moment thinking about extending the existing module(s) to achieve that. I think it would be a benefit.

OfficeMedium’s picture

Thank you and you're very welcome.

That's interesting to hear. What are you using for your intranet? Custom built solution? Care to share any details?

Those three modules didn't contain any overly important modifications:

Activity had a few bugs in it that I reported, but no one seemed to care. For example, if user A created a node, then user B commented on it, it said that user A commented on it. And that goes for all actions related to the node. There were a few problems like this, and I posted solutions in the issue queue (i'd be glad to give you our copy if you needed it).

Facebook Statuses only received a few minor updates related to security issues. We are still using x2-beta3 because we simply cannot get the latest 2.0 release to function correctly. It also seems like a bit overkill as of now. We are working on some sort of middle ground.

Shoutbox received a load of updates - both style and functionality. Let's see if I can remember.

  • Replaced the admin icons
  • Better formated the block
  • Added the time of the shout inline to the message
  • Styled the user name
  • Styled the active user name (your name shows a different color; like an IM)
  • Moved the input box to the top of the page view
  • Added a message if auto-update was enabled
  • Added split settings for block amount and page amount of shouts
  • Added a separate callback function for the JS auto-update to handle the different amounts for the block and the page
  • (I think that's it)

As of now, the shoutbox and shared blog serve as perfect ways of sharing information, links, etc. The status could be used for that, but we see that being solely dedicated to your actual status (keeping things more work-related). There is room for more social features, and they will most likely come in the future (our social features now: http://www.officemedium.com/features/social ). We wanted our Intranets to show their true business function rather than a social play ground. In our opinion, business owners would be more attracted to integrate business software rather than a twitter clone (but we're not always right). We'll see what comes in the future..

If there is anything else I can provide for you, please let me know.

Good luck with your Intranet - feel free to use ours if you don't feel like working on yours.

jaochoo’s picture

OfficeMedium, first of all, thank you for taking the time to reply and apologize for not coming back to you earlier. We were still busy with the requirements analysis and conceptual design, and so it makes more sense to reply now as our project is defined more clearly:

What are you using for your intranet? Custom built solution? Care to share any details?

We will (more or less) completely use Drupal and develop a custom solution for our group. The origin of the project is where one of our board members started a personal blog and found out about the opportunities Social Media and the Web 2.0 can offer. He is just a rather innovative and experimental guy and when he likes something he wants to have it. ;-) So first he wanted to have a blog-like system allowing him and other board members to communicate to and with the staff about an upcoming change project. We soon figured out that it makes sense to extend the project as there is no intranet in place at the moment, neither for corporate nor one of the owned sub-companies does have an own intranet. So we decided to use the upcoming change project as a starting point for a new system, integrating both communication/conversation as well as some basic intranet features.

We wanted our Intranets to show their true business function rather than a social play ground. In our opinion, business owners would be more attracted to integrate business software rather than a twitter clone (but we're not always right).

I would classify our as something in between a multi-author blog,a social network and a classic intranet. Yet the main focus will still be on communication and networking more than on collaboration, CRM, project management, etc.
We decided to copy Facebook both in terms of layout/structure and functionality because of the following reasons: In terms of usability, we believe that our employees will more likely and easily adapt a system when it feels like the same system they are using every day for their social communications. In terms of concept/strategy, we believe that an intranet-like system nowadays has to account for developments like Facebook and Twitter, as well as we believe that giving our people something social and to play with will make our intranet more attractive and therefore will also lead them to the more serious business related stuff. Mixing social and business stuff leads to one of our two main points:

1) An activity stream like on Facebooks first page. Compared to your "Recent Content" box, we would need to theme it differently (which, as far as I follow the tracker for that module, should be possible), as well as we want to have everything (!) aggregrated in that box, not only recent contents but also the status updates, wall posts, user profile changes, people sharing pictures, etc. That's why I was particularly interested in your Activity modifications (I will answer below).
So I guess one challenge will be here, to theme it like Facebook, but even more to get everything aggregrated in the stream. If you have any experience about that I would appreciate if you could share it. So far I hope it should not be too difficult to integrate other activities into the stream as it is using Views.

2) We need to somehow model a data structure of Company---Department---Subdepartment---...---Employee (the 3 dots indicating more sub-departments), where every Company also wants to have different topics for their contents (because they simply operate in completelly different industries) and where it should easily be possible for a non-IT superuser to create a new company. I am still not sure about the way we want to achieve this. I can think of using OG for every company, using taxonomies, using custom content types and node relationships, or a mix of all. I am currently thinking of using custom content types and node relationships (discussing that in the general forums: http://drupal.org/node/693190), maybe together with taxonomies and/or OG. If you have any ideas or suggestions I would appreciate your help! I can see that you modelled it similarly, using a custom content type for "Company" and "Contact". We need to have it a little bit more complex as described above. However, I like the way you are using the "Add new company" opening a thickboy when creating a new contact; would you share how to do that?

Activity had a few bugs in it that I reported, but no one seemed to care. For example, if user A created a node, then user B commented on it, it said that user A commented on it. And that goes for all actions related to the node. There were a few problems like this, and I posted solutions in the issue queue (i'd be glad to give you our copy if you needed it).

I would appreciate if you could provide your copy. Do you know if they integrated your bugfixes?

Facebook Statuses only received a few minor updates related to security issues. We are still using x2-beta3 because we simply cannot get the latest 2.0 release to function correctly. It also seems like a bit overkill as of now. We are working on some sort of middle ground.

Would you tell what exactly you are working on? However, I have to admit that due to the delay we had I still wasn't able to try out the Facebook-like statuses module.

Shoutbox received a load of updates - both style and functionality.

Did you submit these updates so that they are part of a future release?

Thanks for sharing your experiences!

OfficeMedium’s picture

Hey,

Thanks for the reply and you're very welcome for sharing. Your project sounds very interesting and it seems like you have you work cut out for you. Best of luck with everything. I'll try to address your questions..

I am still not sure about the way we want to achieve this. I can think of using OG for every company, using taxonomies, using custom content types and node relationships, or a mix of all. I am currently thinking of using custom content types and node relationships (discussing that in the general forums: http://drupal.org/node/693190), maybe together with taxonomies and/or OG. If you have any ideas or suggestions I would appreciate your help!

We're actually just getting started on trying to put together some sort of grouping system. Obviously, as you pointed out, OG is the first place to look. A few users said that they're looking for a way to group nodes and have them visible to only the members in the group. It makes perfect sense. We had that idea from the start but abandoned it to keep things simple and easy. I've been messing around with OG, but I don't really like it. It seems to unorganized and confusing (so far). I'm not really sure what the plan is now.

I can see that you modelled it similarly, using a custom content type for "Company" and "Contact". We need to have it a little bit more complex as described above. However, I like the way you are using the "Add new company" opening a thickboy when creating a new contact; would you share how to do that?

That would be the Popups API, Popups: Add & Reference, and CCK Node Reference. All very easy to setup.

I would appreciate if you could provide your copy. Do you know if they integrated your bugfixes?

[http://www.officemedium.com/activity.tar.gz] No they did not. The maintainers seems to only care about releasing the next version. I have to warn you though, there is still an active bug in here that we worked around. I've commented out line 714 in activity.module. For reasons still unknown, something with the node permissions was causing the activity blocks to show only a few items (yeah, I have no idea how these people missed this almost a year now). So the permissions check was removed, and that works fine for us, because we use other permissions to keep unauthorized eyes out of the activity streams.

Would you tell what exactly you are working on? However, I have to admit that due to the delay we had I still wasn't able to try out the Facebook-like statuses module.

Everything related to this was put on hold. We're content with what we're using now.

Shoutbox received a load of updates - both style and functionality. Did you submit these updates so that they are part of a future release?

I posted them but I don't think they were added to the package. I could be wrong though. I'll provide this to you if you want also.

Zahor’s picture

Great site. I think you are incorrect in saying Office Medium is the first Drupal based Saas offering (unless it's several years old). I've worked myself on a Drupal based Saas myself. It is marketed directly to clients so unless you were a potential client, you'd never hear about it. If I'm not mistaken, over 3 years ago, Civicspacelabs was offering a Drupal & CiviCRM based service also.

OfficeMedium’s picture

Well I could definitely be wrong, but I'm yet to come across a true SaaS built on Drupal. Perhaps you could link me to those examples so I could check them out for myself.

Thanks

Th30philus’s picture

Thank you very much for sharing. It was very educational, and I look forward to testing/using your contrib modules.

How do you deploy updates of the software to the sub-instances?

How do you preserve customer preferences and option choices during updates?

OfficeMedium’s picture

Well thank you for the comments.

I look forward to testing/using your contrib modules.

As for the contrib modules, it's taking a little longer than we expected. We're still adding features to most of the modules, killing bugs, improving security, improving performance, etc. Before we release something that reflects our company we want to make sure that not only does it work perfectly, but that it won't create any security concerns for us. We also want to make sure that the entire package can be used by anyone, for any application. It will take some time - especially because things are quite busy around here. But they'll come eventually. Thanks for the patience.

How do you deploy updates of the software to the sub-instances?

We run updates a number of different ways depending on what they entail. The easiest way is to use the subclient module, since it runs on all of the instances. Included in the module is subclient.inc, which is used just for cron. There is a variable set for subclient that keeps track of the number of updates that have been ran. Every time cron is invoked, the module checks that file for a new update, and executes it if there is a new one available. The updates are usually just db_querys or variable changes.

If the update is really simple, we can just edit the databases directly, but sometimes that could take a while. If absolutely needed, we can make the changes via the admin section of each instance.

How do you preserve customer preferences and option choices during updates?

Well, there aren't any updates that are going to change user data/settings, etc. Each customer/company gets their own installation/DB. Are you referring to something else?

I hope that helps. Feel free to ask anything else you might want to.

ddorian’s picture

are you still planning on releasing the modules you created?