Sign in

Зарегистрируйтесь, чтобы стать полноправным участником сообщества Masterpro.ws.

Twitter-инструментарий на Ruby on Rails

Показанный далее программный код представляет из себя не более чем концепт идеи, задумку набора инструментов для работы в Twitter, написанный аффтором - или, лучше сказать, быстро набросанный - как приложение Ruby on Rails на основе gem 'twitter'.

 

 

 

Рабочий пример описанного в статье кода, в числе других Rails Examples - всегда возможно найти в тестовом блоге автора на herokuapp.com, welcome.

 

Код полностью работоспособен, что удостоверяет скринкаст... если идея вас заинтересовала - вы можете попробовать причесать и сделать логику несколько более аккуратной, избавиться от ненужных инстансных переменных и elsif, упорядочить методы и создать для удобства работы классы и тесты, а также все, что вашей душе угодно. Увы, после очередного закручивания гаек своего API зловредным Твиттером не вижу особого смысла в продолжении работы над данным проектом. По секрету скажу, что бдительные модераторы Twitter, испросив ссылки на демки (да, теперь вот так), моментально отказали мне в девелоперском доступе даже к одному-единственному тви-аккаунту, токены которого я запрашивал; что заведомо вселяет немалые сомнения в рентабельности дальнейшей разработки. Жаль, конечно, проект обещал быть интересным и востребованным... ну, что же; в свете текущих событий, политических и не очень... нелепо было бы обижаться на сотрудников Twitter, бегущих сегодня как огня не только ботов, но и вообще любых попыток автоматизации действий пользователя в своей соц. сети. Повторюсь, их право.

 

Примечание. Приложение оптимизировано для работы (функции фолловинг и анфолловинг) с популярными твиттер-аккаунтами, насчитывающими большое количество читателей: тестировал, в частности, на собственных тви-акках, 15 - 18 тыс. фолловеров в каждом. В этом случае все значительно медленнее, чем показывает скринкаст; кроме того, вступают в действие лимиты Твиттера, о которых подробнее в этом материале.

 

config = {
      consumer_key: **********,
      consumer_secret: *********,
      access_token: ********,
      access_token_secret: *********
    }

    if (params[:select_action] == 'follow') || (params[:select_action] == 'unfollow')
      client = Twitter::REST::Client.new config

      def get_follower_ids(client, user_id)
        follower_ids = []
        next_cursor = -1
        while next_cursor != 0
          cursor = client.follower_ids(user_id, cursor: next_cursor)
          follower_ids.concat cursor.attrs[:ids]
          next_cursor = cursor.send(:next_cursor)
        end
        follower_ids
    end

      def get_friend_ids(client, user_id)
        friend_ids = []
        next_cursor = -1
        begin
          while next_cursor != 0
            cursor = client.friend_ids(user_id, cursor: next_cursor)
            friend_ids.concat cursor.attrs[:ids]
            next_cursor = cursor.send(:next_cursor)
          end
        rescue Twitter::Error::Unauthorized
          []
        end
        friend_ids
      end

      def get_followers_info(client)
        followers = []
        get_follower_ids(client, client.user.id).each_slice(100) do |ids|
          followers.concat client.users(ids)
        end
        followers
      end

      def get_friends_info(client)
        friends = []
        get_friend_ids(client, client.user.id).each_slice(100) do |ids|
          friends.concat client.users(ids)
        end
        friends
      end
      begin
        @followers = []
        followers = get_followers_info(client)
        followers.each_with_index do |user, _index|
          @followers << user.id
          puts "adding follower to an array: #{user.id}"
        end
      rescue Twitter::Error::TooManyRequests
        []
        puts "rescue Twitter::Error #{Time.now}"
        sleep 905
        retry
      end
      begin
        @friends = []
        friends = get_friends_info(client)
        friends.each_with_index do |user, _index|
          @friends << user.id
          puts "adding friend to an array: #{user.id}"
        end
      rescue Twitter::Error::TooManyRequests
        []
        puts "rescue Twitter::Error #{Time.now}"
        sleep 905
        retry
      end
      if params[:select_action] == 'follow'
        @follow = @followers - @friends
        begin
  @follow.take(100).reverse_each do |line|
    client.follow(line)
    @follow.delete(line)
    puts "follow: #{line} #{Time.now}"
    sleep rand(1..5)
  end
rescue Twitter::Error::TooManyRequests, Twitter::Error::Forbidden, OpenSSL::SSL::SSLError, Twitter::Error::ServiceUnavailable, HTTP::ConnectionError
  []
  puts "rescue Twitter::Error #{Time.now}"
  sleep 905
  retry
end
      elsif params[:select_action] == 'unfollow'
        @unfollow = @friends - @followers
        begin
          @unfollow.take(1000).reverse_each do |line|
            client.unfollow(line)
            @unfollow.delete(line)
            puts "unfollow: #{line} #{Time.now}"
            sleep rand(1..5)
          end
        rescue Twitter::Error::TooManyRequests, Twitter::Error::Forbidden, OpenSSL::SSL::SSLError, Twitter::Error::ServiceUnavailable, HTTP::ConnectionError
          []
          puts "rescue Twitter::Error #{Time.now}"
          sleep 905
          retry
        end
      end
    end
    if params[:select_action] == 'retweet'
      $i = 0
      $num = 15
      $i1 = 0
      while $i + $i1 <= $num
        begin
          rClient = Twitter::REST::Client.new config
          sClient = Twitter::Streaming::Client.new(config)
          topics = params['tag'].split(/,/)
          sClient.filter(track: topics.join(',')) do |tweet|
            if tweet.is_a?(Twitter::Tweet)
              flash[:success] ||= []
              flash[:success] << tweet.text
              # puts tweet.text
              rClient.retweet tweet
              $i += 1
              sleep rand(1..15)
              break if $i1 == 15
            end
          end
        rescue StandardError
          # puts 'error occurred, waiting for 5 seconds'
          flash[:notice] ||= []
          flash[:notice] << 'error occurred, waiting for 5 seconds'
          $i1 += 1
          sleep 5
          break if $i1 == 15
        end
      end
    else
      flash.now[:error] = 'Error'
    end

    if params[:select_action] == 'post'
      client = Twitter::REST::Client.new config
      @array = params[:tag].split(/[\r\n]+/)
      @array.each do |i|
        client.update(i)
        sleep rand(1..10)
      end
      flash.now[:success] = 'Tweets published!'
    else
      flash.now[:error] = 'Error. Try again.'
 end

 

Тем не менее, в качестве "домашнего" (open source и полностью бесплатно) "средства ухода" за своим тви-акком - приложение вполне имеет право на существование: как видите, в полностью автоматическом режиме вычисляются идентификаторы аккаунтов, которые далее фолловятся и анфолловятся, также приложение умеет искать твиты по заданным хеш-тегам - одному или нескольким - и ретвитить; также реализован постинг твитов (каждый твит с новой строчки) через рандомные промежутки времени. Разумеется, приложение способно не только хранить любое число аккаунтов для входа и токены доступа для любого количества твиттер-аккаунтов, но и легко переключаться между ними; что на данный момент представляется мне уже, к сожалению, избыточностью.

 

Оставить комментарий

Добавьте ваш комментарий