Meteor is still in it’s infancy. There’s a good chance you’ll want to do something it is not mature enough to achieve right now. What’s a poor developer to do? When you can’t roll your own solution, you could consider using an external service that talks to your meteor server to get things done. In this article I’ll describe a couple of ways we did this to augment League, our sport-management application.

Sending emails

As a seasoned Rails developer, I’m used to the nicer things when it comes to emails. ActionMailer is pretty good these days, and the premailer gem allows you to use (most) of your styles freely within your emails.

Things are a little more raw and exciting in the meteor world; Node modules exist for sending emails, but integrating node modules into a meteor deployment can be a challenge, and it doesn’t seem like a premailer replacement is out there.

So, we took the “easy” road, and set up a simple rails project with a single controller + action: to fire off emails:

class MailsController > ApplicationController
  def create
    mail = params[:mail].to_sym
    data = ActiveSupport::JSON.decode(params[:data]).with_indifferent_access
 
    Notifications.send(mail, data).deliver
    head :ok
  end
end

Calling out to the mailer from meteor easy enough:

Meteor.http.call 'POST', LeagueMailerConfig.url, options

Serving calendars via .ics

We wanted to make keeping track of a League team easier by integrating with calendaring apps via the .ics format. It isn’t possible using pure meteor right now because there is no server side routing at the moment (it serves up the same html|js|css mix whatever URL you hit).

We decided to re-purpose the league-mailer rails server mentioned above and create an end-point that communicates to the league app via DDP – meteor’s distributed data protocol. DDP is a pretty simple protocol and it wasn’t difficult to create a ruby DDP client. Here’s the gem if you want to use it yourself.

Then we just needed to use event-machine to subscribe to our games publication to fill out a games collection and get our results:

module LeagueServer
  # pretty simplistic, but it seems to work
  def self.get_games(team_ids)
    games = nil
    EM.run do
      league_client = if ::Rails.env.production?
        RubyDdp::Client.new('beta.getleague.com', 80)
      else
        RubyDdp::Client.new('localhost', 3000)
      end
 
      league_client.onconnect = lambda do |event|
        league_client.subscribe('games', [team_ids]) do |result|
          games = league_client.collections['games']
          EM.stop_event_loop
        end
      end
    end
 
    games
  end
end

From there, it’s standard rails routing and some harnessing of the excellent iCalendar gem to get the right data published at a URL of your choice!

In the future I hope to pull both of these services inside the League meteor app.

Tom Coleman

Co-creator of bindle.me, searching for simplicity, quality and elegance in technology, products and code.

See all Tom Coleman's posts

6 Responses to “Augmenting Meteor: plugging gaps with external services.”

  1. Jason Cochran says:

    Hello. I am trying to use this in a .rb file and running it using ruby ddp.test.

    The output is:

    ddp server starting…
    client: #

    …, but nothing else is printed out. It is not connecting for some reason. There are no errors.

    Here is the code:

    require ‘ruby-ddp-client’
    require ‘eventmachine’

    # defines the FAYE_TOKEN (auth token)
    #require File.expand_path(‘../config/initializers/faye_token.rb’, __FILE__)

    class Server

    approvals = nil
    EM.run do
    puts “ddp server starting…”
    ddp_client = RubyDdp::Client.new(‘localhost’, 3000)
    puts “client: #{ddp_client}”
    ddp_client.onconnect = lambda do |event|
    puts “connected to meteor…”
    ddp_client.subscribe(‘approvals’, [approval_ids]) do |result|
    puts “result: #{result}”
    approvals = ddp_client.collections['approvals']
    EM.stop_event_loop
    end
    end
    ddp_client.connect
    end
    puts “approvals: #{approvals}”

    end

    new Server

  2. Zach says:

    I know this is a fairly old post, but I think it’s exactly what I need. I’m almost to the point of understanding it, but just a little confused. So with the ruby ddp client, I can have a complete Meteor app (using it’s default mongo db) and connect to it with a rails app via DDP to subscribe to the collections? Do I need to create any added/removed/etc methods to update the rails app or will that happen automatically?

    • Tom Coleman says:

      Hey Zach,

      I don’t think the ruby DDP gem fires any events right now when items are added etc. I think behind the scenes it keeps the collection up-to-date but there wouldn’t be any event that told you it happened. I haven’t looked at the code in some time (!) so I’m not 100% sure.

      The way this code works, the sub will be re-established for every request to your Rails app. Whether or not this is a good idea is pretty debatable.

      Tom

  3. Bremma says:

    Hi there, we are aplnning a big cycling adventure and are LOVING the bindle. We have seen blogs that have linked it INTO their site, but we have not been able to find any advice on how to do that. All we can do is paste links but we would love to make it workable on our wordpress site. Do you have any advice on how we can do it? Thanks for your time
    Cheers, Emma

    • Dominic H. Nguyen says:

      Thanks Emma. You can embed a Bindle -similar to youtube- by going to your Bindle page and clicking on the embed icon which lives at the top of the page under the title next to the Facebook and Twitter icons.

Leave a Reply

  • Search: