() translation by (you can also view the original English article)



Bienvenido de vuelta a nuestra cobertura de la API de Twitter. Si usas Twitter, podrías haberte cruzado con un amigo compartiendo tweets desde el bot @infinite_scream (mostrado arriba). Se que es mayormente un bot porque tuitea en intervalos de diez minutos. Pero varia la cadena de texto en longitud de sus gritos virtuales para evitar ser bloqueado por las infames restricciones no documentadas de la API de Twitter. Tuitea demasiado frecuentemente o repite el mismo contenido y encontrarás a tus bots bloqueados sin esperanza.
Recientemente, un amigo en línea me pidió ayudarle a escribir código para un bot que podría repetir pero proporcionar alguna variación inteligente de contenido. En el tutorial de hoy, escribiré sobre cómo hacer esto con la API de Twitter.
En el tutorial de hoy, describiré cómo construir un bot que hace los básicos:
- intervalo aleatorio de tweet
- selección aleatoria de texto de estado
- selección aleatoria de hashtags
- inclusión aleatoria de URLs
- evitar ser bloqueado por Twitter
Sin embargo, si quieres usar un bot de API de Twitter para promover efectivamente tu producto o servicio en tu propia cuenta sin molestar a tus seguidores, necesitas escribir código que varíe de forma inteligente el tema, los contenidos y la frecuencia de tus tweets de manera organizada. Estaré escribiendo sobre cómo hacer eso en futuros episodios.
Si tienes alguna pregunta o idea, por favor publícalas en los comentarios de abajo. Si quisieras ver algunos de mis otros tutoriales Envato Tuts+, por favor visita mi página de instructor, especialmente mi serie startup. Comencemos.
Comenzando
Para el bot en el episodio uno, estoy intentando generar tweets divertidos de manera regular mientras evito molestar al gran Dios de Twitter del Acceso Restringido en el Cielo.
El contenido del tweet es bastante simple y puede ser creado de manera aleatoria combinando estados de texto previamente escritos, hashtags, y URLs.
El bot se ejecuta en Yii, una plataforma popular basada en PHP. Mantendré la guía bastante simple para desarrolladores PHP comunes. Sin embargo, te aliento a usar frameworks. Puedes aprender más en mi Serie Yii.
Construyendo el Bot
Registrando una Aplicación Twitter
Básicamente, la primera cosa que hice fue registrar una aplicación para obtener mis llaves Twitter:



Si no estás familiarizado con crear una aplicación y autorizar acceso API con Twitter, por favor revisa algunos de nuestros tutoriales anteriores:
Construyendo Con la API de Twitter: Comenzando
Construyendo Con la API de Twitter: Tormentas de Tweets
Construyendo Tu Startup Con PHP: Simplificando Onramp Con OAuth
Creación de Contenido para un Rango de Tweets
Quería crear un sistema en donde mi amigo (o cualquier autor aprobado) pudiera escribir variaciones de tweets y colocarlas en una base de datos para uso continuo. Primero, creé una migración de base de datos para construir la tabla para ellos.
Todas mis tablas para este proyecto tienen el prefijo norm_
. Aquí está la tabla Tweet o norm_tweet
:
1 |
<?php
|
2 |
use yii\db\Schema; |
3 |
use yii\db\Migration; |
4 |
class m170120_211944_create_table_norm_tweet extends Migration |
5 |
{
|
6 |
public function up() |
7 |
{
|
8 |
$tableOptions = null; |
9 |
if ($this->db->driverName === 'mysql') { |
10 |
$tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB'; |
11 |
}
|
12 |
|
13 |
$this->createTable('{{%norm_tweet}}', [ |
14 |
'id' => Schema::TYPE_PK, |
15 |
'tweet' => Schema::TYPE_TEXT.' NOT NULL', |
16 |
'media_id' => Schema::TYPE_STRING.' NOT NULL', |
17 |
], $tableOptions); |
18 |
|
19 |
}
|
20 |
|
21 |
public function down() |
22 |
{
|
23 |
|
24 |
$this->dropTable('{{%norm_tweet}}'); |
25 |
}
|
26 |
}
|
Después, usé el sistema scaffolding Gii de Yii para crear un modelo y archivos CRUD para mi. Aquí está el modelo:



Y aquí está la generación CRUD:



Así que todo este código proporciona de manera automática la vista de cuadrícula de abajo y capacidades de edición.



Por ahora, no estoy usando el Medio ID, que es para que las imágenes que son subidas se usen dentro de los tweets. Probablemente abordaré esto en el siguiente episodio.
Bastante sencillo hasta ahora, ¿verdad?
Agregando un Rango de Hashtags
Después, repito este proceso para los otros modelos. Aquí está la migración norm_hash
para hashtags:
1 |
<?php
|
2 |
use yii\db\Schema; |
3 |
use yii\db\Migration; |
4 |
class m170120_212009_create_table_norm_hash extends Migration |
5 |
{
|
6 |
public function up() |
7 |
{
|
8 |
$tableOptions = null; |
9 |
if ($this->db->driverName === 'mysql') { |
10 |
$tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB'; |
11 |
}
|
12 |
|
13 |
$this->createTable('{{%norm_hash}}', [ |
14 |
'id' => Schema::TYPE_PK, |
15 |
'tag' => Schema::TYPE_STRING.' NOT NULL', |
16 |
], $tableOptions); |
17 |
|
18 |
}
|
19 |
|
20 |
public function down() |
21 |
{
|
22 |
|
23 |
$this->dropTable('{{%norm_hash}}'); |
24 |
}
|
25 |
}
|
La idea es incluir de manera aleatoria un hashtag seleccionado (o dos) en los tweets para hacer parecer que el bot es humano, variando sus tweets.
Aquí está la UX de Hashtag:



No repetiré los pasos Yii Gii de arriba, pero los repito para norm_hash
y norm_url
también.
Agregando una Variedad de URLs
Aquí está la migración de base de datos para agregar URLs:
1 |
<?php
|
2 |
use yii\db\Schema; |
3 |
use yii\db\Migration; |
4 |
class m170120_211955_create_table_norm_url extends Migration |
5 |
{
|
6 |
public function up() |
7 |
{
|
8 |
$tableOptions = null; |
9 |
if ($this->db->driverName === 'mysql') { |
10 |
$tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB'; |
11 |
}
|
12 |
|
13 |
$this->createTable('{{%norm_url}}', [ |
14 |
'id' => Schema::TYPE_PK, |
15 |
'url' => Schema::TYPE_STRING.' NOT NULL', |
16 |
'last_used' => Schema::TYPE_INTEGER . ' NOT NULL', |
17 |
'created_at' => Schema::TYPE_INTEGER . ' NOT NULL', |
18 |
'updated_at' => Schema::TYPE_INTEGER . ' NOT NULL', |
19 |
], $tableOptions); |
20 |
|
21 |
}
|
22 |
|
23 |
public function down() |
24 |
{
|
25 |
|
26 |
$this->dropTable('{{%norm_url}}'); |
27 |
}
|
28 |
}
|
El bot maestro podría agregar URLs en diferentes ocasiones. Es probablemente mejor que este bot no use URLs antiguas o las repita. Las estampas de tiempo Unix last_used
y created_at
permiten al algoritmo de tweets descrito abajo que decida cuando usar URLs.
Aquí está la página UX URL:



Ahora, veamos el divertido algoritmo para combinar todas estas tablas en tweets interesantes que no son molestos para el Señor Maestro de Restricciones de Twitter.
Aleatorización de Contenido de Tweets de Bot
Es divertido tener un bot que tuitea una variedad de contenido, pero la variedad también es útil para prevenir que sea bloqueado por Twitter.
Puedes ver los Límites de Tasa de Twitter, pero algunas de las reglas para repetición de contenido no parecen estar documentadas:



Tomo instrucciones de mi amigo sobre cómo querían que el algoritmo construyera tweets desde la base de datos de tweets, hashtags, y URLs.
Aquí está el algoritmo de construcción que decidimos por ahora; es fácil de modificar. Lo describiré en partes.
En mi opinión el algoritmo de abajo es bajo en su uso de hashtags y URLs, y si quieres una variedad más robusta de contenido, cámbialo a tu gusto.
Primero, usamos yii\db\Expression;
para seleccionar apropiadamente un solo texto de tweet aleatorio de la tabla:
1 |
<?php
|
2 |
|
3 |
namespace frontend\models; |
4 |
|
5 |
use Yii; |
6 |
use yii\db\Expression; |
7 |
|
8 |
...
|
9 |
|
10 |
public static function build() { |
11 |
// pick a random tweet message (any one of them)
|
12 |
$txt = NormTweet::find() |
13 |
->orderBy(new Expression('rand()')) |
14 |
->one(); |
Después decidimos si usar un hashtag (actualmente 1 en 5 o el 20% del tiempo) y cuántos usar (actualmente fijo a solo uno):
1 |
// decide whether to use a hashtag
|
2 |
// pick a random # between 0 and 4
|
3 |
$useHash = rand(0,4); |
4 |
// if rand# is not 0 but instead 1,2,3 or 4, include hashtag(s)
|
5 |
// for less freq use of hash tags, we can change this > 2 or >3
|
6 |
if ($useHash>3) { |
7 |
// so we're now going to decide which and how many hash tags to
|
8 |
// Creator decided to only use one hashtag for right now
|
9 |
$numHash = 1; // rand(1,3); |
10 |
// select this rand# $numHash randomly from our list
|
11 |
$hash = NormHash::find() |
12 |
->orderBy(new Expression('rand()')) |
13 |
->one(); |
14 |
} else { |
15 |
// don't use any hashtags
|
16 |
$hash=false; |
17 |
}
|
Después, decidimos si hay una URL disponible para usar. Las URLs deben tener menos de una semana de antigüedad y solo pueden ser usadas una vez cada 72 horas (3 días). Así que cualquier nueva URL estaría solo disponible para usar una, dos o posiblemente tres veces antes de expirar.
1 |
// only use a url if it's less than a week old
|
2 |
$url_weekago = time()-7*24*3600; |
3 |
$url_3daysago = time()-3*24*3600; |
4 |
// only use a url if it's not been posted in the last 72 hrs
|
5 |
$url= NormUrl::find() |
6 |
->where('created_at>'.$url_weekago) |
7 |
->andWhere('last_used<'.$url_3daysago) // handles unused zero case |
8 |
->orderBy(['id' => SORT_DESC])->one(); |
Finalmente, construimos el tweet basados en la información seleccionada (las URLs disponibles son agregadas una de cada cuatro veces o 25% de probabilidad):
1 |
$content = $txt->tweet; |
2 |
if ($hash!==false) { |
3 |
$content.=' #'.$hash->tag; |
4 |
}
|
5 |
// only add URL 1/4 of the time
|
6 |
if (!is_null($url) && rand(1,4) ==1) { |
7 |
$content.=' '.$url->url; |
8 |
$url->last_used = time(); |
9 |
$url->update(); |
10 |
}
|
11 |
return $content; |
Eligiendo Cuando Tuitear
Yii te permite llamar controladores de consola desde cron. Así que agrego una llamada a mi /console/DaemonController.php en crontab.
$ sudo crontab -l
Aquí está cómo mis tareas están programadas:
1 |
# m h dom mon dow command
|
2 |
*/3 * * * * /var/www/bot/yii daemon/frequent |
3 |
*/15 * * * * /var/www/bot/yii daemon/quarter |
4 |
0 * * * * /var/www/bot/yii daemon/hourly |
5 |
15 1 * * * /var/www/bot/yii daemon/overnight |
6 |
15 3 * * 5 /var/www/bot/yii daemon/weekly |
Cada hora, daemon/hourly
en /console/DaemonController.php es solicitado. Nuestra aplicación bot solo decide si tuitear o no una vez cada cuatro horas.
Primero, verás que tengo una tabla NormLog
que no describí arriba, pero que sigue a toda la salida y cuando los tweets son hechos. Así que mi amigo no quería tuitear más de una vez al día.
1 |
public function actionHourly() { |
2 |
// every hour
|
3 |
$current_hour = date('G'); |
4 |
if ($current_hour%4) { |
5 |
// every four hours
|
6 |
echo "Review tweeting plan..."; |
7 |
$dayAgo = time()-24*3600; |
8 |
$nl= \frontend\models\NormLog::find() |
9 |
->orderBy(['id' => SORT_DESC]) |
10 |
->one(); |
11 |
echo 'created_at: '.$nl->id.' '.$nl->created_at.'...'; |
12 |
echo 'dayago: '.$dayAgo.'...'; |
13 |
if ($nl->created_at<$dayAgo) { |
14 |
// okay to maybe tweet
|
15 |
...
|
No queríamos que los seguidores de nuestro bot se molestaran por tuitear con alta frecuencia.
Después, elige un número, básicamente las seis veces al día (cada cuatro horas), y tuitea si el número es 6 (o una probabilidad de uno en 12).
1 |
// every four hours, if 6 is picked from 1-12, we tweet
|
2 |
// 1 in 12 chance 12x in two days
|
3 |
$r = rand(1,12); |
4 |
if ($r==6) { |
5 |
\frontend\models\NormTweet::deliver(); |
6 |
echo 'tweet, 6 was picked...'; |
7 |
} else { |
8 |
echo "do not tweet, 1 in 12 # not picked..."; |
9 |
}
|
10 |
} else { |
11 |
// never tweet twice in 24 hrs
|
12 |
echo 'do not tweet, not yet 24 hrs...'; |
13 |
}
|
14 |
echo '..made it to end...!'; |
15 |
}
|
16 |
if ($current_hour%6) { |
17 |
// every six hours
|
18 |
}
|
19 |
}
|
Entregando el Tweet a la API de Twitter
Aquí está el método NormTweet::deliver()
llamado por el Daemon para publicar el tweet:
1 |
public static function deliver() |
2 |
{
|
3 |
// post an update
|
4 |
// construct
|
5 |
$content = NormTweet::build(); |
6 |
// tweet it using params for norm acct
|
7 |
$connection = new TwitterOAuth( |
8 |
Yii::$app->params['norm']['consumer_key'], |
9 |
Yii::$app->params['norm']['consumer_secret'], |
10 |
Yii::$app->params['norm']['access_token'], |
11 |
Yii::$app->params['norm']['access_token_secret']); |
12 |
$postit = $connection->post("statuses/update", |
13 |
["status" => $content]); |
14 |
// save it in the log
|
15 |
$nl = new NormLog(); |
16 |
$nl->tweet = $content; |
17 |
$nl->save(); |
18 |
}
|
19 |
}
|
Las llaves de aplicación de la cuenta de Twitter son almacenadas en /bot/frontend/config/params-local.php, configuradas desde el archivo bot.ini que uso:
1 |
$ more params-local.php |
2 |
<?php |
3 |
return [ |
4 |
'norm' => [ |
5 |
'consumer_key' => $config['norm_consumer_key'], |
6 |
'consumer_secret' => $config['norm_consumer_secret'], |
7 |
'access_token' => $config['norm_access_token'], |
8 |
'access_token_secret' => $config['norm_access_token_secret'], |
9 |
'user_id' => $config['norm_user_id'], |
10 |
],
|
11 |
|
12 |
];
|
Los bots no son simples, ¡pero son divertidos!
Examinando los Resultados
Aquí están los resultados de nuestro bot:



¡Solo bromeo! Ese es uno de nuestros dioses editoriales, Tom McFarlin. Los scripts de IA aún no son capaces de reemplazar su "perspicacia", pero Envato Tuts+ me ha contratado para trabajar en esto.
Aquí está el bot real, pensado para recordar a mi amigo y sus seguidores que las nuevas políticas de América no son exactamente normales. Imagino si tus vistas estarían de acuerdo con eso.



Espero que hayas disfrutado este episodio.
¿Qué Sigue?
Después, voy a crear una plataforma más orientada a mercadeo para ayudarte a usar la API de Twitter para promocionar tu startup, servicios, y negocio sin ser etiquetado como bot y ser bloqueado.
Si tienes alguna pregunta o sugerencia sobre este tutorial, por favor publícalos en los comentarios. Si quisieras estar al tanto de mis futuros turoriales Envato Tuts+ y otras series, por favor visita mi página de instructor o sigue @reifman.