Customizing Trello with Ruby

Share this article

Customizing Trello with Ruby
trello-icon

Trello is a great collaboration tool. It’s based around boards, which contain lists of cards. How you use it is up to you, as it’s one of those simple tools with many uses. Want to plan or coordinate with multiple people, or just manage your own todos? Just set up a board and get going.

All of Trello’s features can be controlled through its API, and it’s completely free, including use of the web and mobile apps, as well as access to the API. With the ruby-trello gem you can be automating your boards in no time.

Getting Started

Sign up if you haven’t already, and grab your developer keys, as you will need these to make API requests. Install the ruby-trello gem

gem install ruby-trello

and request a “member token” that your brand new application can use to identify itself

TRELLO_DEVELOPER_PUBLIC_KEY="your key" # found at https://trello.com/1/appKey/generate
puts "please visit"
puts "https://trello.com/1/authorize?key=#{TRELLO_DEVELOPER_PUBLIC_KEY}&name=SitepointTutorial&expiration=never&response_type=token&scope=read,write"
puts "and take note of the token"

Now we can start setting up and using the Trello API

require 'trello'

TRELLO_DEVELOPER_PUBLIC_KEY="your key"
TRELLO_MEMBER_TOKEN="the token you just got"

Trello.configure do |trello|
  trello.developer_public_key = TRELLO_DEVELOPER_PUBLIC_KEY
  trello.member_token = TRELLO_MEMBER_TOKEN
end

Trello::Board.all.each do |board|
  puts "* #{board.name}"
end

Building Blocks: Boards, Lists and Cards

If all went well, you just saw a list of your existing Trello boards pop up in the terminal. Boards are the top-level organizing concept in Trello, represented by instances of Trello::Board in the Ruby API wrapper.

Note that Trello::Board has a class method named all, just like ActiveRecord models do. This is no coincidence. ruby-trello makes use of ActiveModel under the hood, making its core classes walk and quack a lot like Rails models. This makes the API seem familiar to Rails developers, and it means that you can use instances of Trello::Board, Trello::Card or Trello::List with Rails form helpers. For example, all these objects have a valid? method, just like ActiveRecord instances, and when invalid the errors method will tell you what the problem is.

Building on Top of Trello

To demonstrate using the API, we will implement a simple “app” using Trello as the user interface. Imagine as an organization you want to keep an eye on how people talk about you on Twitter. As a first step, you want to simply count the number of positive, negative, and neutral tweets. To do so, we will set up a board with four lists. For every tweet, a card will pop up in the “Incoming” list. The friendly customer support people can then drag each tweet to the “Positive”, “Neutral”, or “Negative” list. At the top of each list, we’ll add a card that keeps a tally of the number of cards added. Every now and then we archive all cards and update the count.

Here you see our app in action, tracking mentions of the term “books”.

Twitter Follow-up "app" built on top of Trello

Creating the Board and Lists

To get started, get a reference to our board. If it isn’t found, create it. Trello will already add a few lists for us (Todo, Done), but we prefer to set up our own. As such, close the Trello-provided lists first and then add our own. Finally, add the card that will keep track of the count to the last three lists.

BOARD_NAME = 'Twitter Followup'
BOARD_DESC = 'Handling mentions on Twitter'
LIST_NAMES = ['Incoming', 'Positive', 'Neutral', 'Negative']

board = Trello::Board.all.detect do |board|
  board.name =~ BOARD_NAME
end

unless board
  board = Trello::Board.create(
    name: BOARD_NAME,
    description: BOARD_DESC
  )
  board.lists.each(&:close!)

  LIST_NAMES.reverse.each do |name|
    Trello::List.create(name: name, board_id: board.id)
  end

  board.lists.drop(1).each do |list|
    Trello::Card.create(name: '[0]', list_id: list.id)
  end
end

Notice how Trello::Card and Trello::List each take the id of the enclosing entity, respectively the list and the board.

For a List, the ruby-trello gem doesn’t give you more options than that. For a Card you can get more creative though.

card = Trello::Card.create(
  name: 'card with memberd and labels',
  list_id: list.id,
  card_labels: [ :yellow, :green ],
  member_ids: [ Trello::Member.find('arnebrasseur').id ]
)

