Ejemplo de PHP más simple para recuperar user_timeline con Twitter API versión 1.1

292

Debido al retiro de Twitter API 1.0 a partir del 11 de junio de 2013 , la secuencia de comandos a continuación ya no funciona.

// Create curl resource 
$ch = curl_init(); 
// Set url 
curl_setopt($ch, CURLOPT_URL, "http://twitter.com/statuses/user_timeline/myscreenname.json?count=10"); 
// Return the transfer as a string 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
// $output contains the output string 
$output = curl_exec($ch); 
// Close curl resource to free up system resources 
curl_close($ch);

if ($output) 
{
    $tweets = json_decode($output,true);

    foreach ($tweets as $tweet)
    {
        print_r($tweet);
    }
}

¿Cómo puedo obtener el user_timeline (estados recientes) con el menor código posible?

Encontré esto: https://dev.twitter.com/docs/api/1.1/get/statuses/user_timeline pero recibo el siguiente error:

"{"errors":[{"message":"Could not authenticate you","code":32}]}"

Hay muchas clases por ahí, pero después de probar varias, ninguna parece funcionar debido a estas actualizaciones en Twitter, y algunas de ellas son clases bastante avanzadas con mucha funcionalidad que realmente no necesito.

¿Cuál es la forma más simple / más corta de obtener los estados de usuario recientes con PHP?

ciudadano del mundo
fuente
98
MATARÍA por la respuesta a esto. Su documentación es horriblemente mala.
RCNeil
Soy nuevo en la API de Twitter y estoy luchando un poco con él. Me encontré usando código obsoleto.
Anthony
Echa un vistazo a aamirafridi.com/twitter/…
Aamir Afridi
@ Mark Gracias Mark !! ¡¡Eso fue fácil!! Eso no funcionó para mí inicialmente. Estoy ejecutando WAMP. Tuve que hacer un cambio en mi php.ini en mi directorio de Apache de acuerdo con este hilo: stackoverflow.com/questions/5444249/…
Adlin Ling
1
Acabo de escribir una solución sin CURL ni ninguna otra biblioteca adicional: stackoverflow.com/questions/17049821/…
Rauli Rajande

Respuestas:

820

Nota importante: A mediados de 2018, el proceso para obtener tokens API de Twitter se volvió mucho más burocrático. Me ha llevado más de una semana de trabajo obtener un conjunto de tokens API, y esto es para un proyecto de código abierto para ustedes y niñas con más de 1.2 millones de instalaciones en Packagist y 1.6k estrellas en Github, lo que en teoría debería ser una prioridad más alta .

Si tiene la tarea de trabajar con la API de Twitter para su trabajo, debe tener en cuenta este tiempo de espera potencialmente extremadamente largo. También considere otras vías de redes sociales como Facebook o Instagram y brinde estas opciones, ya que el proceso para recuperar sus tokens es instantáneo.


¿Entonces quieres usar la API de Twitter v1.1?

Nota: los archivos para estos están en GitHub .

La versión 1.0 pronto quedará obsoleta y no se permitirán solicitudes no autorizadas. Entonces, aquí hay una publicación para ayudarlo a hacer eso, junto con una clase de PHP para facilitarle la vida.

1. Cree una cuenta de desarrollador: configure una cuenta de desarrollador en Twitter

Debe visitar el sitio oficial de desarrolladores de Twitter y registrarse para obtener una cuenta de desarrollador. Este es un paso gratuito y necesario para realizar solicitudes para la API v1.1.

2. Cree una aplicación: cree una aplicación en el sitio de desarrolladores de Twitter

¿Qué? ¿Pensaste que podrías hacer solicitudes no autenticadas? No con la API v1.1 de Twitter. Debe visitar http://dev.twitter.com/apps y hacer clic en el botón "Crear aplicación".

Ingrese la descripción de la imagen aquí

En esta página, complete los detalles que desee. Para mí, no importó, porque solo quería hacer un montón de solicitudes de bloqueo para deshacerme de los seguidores de spam. El punto es que obtendrá un conjunto de claves únicas para usar en su aplicación.

Entonces, el punto de crear una aplicación es darse un juego de llaves (y Twitter). Estos son:

  • La clave del consumidor
  • El secreto del consumidor
  • El token de acceso
  • El secreto del token de acceso

Hay un poco de información aquí en lo que estas fichas para.

3. Cree tokens de acceso : los necesitará para realizar solicitudes exitosas

OAuth solicita algunos tokens. Por lo tanto, debe tenerlos generados por usted.

Ingrese la descripción de la imagen aquí

Haga clic en "crear mi token de acceso" en la parte inferior. Luego, una vez que se desplace hacia la parte inferior nuevamente, tendrá algunas claves recién generadas. Debe tomar las cuatro claves previamente etiquetadas de esta página para sus llamadas a la API, así que anótelas en alguna parte.

4. Cambiar el nivel de acceso : no quieres solo lectura, ¿verdad?

Si desea hacer un uso decente de esta API, deberá cambiar su configuración a Leer y escribir si está haciendo algo más que la recuperación de datos estándar utilizando solicitudes GET .

Ingrese la descripción de la imagen aquí

Elija la pestaña "Configuración" cerca de la parte superior de la página.

Ingrese la descripción de la imagen aquí

Dé a su aplicación acceso de lectura / escritura y presione "Actualizar" en la parte inferior.

Puede leer más sobre el modelo de permiso de aplicaciones que Twitter usa aquí.


5. Escriba el código para acceder a la API : he hecho la mayor parte por usted

Combiné el código anterior, con algunas modificaciones y cambios, en una clase PHP, por lo que es realmente simple hacer las solicitudes que necesita.

