No hace mucho fui víctima de cyberbulling con amenazas, insultos y elevadas menciones, retweets y favoritos en Twitter cuando el Gobierno Venezolano confundió mi nombre y profesión por alguien que según ellos es el webmaster de DolarToday.com en un programa de TV donde me dedicaron 15 minutos en la emisora del estado VTV.

Gracias a las experiencias en IRC le reste importancia pero aun persistía la oleada de interacciones que molestaban mis notificaciones en Twitter. Al principio pensé en simplemente proteger mi cuenta y dejar que esto pasara pero sentí que eso era lo que los atacantes querían, La alternativa era silenciar a estas cuentas pero dejar que le lean al mismo tiempo.

La tarea suena sencilla pero cuando tienes cientos de cuentas insultando, amenazando y cientos de cientos mas retuiteando cada minuto, se hace un poco tediosa la tarea así que decidí automatizar esto con este script:

import json
import requests
from requests_oauthlib import OAuth1
import sys
import csv
from time import sleep

whitelist = ['orvtech']

shitlist = ['amaia_roja', 'anat5', 'carollafra', 'contraofensiva',
            'correoorinoco', 'forocandanga', 'guerrillaragua',
            'hectorodriguez', 'izarradeverdad', 'jorgerpsuv',
           'jrodriguezpsuv', 'lahojillaentv', 'laradiodelsur',
            'maperezpirela', 'nicolasmaduro', 'prisciliano_alf',
            'thaivama', 'yndiratorregros', 'PatriciaDorta40']

#credentials from ghost account
consumer_key=''
consumer_secret=''
access_token_key=''
access_token_secret=''

#credentials from actual account
consumer_key2=''
consumer_secret2=''
access_token_key2=''
access_token_secret2=''

def get_retweets(tweetid):
  retweetdata={}
  handles=[]
  api_url="https://api.twitter.com/1.1/statuses/retweets/"+tweetid+".json"
  payload = {'count':'100'}
  auth = OAuth1(consumer_key, consumer_secret, access_token_key, access_token_secret)
  r = requests.get(api_url, stream=False, auth=auth, params=payload)
  try:
    if r.headers['x-rate-limit-remaining'] and r.headers['x-rate-limit-remaining'] == "0":
      print("We reached rate limit for ", api_url)
      print("Try again at", r.headers["x-rate-limit-reset"])
      quit()
  except KeyboardInterrupt:
      sys.exit()
  except:
     print "OK"
  retweetsObj = json.loads(r.content)
  for y in range(len(retweetsObj)):
    handles.append(retweetsObj[y]['user']['screen_name'])
  return handles

BLOCK_URL = 'https://api.twitter.com/1.1/blocks/create.json'
MUTE_URL = 'https://api.twitter.com/1.1/mutes/users/create.json'

def getTweets(usuarios):
   api_url="https://api.twitter.com/1.1/statuses/user_timeline.json"
   payload = {'screen_name': usuarios, 'count':'1', 'trim_user':'t', 'include_rts':'false'}
   auth = OAuth1(consumer_key, consumer_secret, access_token_key, access_token_secret)
   r = requests.get(api_url, stream=False, auth=auth, params=payload)
   statusObj = json.loads(r.content)
   return statusObj[0]['id']

def act_on_handle(api_url, auth, payload):
    try:
       r = requests.post(api_url, stream=False, auth=auth, params=payload)
       msgs = json.loads(r.content)
       print r.headers['status'] , payload
       if r.headers['x-rate-limit-remaining'] and r.headers['x-rate-limit-remaining'] == "0":
          print('We reached rate limit for {url}'.format(url=api_url))
          print('Try again at {reset}'.format(reset=r.headers["x-rate-limit-reset"]))
          sys.exit()
    except KeyboardInterrupt:
       sys.exit()
    except:
       pass

def main():
    for cuenta in shitlist:
       try:
         tweet = str(getTweets(cuenta))
         print "\nAnalizyng retweeters of" , cuenta , "TweetID:", tweet
         print "https://twitter.com/" + cuenta + "/status/" + tweet
         HANDLES = get_retweets(tweet)
         for user in HANDLES:
            if user not in whitelist:
              auth2 = OAuth1(consumer_key2, consumer_secret2, access_token_key2, access_token_secret2)
              payload = "screen_name=" + user
              #act_on_handle(BLOCK_URL, auth2, payload)
              act_on_handle(MUTE_URL, auth2, payload)
              sleep(1)
            else:
              print "YOU FOLLOW " , user , "WHO RETWEETED" , cuenta
              sleep(40)
         sleep(60)
       except KeyboardInterrupt:
         sys.exit()
       except:
         pass

if __name__ == '__main__':
    main()

Este script usa dos cuentas, La cuenta que esta siendo atacada la cual va a ser protegida y una segunda cuenta que es la que usamos para ver las interacciones de las cuentas que nos están atacando. Al momento de escribir este articulo, no es necesario usar la segunda cuenta pero en un futuro twitter podría prohibir que uno viera las interacciones de tweets de cuentas que no tiene en mudo o bloqueadas por el API así que decidí prepararme para eso. Como siempre los OAuth tokens y llaves las pueden obtener registrando sus apps en apps.twitter.com.

El programa lo que hace es buscar todos los tweets de una lista de cuentas que sabemos nos atacan y tomar acción contra quienes retuitean estos tweets, las acciones pueden ser bloquear y/o enmudecer.

Tras dejarlo correr un par de ciclos el resultado fue total normalidad en mi cuenta de Twitter. Ayudo un poco que los clusters de cuentas automatizadas fueron reportados y suspendidas de Twitter un par de días después.

Para la versión mas reciente de este programa, colaborar y reportar bugs pueden visitar el mi repositorio en GitHub.

Leer más

QRDA nace bajo la idea de proveer soluciones tecnológicas a distintas organizaciones sin fines de lucro, a través del apoyo de twitter.com/delbosquetech y con el respaldo de la Comunidad del Software Libre en Venezuela.

Esta idea la propone Luis Ortiz, gran amigo y compañero de trabajo. Se desarrolla en una reunión social (agua, cerveza, jugos, refresco, pizza) por lo que es considerado un evento entre panas que buscamos un mismo fin: dar apoyo con nuestro conocimiento tecnológico para desarrollar proyectos determinados.

Luis en la Charla de Inicio de QRDA

Luego de establecer las bases que sustentarían este proyecto, se fueron creando diferentes tickets en github que permitieran establecer un orden a las actividades que se van desarrollando, para luego crear las diferentes listas de correo y comenzar a trabajar.

Al final de la actividad pudimos compartir con personas que se acercaron de diferentes parte de Venezuela y que integran la Comunidad del Software Libre, gente con la cual me identifico y que se ha ganado mi respeto.

La lista de agradecimiento es extensa, son muchos los involucrados en este maravilloso proyecto que, aún y cuando está comenzando, podría asegurar que ayudará a muchas personas y tendrá un crecimiento positivo. Muchas gracias a todos.

Les dejo las redes sociales de QRDA para que también puedan seguir este proyecto y, si lo desean, puedan unirse a nosotros:

https://twitter.com/QRDAve/
https://instagram.com/qrda.ve
https://www.facebook.com/QRDA.com.ve
http://qrda.com.ve

Nuevamente Gracias por venir.

Leer más