Updating a card’s attributes works by simply setting new values, and consequently calling card.save.

card = board.lists[0].cards[0]
card.name = 'First card in the first list, I am'
card.desc += "\n\nThe end of my description, this is."
card.save

Notice that ActiveRecord-like syntax board.lists.create(...) does not work. To add a list to a board, or a card to a list, you have to explicitly get the id of the board or list and pass it to the new object.

The Beating Heart

To make our app ‘tick’, we will need two different background jobs. One is responsible for pushing Tweets onto the board, the other takes care of counting and archiving the cards that have been sorted into categories. We will combine both in a single script, so we can invoke it like this:

$ twitter_followup.rb stream sitepoint

To get all tweets that mention Sitepoint Use Twitter’s streaming API, or:

$ twitter_followup.rb process

To process cards that have been sorted.

The following code block is a straightforward way of reading the command line arguments and delegating to either a listen_to_tweets method, or to process_sorted_cards. The board is already available to us. The definition of twitter_client is beyond the scope of this article, but you can have a look at the complete script, or find out more about using the Twitter gem on Sitepoint.

case ARGV[0]
when 'stream'
  topics = ARGV.drop(1)
  listen_to_tweets(board, twitter_client, topics)
when 'process'
  loop do
    process_sorted_cards(board)
    sleep 5
  end
end

Drinking From Twitter’s Firehose

Support for Twitter’s streaming API is a relatively new addition to twitter gem. Lucky for us, since it makes implementing listen_to_tweets short and sweet.

def listen_to_tweets(board, twitter_client, topics)
  incoming_list = board.lists.first

  twitter_client.filter(:track => topics.join(",")) do |object|
    if object.is_a?(Twitter::Tweet)
      Trello::Card.create(
        list_id: incoming_list.id,
        name: object.text,
        desc: object.url.to_s
      )
    end
  end
end

The code sets the tweet’s text as the card’s “name”, which is the part you see when looking at the board. When you open a card you see its description, which is used here to keep a link back to the original tweet. We will pull those pieces of data back out again before archiving the card.

Adding Things Up

To do the actual count-and-archive step, we implement a few helper methods. The first returns the Trello::List instances that need processing by looping over the lists on the board. Using Enumerable#find returns the first object for which the given block returns a truthy value.

def score_lists(board)
  LIST_NAMES.drop(1).map do |name|
    board.lists.find { |list| list.name == name }
  end
end

Similarly, we need a reference to the Trello::Card that holds the count for each column. A regular expression looks for a card with only digits surrounded by square brackets. The \A, which matches the beginning, and \z, which matches the end of the string, are important anchors to prevent false positives. They are usually preferred over ^, $, since these will match the beginning and end of any line in a multi-line string.

def find_score_card(list)
  list.cards.find do |card|
    card.name =~ /\A\[\d+\]\z/
  end
end

Finally, process each card that has been sorted, archive it, and update the score card. The score card’s description keeps a list of all the tweets that have been added to it. Card descriptions allow Markdown formatting. To get a bullet point list, including links to the original tweets, our markup will look like this