Esto usa OAuth y la API de Twitter v1.1 , y la clase que he creado que puedes encontrar a continuación.

require_once('TwitterAPIExchange.php');

/** Set access tokens here - see: https://dev.twitter.com/apps/ **/
$settings = array(
    'oauth_access_token' => "YOUR_OAUTH_ACCESS_TOKEN",
    'oauth_access_token_secret' => "YOUR_OAUTH_ACCESS_TOKEN_SECRET",
    'consumer_key' => "YOUR_CONSUMER_KEY",
    'consumer_secret' => "YOUR_CONSUMER_SECRET"
);

Asegúrese de poner las claves que obtuvo de su aplicación en sus respectivos espacios.

A continuación, debe elegir una URL a la que desea realizar una solicitud. Twitter tiene su documentación API para ayudarlo a elegir qué URL y también el tipo de solicitud (POST o GET).

/** URL for REST request, see: https://dev.twitter.com/docs/api/1.1/ **/
$url = 'https://api.twitter.com/1.1/blocks/create.json';
$requestMethod = 'POST';

En la documentación, cada URL indica lo que puede pasarle. Si estamos usando la URL de "bloques" como la anterior, puedo pasar los siguientes parámetros POST:

/** POST fields required by the URL above. See relevant docs as above **/
$postfields = array(
    'screen_name' => 'usernameToBlock', 
    'skip_status' => '1'
);

Ahora que ha configurado lo que desea hacer con la API, es hora de hacer la solicitud real.

/** Perform the request and echo the response **/
$twitter = new TwitterAPIExchange($settings);
echo $twitter->buildOauth($url, $requestMethod)
             ->setPostfields($postfields)
             ->performRequest();

Y para una solicitud POST , eso es todo.

Para una solicitud GET , es un poco diferente. Aquí hay un ejemplo:

/** Note: Set the GET field BEFORE calling buildOauth(); **/
$url = 'https://api.twitter.com/1.1/followers/ids.json';
$getfield = '?username=J7mbo';
$requestMethod = 'GET';
$twitter = new TwitterAPIExchange($settings);
echo $twitter->setGetfield($getfield)
             ->buildOauth($url, $requestMethod)
             ->performRequest();     

Ejemplo de código final : para una simple solicitud GET de una lista de mis seguidores.

$url = 'https://api.twitter.com/1.1/followers/list.json';
$getfield = '?username=J7mbo&skip_status=1';
$requestMethod = 'GET';
$twitter = new TwitterAPIExchange($settings);
echo $twitter->setGetfield($getfield)
             ->buildOauth($url, $requestMethod)
             ->performRequest();  

¡He puesto estos archivos en GitHub con crédito a @ lackovic10 y @rivers! Espero que alguien lo encuentre útil; Sé que lo hice (lo usé para el bloqueo masivo en un bucle).

Además, para aquellos en Windows que tienen problemas con los certificados SSL, miren esta publicación . Esta biblioteca utiliza cURL debajo del capó, por lo que debe asegurarse de tener sus certificados cURL configurados probablemente. Google también es tu amigo.

Jimbo
fuente
44
@kaffolder El enlace en esa página: profilepicture.co.uk/caching-api-responses-php sugiere una forma simple de hacerlo. Usted escribe sus datos de Twitter en un archivo o base de datos (MySQL o MongoDB) en la primera solicitud, luego cada solicitud subsiguiente verifica el tiempo actual contra el límite de tiempo que desea para el archivo (puede nombrar el archivo como el límite de tiempo), y si el archivo existe y el nombre del archivo está dentro del límite de tiempo que desea, extraiga los datos en lugar de realizar la solicitud de la API. Si el archivo existe pero se pasa el límite de tiempo, elimine el archivo y luego realice la solicitud de API.
Jimbo
77
No puedo entender cómo manejar los datos json una vez devueltos. No quiero simplemente repetirlo en la pantalla como en echo $ twitter -> setGetfield ($ getfield) -> buildOauth ($ url, $ requestMethod) -> performRequest (); ¡DISCULPAS, no puedo entender cómo hacer nuevas líneas! Quiero hacer algo como $ jsonData = json_decode ($ twitter); pero no funciona - Siento que me estoy perdiendo algo fundamental pero el centavo no se está cayendo ...
Ashley
67
Gracias, la documentación de Twitter es un desastre desorganizado, esto ayudó mucho.
joren 01 de
77
Hay bastantes requisitos previos para que esta clase funcione en Windows. Debe tener una versión funcional de cURL cargada en su php.iniarchivo y también debe cargar los certificados de CA en su php.iniarchivo usando curl.cainfo = path\to\cacert.pem. Puede obtener los certificados de CA aquí .
Jake Z
44
@Jimbo Estaba notando que algunas de las extensiones de cURL predeterminadas tienen errores en Windows y requieren reemplazo (de ahí el enlace a las versiones "fijas") y que sin cargar los certificados de CA, su clase devuelve un falso, ya que curl_error () informa que `el problema del certificado SSL, verifique que el certificado CA esté bien`. Esto se puede evitar desactivando CURLOPT_SSL_VERIFYPEER, pero pensé que incluiría las instrucciones básicas para usar realmente los certificados de CA. Solo incluí esto para potencialmente salvar a algunas personas de unos minutos de búsqueda.
Jake Z
137

Vaya a dev.twitter.com y cree una aplicación . Esto le proporcionará las credenciales que necesita. Aquí hay una implementación que escribí recientemente con PHP y cURL .

