diff --git a/app/helpers/twitter_helper.rb b/app/helpers/twitter_helper.rb
index 7ce28be9c3ea6ea855062f19ca09abafbf741a88..9f1015f6507331d0f11ebfe00bbc005a41357a41 100644
--- a/app/helpers/twitter_helper.rb
+++ b/app/helpers/twitter_helper.rb
@@ -1,88 +1,14 @@
 module TwitterHelper
-  def twitter_enabled
-    if Rails.application.secrets.twitter
-      Rails.application.secrets.twitter['enabled'] == true
-    end
-  end
-
-  def twitter_client
-    Twitter::REST::Client.new do |config|
-      config.bearer_token = Rails.application.secrets.twitter['bearer_token']
-    end
-  end
-
-  def twitter_handle
-    Rails.application.secrets.twitter['twitter_handle']
-  end
 
-  def twitter_user_info
-      $twitter_user_info ||= []
+  def twitter
+    @twitter ||= TweetSource.new Rails.application.secrets.twitter,
+      Rails.application.secrets.twitter['bearer_token']
   end
 
-  def update_twitter_info
-    twitter_user_info[0] = Time.now
-    twitter_user_info[1] = twitter_client.user(twitter_handle).name
-    twitter_user_info[2] = twitter_client.user_timeline(twitter_handle, {:count => 200}).select{ |tweet| tweet.text.start_with?('RT','@')==false}
-    if twitter_user_info[2] == nil
-      error_handling
-      twitter_user_info[3] = "The twitter handle does not exist or the account's tweets are protected. Please change the privacy settings accordingly or contact your provider-admin."
-    end
-  rescue Twitter::Error::BadRequest
-    error_handling
-    twitter_user_info[3] = "The request for displaying tweets is invalid or cannot be otherwise served."
-  rescue Twitter::Error::Unauthorized
-    error_handling
-    twitter_user_info[3] = "Your bearer-token is invalid or the account's tweets are protected and cannot be displayed. Please change the privacy settings of the corresponding account, check your bearer-token in the secrets-file or contact your provider-admin to have the tweets shown."
-  rescue Twitter::Error::Forbidden
-    error_handling
-    twitter_user_info[3] = "The request for displaying tweets is understood, but it has been refused or access is not allowed."
-  rescue Twitter::Error::NotAcceptable
-    error_handling
-    twitter_user_info[3] = "An invalid format is specified in the request for displaying tweets."
-  rescue Twitter::Error::TooManyRequests
-    error_handling
-    twitter_user_info[3] = "The rate-limit for accessing the tweets is reached. You should be able to display tweets in a couple of minutes."
-  rescue Twitter::Error::NotFound
-    error_handling
-    twitter_user_info[3] = "The twitter hanlde does not exist."
-  rescue Twitter::Error
-    error_handling
-    twitter_user_info[3] = "An error occured while fetching the tweets."
-  end
-
-  def error_handling
-    twitter_user_info[2] = []
-    twitter_user_info
-  end
-
-  def cached_info
-    if twitter_user_info[0] == nil
-      update_twitter_info
-    else
-      if Time.now > twitter_user_info[0] + 15.minutes
-        update_twitter_info
-      end
-    end
-    twitter_user_info
-  end
+  delegate :tweets, :error_message, :all_tweets_count, :num_of_tweets,
+    to: :twitter
 
-  def twitter_name
-    cached_info[1]
-  end
-
-  def num_of_tweets
-    3
-  end
-
-  def tweets
-    cached_info[2].take(num_of_tweets)
-  end
-
-  def error_message
-    cached_info[3]
-  end
-
-  def all_tweets_count
-    twitter_user_info[2].count
-  end
+  delegate :enabled?, :handle, :name,
+    to: :twitter,
+    prefix: true
 end