* tweet text [](http://link.to.the.tweet)`
* next tweet #trelloRuby [↗](http://link.to.the/second/tweet)`

The process_card method handles an individual card that is ready to be archived:

def process_card(card, score_card)
  old_score = score_card.name[/\d+/].to_i
  new_score = old_score + 1

  tweet_text = card.name
  tweet_link = card.desc

  score_card.name = "[#{new_score}]"
  score_card.desc = "* #{tweet_text} [↗](#{tweet_link}) \n" + score_card.desc

  card.closed = true

  [card, score_card].each(&:save)
end

Note that the action called “archiving” in Trello’s UI is consistently called “closing” in the API. This goes for boards, lists, and cards, as well. Trello does not allow deleting anything, but it’s possible to archive/close any object. This means it will longer show up, unless explicitly requested. Setting the closed property and saving the card (or list, board), can also be done in a single step, e.g. card.close!.

Almost done, we just need to go through the score_lists and process each card, except the score_card itself:

def process_sorted_cards(board)
  score_lists(board).each do |list|
    score_card = find_score_card(list)
    list.cards.each do |card|
      unless card.id == score_card.id
        process_card(card, score_card)
      end
    end
  end
end

Go Out and Play

Trello has a nice, clean interface, and through the API, a lot is possible.

  • Extend our Twitter app so writing comments automatically replies to the tweet.
  • Integrate with Git or Github through post-commit and web hooks, to schedule a code review task for every commit.
  • Perhaps randomly adding animated cat gifs to each card on Friday afternoon sounds more like your thing.

So what would you like to build? Let us know in the comments!

Frequently Asked Questions (FAQs) about Customizing Trello with Ruby

How can I customize Trello using Ruby?

Customizing Trello using Ruby involves using the Trello API. You’ll need to create an application on Trello’s developer platform, get your API key and token, and then use these to interact with the Trello API using Ruby. You can create, update, and delete cards, lists, and boards, among other things. The Ruby Trello gem is a useful tool for this, as it provides a convenient interface for the Trello API.

How can I archive and unarchive cards in Trello using Ruby?

Archiving and unarchiving cards in Trello using Ruby can be done using the Trello API. You can use the ‘closed’ attribute of a card to archive or unarchive it. Setting ‘closed’ to true will archive the card, and setting it to false will unarchive it. The Ruby Trello gem provides methods for updating card attributes, including ‘closed’.

How can I change the background of a Trello board using Ruby?

Changing the background of a Trello board using Ruby is not directly supported by the Trello API. However, you can create a custom application that uses the Trello API to interact with Trello, and then use CSS to change the appearance of the Trello board in your application. This would require knowledge of both Ruby and CSS.

How can I find archived information on Trello using Ruby?

You can find archived information on Trello using Ruby by using the Trello API. You can use the ‘cards’ endpoint with the ‘filter’ parameter set to ‘closed’ to get a list of all archived cards. The Ruby Trello gem provides a method for getting all cards on a board, which you can then filter to find the archived cards.

How can I add personality to my Trello boards using Ruby?

Adding personality to your Trello boards using Ruby can be done by customizing the appearance and behavior of your boards using the Trello API. You can create custom card covers, labels, and stickers, and you can use webhooks to create custom behaviors. The Ruby Trello gem provides methods for creating and updating these elements.

How can I delete cards in Trello using Ruby?

Deleting cards in Trello using Ruby can be done using the Trello API. You can use the ‘delete’ method provided by the Ruby Trello gem to delete a card. Note that this will permanently delete the card, not just archive it.

How can I create a new Trello board using Ruby?

Creating a new Trello board using Ruby can be done using the Trello API. You can use the ‘create_board’ method provided by the Ruby Trello gem to create a new board. You’ll need to provide a name for the board, and you can also specify other attributes such as the board’s description and visibility.

How can I add a new card to a Trello board using Ruby?

Adding a new card to a Trello board using Ruby can be done using the Trello API. You can use the ‘create_card’ method provided by the Ruby Trello gem to create a new card. You’ll need to provide a name for the card, and you can also specify other attributes such as the card’s description and due date.

How can I update a Trello card’s description using Ruby?

Updating a Trello card’s description using Ruby can be done using the Trello API. You can use the ‘update_card’ method provided by the Ruby Trello gem to update a card’s description. You’ll need to provide the new description for the card.

How can I move a card to a different list on a Trello board using Ruby?

Moving a card to a different list on a Trello board using Ruby can be done using the Trello API. You can use the ‘move_to_list’ method provided by the Ruby Trello gem to move a card to a different list. You’ll need to provide the ID of the list you want to move the card to.

Arne BrasseurArne Brasseur
View Author

Arne is a developer, public speaker, programming coach, author and open-source contributor. With a passion for both human and programming languages, he has spent the last decade teaching and exploring the finer points of Ruby, LISP, Haskell, Mandarin Chinese, and others. When not hopping conferences or Pacific islands, he can be found at his home base in Berlin, brewing fine teas while pondering the future of open-source and the web.

GlennG
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week