<?php
    function buildBaseString($baseURI, $method, $params) {
        $r = array();
        ksort($params);
        foreach($params as $key=>$value){
            $r[] = "$key=" . rawurlencode($value);
        }
        return $method."&" . rawurlencode($baseURI) . '&' . rawurlencode(implode('&', $r));
    }

    function buildAuthorizationHeader($oauth) {
        $r = 'Authorization: OAuth ';
        $values = array();
        foreach($oauth as $key=>$value)
            $values[] = "$key=\"" . rawurlencode($value) . "\"";
        $r .= implode(', ', $values);
        return $r;
    }

    $url = "https://api.twitter.com/1.1/statuses/user_timeline.json";

    $oauth_access_token = "YOURVALUE";
    $oauth_access_token_secret = "YOURVALUE";
    $consumer_key = "YOURVALUE";
    $consumer_secret = "YOURVALUE";

    $oauth = array( 'oauth_consumer_key' => $consumer_key,
                    'oauth_nonce' => time(),
                    'oauth_signature_method' => 'HMAC-SHA1',
                    'oauth_token' => $oauth_access_token,
                    'oauth_timestamp' => time(),
                    'oauth_version' => '1.0');

    $base_info = buildBaseString($url, 'GET', $oauth);
    $composite_key = rawurlencode($consumer_secret) . '&' . rawurlencode($oauth_access_token_secret);
    $oauth_signature = base64_encode(hash_hmac('sha1', $base_info, $composite_key, true));
    $oauth['oauth_signature'] = $oauth_signature;

    // Make requests
    $header = array(buildAuthorizationHeader($oauth), 'Expect:');
    $options = array( CURLOPT_HTTPHEADER => $header,
                      //CURLOPT_POSTFIELDS => $postfields,
                      CURLOPT_HEADER => false,
                      CURLOPT_URL => $url,
                      CURLOPT_RETURNTRANSFER => true,
                      CURLOPT_SSL_VERIFYPEER => false);

    $feed = curl_init();
    curl_setopt_array($feed, $options);
    $json = curl_exec($feed);
    curl_close($feed);

    $twitter_data = json_decode($json);

//print it out
print_r ($twitter_data);

?>

Esto se puede ejecutar desde la línea de comando:

$ php <name of PHP script>.php
Ríos
fuente
2
Gracias por el fragmento de código, trabaje a la perfección. El único problema es que parece que no puedo entender cómo configurar el retorno del conteo posterior. Solo devuelve 20 y quiero la cantidad total, que es 200 según el límite de Twitter.
Flatlyn
23
¿Cómo establecerías el screen_namey countcon este enfoque? Intenté agregarlo a la $urlvariable pero recibí el error "No se pudo autenticar".
Javier Villanueva
1
¡Este código funciona muy bien! Estoy tratando de modificarlo para usar la api search / tweets.json, pero siempre recibo la respuesta 'no se pudo autenticar', ¿alguna idea?
Chris
1
Esta publicación ha sido muy útil. Sin embargo, mi código no parece volver curl_init(). He visto algunos ejemplos y se ven muy simples y directos y exactamente como este código aquí ... ¿Necesito instalar algo especial?
jessicaraygun
1
Me funcionó el 26 de octubre de 2016. El resultado fue un poco más complejo de lo que esperaba.
JohnC
61

El código pegado por Rivers es genial. ¡Muchas gracias! Soy nuevo aquí y no puedo comentar, solo me gustaría responder a la pregunta de javiervd (¿Cómo establecerías el nombre de pantalla y contarías con este enfoque?), Ya que he perdido mucho tiempo para resolverlo fuera.

Debe agregar los parámetros tanto a la URL como al proceso de creación de la firma. Crear una firma es el artículo que me ayudó. Aquí está mi código:

$oauth = array(
           'screen_name' => 'DwightHoward',
           'count' => 2,
           'oauth_consumer_key' => $consumer_key,
           'oauth_nonce' => time(),
           'oauth_signature_method' => 'HMAC-SHA1',
           'oauth_token' => $oauth_access_token,
           'oauth_timestamp' => time(),
           'oauth_version' => '1.0'
         );

$options = array(
             CURLOPT_HTTPHEADER => $header,
             //CURLOPT_POSTFIELDS => $postfields,
             CURLOPT_HEADER => false,
             CURLOPT_URL => $url . '?screen_name=DwightHoward&count=2',
             CURLOPT_RETURNTRANSFER => true, CURLOPT_SSL_VERIFYPEER => false
           );
faltaovic10
fuente
2
No puedo votar esto lo suficiente. En la documentación de la API de Twitter, esto te mira a la cara, pero nunca es súper 'obvio'. ¿Este enfoque interfiere con la buildAuthorizationHeaderfunción? Lo implementé por separado.
Moe
No he trabajado con esto durante mucho tiempo, así que no recuerdo, si aún no ha resuelto su problema, puedo investigarlo en los próximos días.
lackovic10
He estado tratando de adaptar su solución para realizar la POST en status / update.json sin suerte, ¿tiene alguna idea de cómo se puede lograr esto?
perrohunter
1
@perrohunter No tengo idea de que tendría que investigar más sobre esto. Si no encuentras una manera en un par de días, envíame un mensaje e intentaré ayudarte.
lackovic10
18

Como se indicó en otras respuestas, cree una aplicación de Twitter para obtener el token, la clave y el secreto. Usando el siguiente código, puede modificar los parámetros de solicitud desde un punto y evitar errores tipográficos y errores similares (cambiar la $requestmatriz en la returnTweet()función).

function buildBaseString($baseURI, $method, $params) {
    $r = array();
    ksort($params);
    foreach($params as $key=>$value){
        $r[] = "$key=" . rawurlencode($value);
    }
    return $method."&" . rawurlencode($baseURI) . '&' . rawurlencode(implode('&', $r));
}

