diff --git a/services/tumblr.rb b/services/tumblr.rb
new file mode 100644
index 000000000..6413025cf
--- /dev/null
+++ b/services/tumblr.rb
@@ -0,0 +1,42 @@
+class Service::Tumblr < Service
+ string :oauth_token, :oauth_secret, :blog_url
+
+ def receive_push
+ return unless payload['commits']
+
+ repository = payload['repository']['name']
+ compare_url = payload['compare']
+
+ title = "New commits pushed to #{repository}."
+ description << "
"
+ payload['commits'].each do |commit|
+ description << "- #{commit['message']}
"
+ end
+ description << "
"
+
+ post(title, compare_url, description)
+
+ end
+
+ def post(title, url, description
+
+ params = {:type => "link", :title => title, :url => url, :description => description}
+ access_token = ::OAuth::AccessToken.new(consumer, data['oauth_token'], data['oauth_secret'])
+ consumer.request(:post, "/v2/#{data['blog_url']}/post"
+ access_token, { :scheme => :query_string }, params)
+ end
+
+ def consumer_key
+ secrets['tumblr']['key']
+ end
+
+ def consumer_secret
+ secrets['tumblr']['secret']
+ end
+
+ def consumer
+ @consumer ||= OAuth::Consumer.new(consumer_key, consumer_secret,
+ :site => "http://api.tumblr.com")
+ end
+
+end
diff --git a/test/tumblr_test.rb b/test/tumblr_test.rb
new file mode 100644
index 000000000..8d5655bc9
--- /dev/null
+++ b/test/tumblr_test.rb
@@ -0,0 +1,29 @@
+require File.expand_path('../helper', __FILE__)
+
+class TumblrTest < Service::TestCase
+ def test_push
+ svc = service({'token' => 't', 'secret' => 's'}, payload)
+
+ def svc.post(title, url, description)
+ @params = {:title => title, :url => url, :description => description}
+ end
+
+ svc.receive_push
+ assert_equal 'test', @params['title']
+
+ end
+
+ def test_oauth_consumer
+ svc = service({'oauth_token' => 't', 'oauth_secret' => 's'}, payload)
+
+ svc.secrets = {'tumblr' => {'key' => 'ck', 'secret' => 'cs'}}
+ assert_equal 'ck', svc.consumer_key
+ assert_equal 'cs', svc.consumer_secret
+ assert svc.consumer
+ end
+
+ def service(*args)
+ super Service::Tumblr, *args
+ end
+
+end