diff --git a/app/models/tweet_source.rb b/app/models/tweet_source.rb
new file mode 100644
index 0000000000000000000000000000000000000000..aba74cfdb8fdcc1e0a28ffb5403d609d6fed34eb
--- /dev/null
+++ b/app/models/tweet_source.rb
@@ -0,0 +1,106 @@
+#
+# Tweet Source
+#
+# A thin wrapper around the twitter api. Allows fetching tweets of a
+# single account.
+#
+# Configuration is handed over in an initializer.
+#
+
+class TweetSource
+
+  def initialize(config, token)
+    @config = config
+    @token = token
+  end
+
+  def handle
+    config['handle']
+  end
+
+  def enabled?
+    config.present? && config['enabled']
+  end
+
+  def name
+    cached_info[1]
+  end
+
+  def num_of_tweets
+    3
+  end
+
+  def tweets
+    cached_info[2].take(num_of_tweets)
+  end
+
+  def error_message
+    cached_info[3]
+  end
+
+  def all_tweets_count
+    user_info[2].count
+  end
+
+  protected
+
+  attr_reader :config, :token
+
+  def client
+    Twitter::REST::Client.new do |client|
+      client.bearer_token = token
+    end
+  end
+
+  def user_info
+    $user_info ||= []
+  end
+
+  def update_info
+    user_info[0] = Time.now
+    user_info[1] = client.user(handle).name
+    user_info[2] = client.user_timeline(handle, {:count => 200}).select{ |tweet| tweet.text.start_with?('RT','@')==false}
+    if user_info[2] == nil
+      error_handling
+      user_info[3] = "The twitter handle does not exist or the account's tweets are protected. Please change the privacy settings accordingly or contact your provider-admin."
+    end
+  rescue Twitter::Error::BadRequest
+    error_handling
+    user_info[3] = "The request for displaying tweets is invalid or cannot be otherwise served."
+  rescue Twitter::Error::Unauthorized
+    error_handling
+    user_info[3] = "Your bearer-token is invalid or the account's tweets are protected and cannot be displayed. Please change the privacy settings of the corresponding account, check your bearer-token in the secrets-file or contact your provider-admin to have the tweets shown."
+  rescue Twitter::Error::Forbidden
+    error_handling
+    user_info[3] = "The request for displaying tweets is understood, but it has been refused or access is not allowed."
+  rescue Twitter::Error::NotAcceptable
+    error_handling
+    user_info[3] = "An invalid format is specified in the request for displaying tweets."
+  rescue Twitter::Error::TooManyRequests
+    error_handling
+    user_info[3] = "The rate-limit for accessing the tweets is reached. You should be able to display tweets in a couple of minutes."
+  rescue Twitter::Error::NotFound
+    error_handling
+    user_info[3] = "The twitter handle does not exist."
+  rescue Twitter::Error
+    error_handling
+    user_info[3] = "An error occured while fetching the tweets."
+  end
+
+  def error_handling
+    user_info[2] = []
+    user_info
+  end
+
+  def cached_info
+    if user_info[0] == nil
+      update_info
+    else
+      if Time.now > user_info[0] + 15.minutes
+        update_info
+      end
+    end
+    user_info
+  end
+
+end
diff --git a/app/views/home/_content.html.haml b/app/views/home/_content.html.haml
index c7902b1698bb39a490a961b5341126e2aad9057e..865b95c193974c08f7e8d44d5e25b7837228c0c2 100644
--- a/app/views/home/_content.html.haml
+++ b/app/views/home/_content.html.haml
@@ -1,4 +1,4 @@
-- if twitter_enabled == true
+- if twitter_enabled? == true
   .col-md-8
     .row
       %h1= t(:welcome, :provider => APP_CONFIG[:domain])
diff --git a/app/views/twitter/_index.html.erb b/app/views/twitter/_index.html.erb
index 6e592c75a5e1747202bdd3b05f5b77c2f6e0a8bf..19e787021a0b24e97ece51e601c639ece5db2633 100644
--- a/app/views/twitter/_index.html.erb
+++ b/app/views/twitter/_index.html.erb
@@ -1,4 +1,4 @@
-<% if twitter_enabled == true %>
+<% if twitter_enabled? == true %>
   <div class="twitter">
 
       <div class="twitter_header">