function buildAuthorizationHeader($oauth) {
    $r = 'Authorization: OAuth ';
    $values = array();
    foreach($oauth as $key=>$value)
        $values[] = "$key=\"" . rawurlencode($value) . "\"";
    $r .= implode(', ', $values);
    return $r;
}

function returnTweet(){
    $oauth_access_token         = "x";
    $oauth_access_token_secret  = "x";
    $consumer_key               = "x";
    $consumer_secret            = "x";

    $twitter_timeline           = "user_timeline";  //  mentions_timeline / user_timeline / home_timeline / retweets_of_me

    //  create request
        $request = array(
            'screen_name'       => 'budidino',
            'count'             => '3'
        );

    $oauth = array(
        'oauth_consumer_key'        => $consumer_key,
        'oauth_nonce'               => time(),
        'oauth_signature_method'    => 'HMAC-SHA1',
        'oauth_token'               => $oauth_access_token,
        'oauth_timestamp'           => time(),
        'oauth_version'             => '1.0'
    );

    //  merge request and oauth to one array
        $oauth = array_merge($oauth, $request);

    //  do some magic
        $base_info              = buildBaseString("https://api.twitter.com/1.1/statuses/$twitter_timeline.json", 'GET', $oauth);
        $composite_key          = rawurlencode($consumer_secret) . '&' . rawurlencode($oauth_access_token_secret);
        $oauth_signature            = base64_encode(hash_hmac('sha1', $base_info, $composite_key, true));
        $oauth['oauth_signature']   = $oauth_signature;

    //  make request
        $header = array(buildAuthorizationHeader($oauth), 'Expect:');
        $options = array( CURLOPT_HTTPHEADER => $header,
                          CURLOPT_HEADER => false,
                          CURLOPT_URL => "https://api.twitter.com/1.1/statuses/$twitter_timeline.json?". http_build_query($request),
                          CURLOPT_RETURNTRANSFER => true,
                          CURLOPT_SSL_VERIFYPEER => false);

        $feed = curl_init();
        curl_setopt_array($feed, $options);
        $json = curl_exec($feed);
        curl_close($feed);

    return json_decode($json, true);
}

y luego solo llama returnTweet()

budidino
fuente
1
¡Impresionante trabajo @budidino! Creó la aplicación en dev.twitter.com/apps y llenó sus x con oauth_access_token, oauth_access_token_secret, consumer_key, consumer_secret. * nota * que necesita presionar "crear mi token de acceso" y se tarda unos segundos en generarse, así que espere.
Theo
@budidino dnt necesitamos incluir cualquier biblioteca ??
anam
Completé las claves, agregué esto a mi functions.phparchivo en WordPress, puse <?php echo returnTweet(); ?>un archivo HTML y genera la palabra "Array" y nada más.
J82
@Desi, el resultado es una variedad de tweets, debes manejar cómo mostrar cada uno de ellos. pruebe print_r (returnTweet ()) solo para ver qué hay dentro. Vea este ejemplo de visualización de todos los tweets: gist.github.com/budidino/9681764#file-stackoverflow-returntweet
budidino
1
Si desea obtener solo el último tweet, debe modificar la matriz $ request y establecer el recuento en 1. Supongamos que usa $ tweet = returnTweet (); entonces, si desea mostrar el último tweet (en este caso, el único), puede escribir algo como esto: echo "último tweet:". $ tweet [0] ["texto"]; Asegúrese de revisar la estructura de los retornos de Twitter si desea extraer más que solo el texto del tweet (ejemplo $ userProfileImageURL = $ tweet [0] ["user"] ["profile_image_url"]). dev.twitter.com/docs/api/1.1/get/statuses/user_timeline
budidino
16

Gracias kris

Funcionó para mí sin usar parámetros para la consulta, cada vez que usaba más de un parámetro me mostraba el error: 32 No se pudo autenticar.

El problema para mí, estaba en la codificación de ampersand. Entonces, en su código, donde es la siguiente línea

$url .= "?".http_build_query($query);

Agregué la siguiente línea a continuación:

$url=str_replace("&amp;","&",$url);

Y funcionó usando dos o más parámetros como screen_name y count.

Todo el código se ve así:

$token = 'YOUR TOKEN';
$token_secret = 'TOKEN SECRET';
$consumer_key = 'YOUR KEY';
$consumer_secret = 'KEY SECRET';

$host = 'api.twitter.com';
$method = 'GET';
$path = '/1.1/statuses/user_timeline.json'; // api call path

$query = array( // query parameters
    'screen_name' => 'twitterapi',
    'count' => '2'
);

$oauth = array(
    'oauth_consumer_key' => $consumer_key,
    'oauth_token' => $token,
    'oauth_nonce' => (string)mt_rand(), // a stronger nonce is recommended
    'oauth_timestamp' => time(),
    'oauth_signature_method' => 'HMAC-SHA1',
    'oauth_version' => '1.0'
);

$oauth = array_map("rawurlencode", $oauth); // must be encoded before sorting
$query = array_map("rawurlencode", $query);

$arr = array_merge($oauth, $query); // combine the values THEN sort

asort($arr); // secondary sort (value)
ksort($arr); // primary sort (key)

// http_build_query automatically encodes, but our parameters
// are already encoded, and must be by this point, so we undo
// the encoding step
$querystring = urldecode(http_build_query($arr, '', '&'));

$url = "https://$host$path";

// mash everything together for the text to hash
$base_string = $method."&".rawurlencode($url)."&".rawurlencode($querystring);

// same with the key
$key = rawurlencode($consumer_secret)."&".rawurlencode($token_secret);

// generate the hash
$signature = rawurlencode(base64_encode(hash_hmac('sha1', $base_string, $key, true)));

// this time we're using a normal GET query, and we're only encoding the query params
// (without the oauth params)
$url .= "?".http_build_query($query);
$url=str_replace("&amp;","&",$url); //Patch by @Frewuill

$oauth['oauth_signature'] = $signature; // don't want to abandon all that work!
ksort($oauth); // probably not necessary, but twitter's demo does it

// also not necessary, but twitter's demo does this too
function add_quotes($str) { return '"'.$str.'"'; }
$oauth = array_map("add_quotes", $oauth);

// this is the full value of the Authorization line
$auth = "OAuth " . urldecode(http_build_query($oauth, '', ', '));

// if you're doing post, you need to skip the GET building above
// and instead supply query parameters to CURLOPT_POSTFIELDS
$options = array( CURLOPT_HTTPHEADER => array("Authorization: $auth"),
                  //CURLOPT_POSTFIELDS => $postfields,
                  CURLOPT_HEADER => false,
                  CURLOPT_URL => $url,
                  CURLOPT_RETURNTRANSFER => true,
                  CURLOPT_SSL_VERIFYPEER => false);

// do our business
$feed = curl_init();
curl_setopt_array($feed, $options);
$json = curl_exec($feed);
curl_close($feed);

$twitter_data = json_decode($json);

Espero que ayude a alguien con el mismo problema que tuve.

Frewuill
fuente
muchas gracias, su mejora de código funciona bien! Una pregunta re: "// se recomienda un nonce más fuerte". ¿Qué puede ser eso? hora()?
Sebastian
Gracias por señalar eso. Sebastian: un nonce es un token de un solo uso que debería ser criptográficamente seguro. mt_rand () es demasiado corto (32 bits) y no es un PRNG criptográfico. En teoría, esto hace que el token oauth sea débil, pero por simplicidad en mi código de ejemplo original, quería usar algo que fuera práctico en PHP y fácilmente comprensible.
Kris Reeves
error de recepción 32. No se pudo autenticar ... ¿alguna ayuda por favor? He usado su código anterior
saadk
@frewuill, eres un gran hermano, me está funcionando de maravilla, gracias.
vijay
9

Esta pregunta me ayudó mucho, pero no me ayudó a comprender lo que debe suceder. Esta publicación de blog hizo un trabajo increíble al guiarme.

Aquí están los bits importantes en un solo lugar:

  • Como se señaló anteriormente, DEBE firmar sus solicitudes de API 1.1. Si está haciendo algo como obtener estados públicos, querrá una clave de aplicación en lugar de una clave de usuario. El enlace completo a la página que desea es: https://dev.twitter.com/apps
  • Debe hacer hash TODOS los parámetros, tanto los propios como los parámetros get (o parámetros POST) juntos.
  • Debe ORDENAR los parámetros antes de reducirlos a la forma codificada de URL que se convierte en hash.
  • Debe codificar algunas cosas varias veces: por ejemplo, crea una cadena de consulta a partir de los valores codificados en la url de los parámetros, y luego codifica la URL y concatena con el tipo de método y la url.

Simpatizo con todos los dolores de cabeza, así que aquí hay un código para resumirlo todo:

$token = 'YOUR TOKEN';
$token_secret = 'TOKEN SECRET';
$consumer_key = 'YOUR KEY';
$consumer_secret = 'KEY SECRET';

$host = 'api.twitter.com';
$method = 'GET';
$path = '/1.1/statuses/user_timeline.json'; // api call path

$query = array( // query parameters
    'screen_name' => 'twitterapi',
    'count' => '2'
);

$oauth = array(
    'oauth_consumer_key' => $consumer_key,
    'oauth_token' => $token,
    'oauth_nonce' => (string)mt_rand(), // a stronger nonce is recommended
    'oauth_timestamp' => time(),
    'oauth_signature_method' => 'HMAC-SHA1',
    'oauth_version' => '1.0'
);

$oauth = array_map("rawurlencode", $oauth); // must be encoded before sorting
$query = array_map("rawurlencode", $query);

$arr = array_merge($oauth, $query); // combine the values THEN sort

asort($arr); // secondary sort (value)
ksort($arr); // primary sort (key)

// http_build_query automatically encodes, but our parameters
// are already encoded, and must be by this point, so we undo
// the encoding step
$querystring = urldecode(http_build_query($arr, '', '&'));

$url = "https://$host$path";

// mash everything together for the text to hash
$base_string = $method."&".rawurlencode($url)."&".rawurlencode($querystring);

// same with the key
$key = rawurlencode($consumer_secret)."&".rawurlencode($token_secret);

// generate the hash
$signature = rawurlencode(base64_encode(hash_hmac('sha1', $base_string, $key, true)));

// this time we're using a normal GET query, and we're only encoding the query params
// (without the oauth params)
$url .= "?".http_build_query($query);

$oauth['oauth_signature'] = $signature; // don't want to abandon all that work!
ksort($oauth); // probably not necessary, but twitter's demo does it

// also not necessary, but twitter's demo does this too
function add_quotes($str) { return '"'.$str.'"'; }
$oauth = array_map("add_quotes", $oauth);

// this is the full value of the Authorization line
$auth = "OAuth " . urldecode(http_build_query($oauth, '', ', '));

// if you're doing post, you need to skip the GET building above
// and instead supply query parameters to CURLOPT_POSTFIELDS
$options = array( CURLOPT_HTTPHEADER => array("Authorization: $auth"),
                  //CURLOPT_POSTFIELDS => $postfields,
                  CURLOPT_HEADER => false,
                  CURLOPT_URL => $url,
                  CURLOPT_RETURNTRANSFER => true,
                  CURLOPT_SSL_VERIFYPEER => false);

// do our business
$feed = curl_init();
curl_setopt_array($feed, $options);
$json = curl_exec($feed);
curl_close($feed);

$twitter_data = json_decode($json);
Kris Reeves
fuente
6

Si tiene instalada la biblioteca OAuth PHP, no tiene que preocuparse por realizar la solicitud usted mismo.

$oauth = new OAuth($consumer_key, $consumer_secret, OAUTH_SIG_METHOD_HMACSHA1, OAUTH_AUTH_TYPE_URI);
$oauth->setToken($access_token, $access_secret);

$oauth->fetch("https://api.twitter.com/1.1/statuses/user_timeline.json");
$twitter_data = json_decode($oauth->getLastResponse());

print_r($twitter_data);

Para obtener más información, consulte los documentos o su ejemplo . Puedes usar pecl install oauthpara obtener la biblioteca.

jeffaudio
fuente
5

En primer lugar, quería agradecer a Jimbo y ( su simple biblioteca post / twitter-api-php).

Si va a utilizar la API GET search / tweets con la biblioteca PHP "twitter-api-php" (TwitterAPIExchange.php):

Primero, solo tiene que comentar el área de código "Realizar una solicitud POST y repetir la respuesta".

Simplemente use el código "Realizar una solicitud GET y repetir la respuesta" y repetir la respuesta y cambiar estas dos líneas:

$url = 'https://api.twitter.com/1.1/followers/ids.json';
$getfield = '?screen_name=J7mbo';

a

$url = 'https://api.twitter.com/1.1/search/tweets.json';
$getfield = '?q=J7mbo';

(Cambiar screen_namea q, eso es todo :)

Chanuka Asanka
fuente
Todavía no tengo suerte: /
Ricardo
2

Necesitará una para crear una "aplicación" en Twitter (y necesita una cuenta de Twitter para hacerlo).

Luego, debe usar OAuth para realizar una solicitud autorizada a Twitter .

Puede usar el recurso GET status / user_timeline para obtener una lista de tweets recientes.

Matthew Rapati
fuente
44
Por favor, para nosotros, estúpidos amigos, expliquen. Estás dando tanta información, si no menos, que la documentación. ¿Utiliza la HttpRequest()función de PHP para el paso 2? Existe la biblioteca TwitterOAuth PHP de Abraham, github.com/abraham/twitteroauth , que también se supone que debe hacer esto, pero en realidad no se proporciona un ejemplo de cómo implementarla.
RCNeil
2
¡github.com/abraham/twitteroauth/blob/master/test.php parece tener muchos ejemplos!
Matthew Rapati
2
Falta la página @MatthewRapati.
RN Kushwaha
0

Aquí hay uno breve para obtener un número específico de tweets de su línea de tiempo. Básicamente hace lo mismo que los otros ejemplos, solo que con menos código.

Simplemente complete las claves y ajústelo $counta su gusto:

$url = 'https://api.twitter.com/1.1/statuses/user_timeline.json';
$count = '10';

$oauth = array('count' => $count,
               'oauth_consumer_key' => '[CONSUMER KEY]',
               'oauth_nonce' => md5(mt_rand()),
               'oauth_signature_method' => 'HMAC-SHA1',
               'oauth_timestamp' => time(),
               'oauth_token' => '[ACCESS TOKEN]',
               'oauth_version' => '1.0');

$oauth['oauth_signature'] = base64_encode(hash_hmac('sha1', 'GET&' . rawurlencode($url) . '&' . rawurlencode(implode('&', array_map(function ($v, $k) { return $k . '=' . $v; }, $oauth, array_keys($oauth)))), '[CONSUMER SECRET]&[ACCESS TOKEN SECRET]', true));

$twitterData = json_decode(file_get_contents($url . '?count=' . $count, false, stream_context_create(array('http' => array('method' => 'GET',
                                                                                                                           'header' => 'Authorization: OAuth ' 
                                                                                                                                       . implode(', ', array_map(function ($v, $k) { return $k . '="' . rawurlencode($v) . '"'; }, $oauth, array_keys($oauth))))))));

Éste usa funciones anónimas y en file_get_contentslugar de la biblioteca cURL. Tenga en cuenta el uso de un nonce hash MD5. Todos parecen estar de acuerdo con el time()nonce, sin embargo, la mayoría de los ejemplos en la web sobre OAuth usan algún tipo de cadena encriptada (como esta: http://www.sitepoint.com/understanding-oauth-1/ ). Esto también tiene más sentido para mí.

Nota adicional: necesita PHP 5.3+ para las funciones anónimas (en caso de que su servidor / computadora se encuentre en una cueva de la guerra fría y no pueda actualizarla).

kasimir
fuente
-1

Desde su generador de firmas , puede generar curlcomandos de la forma:

curl --get 'https://api.twitter.com/1.1/statuses/user_timeline.json' --data 'count=2&screen_name=twitterapi' --header 'Authorization: OAuth oauth_consumer_key="YOUR_KEY", oauth_nonce="YOUR_NONCE", oauth_signature="YOUR-SIG", oauth_signature_method="HMAC-SHA1", oauth_timestamp="TIMESTAMP", oauth_token="YOUR-TOKEN", oauth_version="1.0"' --verbose
Geremia
fuente
-2
$connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, OAUTH_TOKEN, OAUTH_TOKEN_SECRET);

$timelines = $connection->get('statuses/user_timeline', array('screen_name' => 'NSE_NIFTY', 'count' => 100, 'include_rts' => 1));
Mohd Abdul Baquee
fuente
3
Incluya una explicación sobre lo que hace este código, para que el OP pueda aprender de él.
Cerbrus
-2

Gracias a este hilo, y especialmente a budidino porque su código es lo que me llevó a casa. Solo quería contribuir a cómo recuperar los datos JSON de una solicitud. Realice cambios en la matriz de solicitud "// crear solicitud" del código para realizar diferentes solicitudes. En última instancia, esto generará el JSON en la pantalla del navegador

<?php
    function buildBaseString($baseURI, $method, $params) {
    $r = array();
    ksort($params);
    foreach($params as $key=>$value){
        $r[] = "$key=" . rawurlencode($value);
    }
    return $method."&" . rawurlencode($baseURI) . '&' . rawurlencode(implode('&', $r));
}

function buildAuthorizationHeader($oauth) {
    $r = 'Authorization: OAuth ';
    $values = array();
    foreach($oauth as $key=>$value)
        $values[] = "$key=\"" . rawurlencode($value) . "\"";
    $r .= implode(', ', $values);
    return $r;
}

function returnTweet(){
    $oauth_access_token         = "2602299919-lP6mgkqAMVwvHM1L0Cplw8idxJzvuZoQRzyMkOx";
    $oauth_access_token_secret  = "wGWny2kz67hGdnLe3Uuy63YZs4nIGs8wQtCU7KnOT5brS";
    $consumer_key               = "zAzJRrPOj5BvOsK5QhscKogVQ";
    $consumer_secret            = "Uag0ujVJomqPbfdoR2UAWbRYhjzgoU9jeo7qfZHCxR6a6ozcu1";

    $twitter_timeline           = "user_timeline";  //  mentions_timeline / user_timeline / home_timeline / retweets_of_me

    //  create request
        $request = array(
            'screen_name'       => 'burownrice',
            'count'             => '3'
        );

    $oauth = array(
        'oauth_consumer_key'        => $consumer_key,
        'oauth_nonce'               => time(),
        'oauth_signature_method'    => 'HMAC-SHA1',
        'oauth_token'               => $oauth_access_token,
        'oauth_timestamp'           => time(),
        'oauth_version'             => '1.0'
    );

    //  merge request and oauth to one array
        $oauth = array_merge($oauth, $request);

    //  do some magic
        $base_info              = buildBaseString("https://api.twitter.com/1.1/statuses/$twitter_timeline.json", 'GET', $oauth);
        $composite_key          = rawurlencode($consumer_secret) . '&' . rawurlencode($oauth_access_token_secret);
        $oauth_signature            = base64_encode(hash_hmac('sha1', $base_info, $composite_key, true));
        $oauth['oauth_signature']   = $oauth_signature;

    //  make request
        $header = array(buildAuthorizationHeader($oauth), 'Expect:');
        $options = array( CURLOPT_HTTPHEADER => $header,
                          CURLOPT_HEADER => false,
                          CURLOPT_URL => "https://api.twitter.com/1.1/statuses/$twitter_timeline.json?". http_build_query($request),
                          CURLOPT_RETURNTRANSFER => true,
                          CURLOPT_SSL_VERIFYPEER => false);

        $feed = curl_init();
        curl_setopt_array($feed, $options);
        $json = curl_exec($feed);
        curl_close($feed);

    return $json;
}

$tweet = returnTweet();
echo $tweet;

?>
Terry Bu
fuente
-2

Si es útil para alguien ... En mi blog he implementado el siguiente código PHP para recuperar los últimos tweets, extraer sus datos más relevantes y luego guardarlos en una base de datos MySQL. Funciona porque lo tengo en mi blog.

La tabla de "tweets" donde los almacena:

CREATE TABLE IF NOT EXISTS `tweets` (
  `tweet_id` int(11) NOT NULL auto_increment,
  `id_tweet` bigint(20) NOT NULL,
  `text_tweet` char(144) NOT NULL,
  `datetime_tweet` datetime NOT NULL,
  `dayofweek_tweet` char(3) NOT NULL,
  `GMT_tweet` char(5) NOT NULL,
  `shorturl_tweet` char(23) NOT NULL,
  PRIMARY KEY  (`tweet_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=83 ;

get_tweets.php:

<?php
function buildBaseString($baseURI, $method, $params) {
    $r= array();
    ksort($params);
    foreach($params as $key=>$value){
        $r[]= "$key=".rawurlencode($value);
    }
    return $method."&".rawurlencode($baseURI).'&'.rawurlencode(implode('&', $r));
}

function buildAuthorizationHeader($oauth) {
    $r= 'Authorization: OAuth ';
    $values= array();
    foreach($oauth as $key=>$value) {
        $values[]= "$key=\"".rawurlencode($value)."\"";
    }
    $r.= implode(', ', $values);
    return $r;
}

function returnTweets($last_id) {
    $oauth_access_token         = "2687912757-vbyfJA483SEyj2HJ2K346aVMxtOIgVbsY4Edrsw";
    $oauth_access_token_secret  = "nIruzmR0bXqC3has4fTf8KAq4pgOceiuKqjklhroENU4W";
    $api_key                    = "ieDSTFH8QHHPafg7H0whQB9GaY";
    $api_secret                 = "mgm8wVS9YP93IJmTQtsmR8ZJADDNdlTca5kCizMkC7O7gFDS1j";
    $twitter_timeline           = "user_timeline";  //[mentions_timeline/user_timeline/home_timeline/retweets_of_me]
    //create request
    $request= array(
        'screen_name'       => 'runs_ES',
        'count'             => '3',
        'exclude_replies'   => 'true'
        );
    if (!is_null($last_id)) { //Add to the request if it exits a last_id
        $request['since_id']= $max_id;
    }
    $oauth = array(
        'oauth_consumer_key'        => $api_key,
        'oauth_nonce'               => time(),
        'oauth_signature_method'    => 'HMAC-SHA1',
        'oauth_token'               => $oauth_access_token,
        'oauth_timestamp'           => time(),
        'oauth_version'             => '1.0'
        );
    //merge request and oauth to one array
    $oauth= array_merge($oauth, $request);
    //do some magic
    $base_info=                 buildBaseString("https://api.twitter.com/1.1/statuses/$twitter_timeline.json", 'GET', $oauth);
    $composite_key=             rawurlencode($api_secret).'&'.rawurlencode($oauth_access_token_secret);
    $oauth_signature=           base64_encode(hash_hmac('sha1', $base_info, $composite_key, true));
    $oauth['oauth_signature']=  $oauth_signature;
    //make request
    $header= array(buildAuthorizationHeader($oauth), 'Expect:');
    $options= array(CURLOPT_HTTPHEADER => $header,
                    CURLOPT_HEADER => false,
                    CURLOPT_URL => "https://api.twitter.com/1.1/statuses/$twitter_timeline.json?". http_build_query($request),
                    CURLOPT_RETURNTRANSFER => true,
                    CURLOPT_SSL_VERIFYPEER => false);
    $feed= curl_init();
    curl_setopt_array($feed, $options);
    $json= curl_exec($feed);
    curl_close($feed);
    return $json;
}

function parse_tweettext($tweet_text) {
    $text= substr($tweet_text, 0, -23);
    $short_url= substr($tweet_text, -23, 23);
    return array ('text'=>$text, 'short_url'=> $short_url);
}

function parse_tweetdatetime($tweetdatetime) {
    //Thu Aug 21 21:57:26 +0000 2014 Sun Mon Tue Wed Thu Fri Sat
    $months= array('Jan'=>'01', 'Feb'=>'02', 'Mar'=>'03', 'Apr'=>'04', 'May'=>'05', 'Jun'=>'06', 
                    'Jul'=>'07', 'Aug'=>'08', 'Sep'=>'09', 'Oct'=>'10', 'Nov'=>'11', 'Dec'=>'12');
    $GMT= substr($tweetdatetime, -10, 5);
    $year= substr($tweetdatetime, -4, 4);
    $month_str= substr($tweetdatetime, 4, 3);
    $month= $months[$month_str];
    $day= substr($tweetdatetime, 8, 2); 
    $dayofweek= substr($tweetdatetime, 0, 3);
    $time= substr($tweetdatetime, 11, 8);
    $date= $year.'-'.$month.'-'.$day;
    $datetime= $date.' '.$time;
    return array('datetime'=>$datetime, 'dayofweek'=>$dayofweek, 'GMT'=>$GMT);
    //datetime: "YYYY-MM-DD HH:MM:SS", dayofweek: Mon, Tue..., GMT: +####
}

//First check in the database the last id tweet:
$query= "SELECT MAX(tweets.id_tweet) AS id_last FROM tweets;";
$result= exec_query($query);
$row= mysql_fetch_object($result);
if ($result!= 0 && mysql_num_rows($result)) { //if error in query or not results
    $last_id= $row->id_last;
}
else {
    $last_id= null;
}

$json= returnTweets($last_id);
$tweets= json_decode($json, TRUE);

foreach ($tweets as $tweet) {
    $tweet_id= $tweet['id'];
    if (!empty($tweet_id)) { //if array is not empty
        $tweet_parsetext= parse_tweettext($tweet['text']);
        $tweet_text= utf8_encode($tweet_parsetext['text']);
        $tweet_shorturl= $tweet_parsetext['short_url'];
        $tweet_parsedt= parse_tweetdatetime($tweet['created_at']);
        $tweet_datetime= $tweet_parsedt['datetime'];
        $tweet_dayofweek= $tweet_parsedt['dayofweek'];
        $tweet_GMT= $tweet_parsedt['GMT'];
        //Insert the tweet into the database:
        $fields = array(
            'id_tweet' => $tweet_id,
            'text_tweet' => $tweet_text,
            'datetime_tweet' => $tweet_datetime,
            'dayofweek_tweet' => $tweet_dayofweek,
            'GMT_tweet' => $tweet_GMT,
            'shorturl_tweet' => $tweet_shorturl
            );
        $new_id= mysql_insert('tweets', $fields);
    }
} //end of foreach
?>

La función para guardar los tweets:

function mysql_insert($table, $inserts) {
    $keys = array_keys($inserts);
    exec_query("START TRANSACTION;");
    $query= 'INSERT INTO `'.$table.'` (`'.implode('`,`', $keys).'`) VALUES (\''.implode('\',\'', $inserts).'\')';
    exec_query($query);
    $id= mysql_insert_id();
    if (mysql_error()) {
        exec_query("ROLLBACK;");
        die("Error: $query");
    }
    else {
        exec_query("COMMIT;");
    }
    return $id;
}
carreras
fuente
'Funciona porque lo tengo en mi blog' es uno de mis favoritos. Tu publicación no responde la pregunta real. También el código php que está utilizando tiene mala calidad. Lea un poco aquí phptherightway.com . Especialmente sobre DB
Maciej Paprocki
También ha hecho públicas todas sus claves y tokens, ¡así que no se sorprenda si alguien lo toma y piratea su cuenta de Twitter!
garrettlynch