Exemplo PHP mais simples para recuperar user_timeline com a API do Twitter versão 1.1

292

Devido à aposentadoria da API 1.0 do Twitter em 11 de junho de 2013 , o script abaixo não funciona mais.

// 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);
    }
}

Como posso obter o user_timeline (status recentes) com o menor código possível?

Encontrei o seguinte: https://dev.twitter.com/docs/api/1.1/get/statuses/user_timeline, mas recebo o seguinte erro:

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

Existem muitas classes por aí, mas depois de tentar várias, nenhuma delas parece funcionar por causa dessas atualizações no Twitter, e algumas delas são classes bastante avançadas, com muitas funcionalidades que eu realmente não preciso.

Qual é a maneira mais simples / mais curta de obter os status recentes de usuário com PHP?

companheiro
fonte
97
Eu mataria pela resposta a isso. A documentação deles é terrivelmente ruim.
RCNeil 16/10/12
Eu sou novo na API do Twitter e estou lutando um pouco com ela. Eu me vi usando código obsoleto.
Anthony
Dê uma olhada em aamirafridi.com/twitter/…
Aamir Afridi
@ Mark Obrigado Mark !! Essa foi fácil!! Isso não funcionou para mim inicialmente. Estou executando o WAMP. Eu tive que fazer uma mudança para o meu php.ini em meu diretório Apache de acordo com esta discussão: stackoverflow.com/questions/5444249/...
Adlin Ling
1
Eu só escrevi solução sem CURL ou quaisquer outras bibliotecas extras: stackoverflow.com/questions/17049821/...
Rauli Rajande

Respostas:

820

Nota importante: a partir de meados de 2018, o processo para obter tokens da API do twitter se tornou muito mais burocrático. Demorei mais de uma semana para receber um conjunto de tokens de API, e isso é para um projeto de código aberto para vocês, garotas e garotas, com mais de 1,2 milhão de instalações no Packagist e 1,6 mil estrelas no Github, que teoricamente deveriam ter maior prioridade .

Se você está encarregado de trabalhar com a API do twitter para o seu trabalho, deve levar em conta esse tempo de espera potencialmente extremamente longo. Considere também outras vias de mídia social como o Facebook ou o Instagram e forneça essas opções, pois o processo para recuperar seus tokens é instantâneo.


Então você quer usar a API do Twitter v1.1?

Nota: os arquivos para estes estão no GitHub .

A versão 1.0 em breve será preterida e solicitações não autorizadas não serão permitidas. Então, aqui está um post para ajudá-lo a fazer exatamente isso, juntamente com uma classe PHP para facilitar sua vida.

1. Crie uma conta de desenvolvedor: configure uma conta de desenvolvedor no Twitter

Você precisa visitar o site oficial do desenvolvedor do Twitter e se registrar para obter uma conta de desenvolvedor. Esta é uma etapa gratuita e necessária para fazer solicitações para a API v1.1.

2. Crie um aplicativo: crie um aplicativo no site do desenvolvedor do Twitter

O que? Você pensou que poderia fazer solicitações não autenticadas? Não com a API v1.1 do Twitter. Você precisa visitar http://dev.twitter.com/apps e clicar no botão "Criar aplicativo".

Digite a descrição da imagem aqui

Nesta página, preencha os detalhes que desejar. Para mim, isso não importava, porque eu só queria fazer um monte de solicitações de bloqueio para me livrar dos seguidores de spam. O ponto é que você terá um conjunto de chaves exclusivas para usar no seu aplicativo.

Portanto, o objetivo de criar um aplicativo é fornecer a si mesmo (e ao Twitter) um conjunto de chaves. Esses são:

  • A chave do consumidor
  • O segredo do consumidor
  • O token de acesso
  • O segredo do token de acesso

Há um pouco de informação aqui sobre para que servem esses tokens.

3. Crie tokens de acesso : você precisará deles para fazer solicitações bem-sucedidas

OAuth solicita alguns tokens. Então você precisa gerá-los para você.

Digite a descrição da imagem aqui

Clique em "criar meu token de acesso" na parte inferior. Então, depois de rolar para o final novamente, você terá algumas chaves recém-geradas. Você precisa pegar as quatro chaves anteriormente identificadas nesta página para suas chamadas à API. Anote-as em algum lugar.

4. Altere o nível de acesso : você não deseja somente leitura, não é?

Se você quiser fazer um uso decente dessa API, precisará alterar suas configurações para Leitura e gravação se estiver fazendo algo diferente da recuperação de dados padrão usando solicitações GET .

Digite a descrição da imagem aqui

Escolha a guia "Configurações" na parte superior da página.

Digite a descrição da imagem aqui

Dê ao seu aplicativo acesso de leitura / gravação e clique em "Atualizar" na parte inferior.

Você pode ler mais sobre o modelo de permissão de aplicativos que o Twitter usa aqui.


5. Escreva código para acessar a API : eu fiz a maior parte por você

Combinei o código acima, com algumas modificações e alterações, em uma classe PHP, portanto é muito simples fazer as solicitações necessárias.

Isso usa o OAuth e a API do Twitter v1.1 e a classe que eu criei, que você pode encontrar abaixo.

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"
);

Certifique-se de colocar as chaves que você obteve de seu aplicativo acima nos respectivos espaços.

Em seguida, você precisa escolher um URL para o qual deseja fazer uma solicitação. O Twitter possui a documentação da API para ajudá-lo a escolher qual URL e também o tipo de solicitação (POST ou 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';

Na documentação, cada URL indica o que você pode passar para ele. Se estivermos usando o URL "blocks" como o acima, posso passar os seguintes parâmetros POST:

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

Agora que você configurou o que deseja fazer com a API, é hora de fazer a solicitação real.

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

E para uma solicitação POST , é isso!

Para uma solicitação GET , é um pouco diferente. Aqui está um exemplo:

/** 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();     

Exemplo de código final : para uma solicitação GET simples de uma lista dos meus 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();  

Coloquei esses arquivos no GitHub com crédito para @ lackovic10 e @rivers! Espero que alguém ache útil; Eu sei que sim (usei para bloquear em massa em um loop).

Além disso, para aqueles no Windows que estão tendo problemas com certificados SSL, consulte esta postagem . Esta biblioteca usa cURL sob o capô, portanto, é necessário verificar se os certificados de cURL estão configurados. O Google também é seu amigo.

Jimbo
fonte
4
@kaffolder O link nessa página: profilepicture.co.uk/caching-api-responses-php sugere uma maneira simples de fazê-lo. Você escreve seus dados do twitter em um arquivo ou banco de dados (MySQL ou MongoDB) na primeira solicitação e, em seguida, a cada solicitação subsequente, você verifica a hora atual contra o limite de tempo desejado para o arquivo (você pode nomear o arquivo como o limite de tempo) e se o arquivo existir e o nome do arquivo estiver dentro do prazo desejado, retire os dados em vez de executar a solicitação da API. Se o arquivo existir, mas o prazo for ultrapassado, exclua o arquivo e execute a solicitação da API.
Jimbo
7
Não consigo descobrir como lidar com os dados json, uma vez retornados. Eu não quero apenas repeti-lo na tela como em eco $ twitter -> setGetfield ($ getfield) -> buildOauth ($ url, $ requestMethod) -> performRequest (); Desculpas, não consigo descobrir como fazer novas linhas! Eu quero fazer algo como $ jsonData = json_decode ($ twitter); mas ele não funciona - Eu sinto que estou perdendo algo fundamental, mas a moeda não é droppping ...
Ashley
67
Obrigado, a documentação do Twitter é uma bagunça desorganizada, isso ajudou muito.
Joren
7
Existem alguns pré-requisitos para que essa classe funcione no Windows. Você precisa ter uma versão funcional do cURL carregada no seu php.iniarquivo e também carregar os certificados da CA no seu php.iniarquivo usando curl.cainfo = path\to\cacert.pem. Você pode obter os certificados da CA aqui .
Jake Z
4
@Jimbo Eu estava apenas observando que algumas das extensões cURL padrão são defeituosas no Windows e exigem substituição (daí o link para as versões "fixas") e que, sem carregar os certificados da CA, sua classe retorna um false, como o curl_error () relata que "problema no certificado SSL, verifique se o certificado da CA está OK". Isso pode ser evitado desativando CURLOPT_SSL_VERIFYPEER, mas pensei em incluir as instruções básicas para realmente usar os certificados da CA. Apenas incluí isso para potencialmente salvar algumas pessoas em alguns minutos de pesquisa.
Jake Z
137

Acesse dev.twitter.com e crie um aplicativo . Isso fornecerá as credenciais necessárias. Aqui está uma implementação que escrevi recentemente com PHP e 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);

?>

Isso pode ser executado na linha de comando:

$ php <name of PHP script>.php
Rivers
fonte
2
Obrigado pelo trecho de código, trabalhe na perfeição. O único problema é que não consigo descobrir como definir o retorno da contagem de postagens. Ele só retorna 20 e eu quero o valor total que é 200 conforme o limite do twitter.
Flatlyn
23
Como você definiria screen_namee countcom essa abordagem? Tentei adicioná-lo à $urlvariável, mas recebi o erro "Não foi possível autenticar você".
Javier Villanueva
1
Esse código funciona muito bem! Estou tentando modificá-lo para usar a API search / tweets.json, mas estou sempre recebendo a resposta 'não foi possível autenticar você' - alguma idéia?
28613 Chris
1
Este post foi muito útil. Meu código não parece retornar curl_init(). Eu olhei para alguns exemplos e eles parecem muito simples, diretos e exatamente como este código aqui ... Preciso instalar algo especial?
Jessicaraygun # 5/13
1
Funcionou para mim em 26 de outubro de 2016. O resultado foi um pouco mais complexo do que eu esperava.
26616 JohnC
61

O código colado por Rivers é ótimo. Muito obrigado! Sou novo aqui e não posso comentar. Gostaria apenas de responder à pergunta de javiervd (como você definiria o screen_name e contaria com essa abordagem?), Pois perdi muito tempo para descobrir isso. Fora.

Você precisa adicionar os parâmetros ao URL e ao processo de criação de assinaturas. Criar uma assinatura é o artigo que me ajudou. Aqui está o meu 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
fonte
2
Não posso votar isso o suficiente. Na documentação da API do Twitter, isso o encara de frente, mas nunca é super 'óbvio'. Essa abordagem mexe com a buildAuthorizationHeaderfunção? Eu o implementei separadamente.
Moe
Não trabalho há muito tempo, então não me lembro, se você ainda não resolveu o problema, posso analisá-lo nos próximos dias.
lackovic10
Estou tentando adaptar sua solução para executar o POST em status / update.json sem sorte, você tem alguma idéia de como isso pode ser alcançado?
precisa saber é o seguinte
1
@perrohunter eu não tenho idéia teria que olhar mais para isso. Se você não encontrar uma maneira em alguns dias, envie-me uma mensagem. Vou tentar ajudá-lo.
precisa saber é o seguinte
18

Como indicado em outras respostas, crie um aplicativo do Twitter para obter o token, a chave e o segredo. Usando o código abaixo, você pode modificar os parâmetros de solicitação de um ponto e evitar erros de digitação e erros semelhantes (alterar a $requestmatriz na returnTweet()função).

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);
}

e depois é só ligar returnTweet()

budidino
fonte
1
Awesome job @budidino! Criou o aplicativo em dev.twitter.com/apps e preencheu seus xs com oauth_access_token, oauth_access_token_secret, consumer_key, consumer_secret. * note * que você precisa pressionar "criar meu token de acesso" e leva alguns segundos para ser gerado; portanto, aguarde.
Theo #
@budidino dnt precisamos incluir qualquer biblioteca ??
anam
Preenchi as chaves, adicionei isso ao meu functions.phparquivo no WordPress, coloquei <?php echo returnTweet(); ?>um arquivo HTML e ele gera a palavra "Matriz" e nada mais.
J82
@Desi, o resultado é uma série de tweets, você deve lidar com a forma como exibe cada um deles. tente print_r (returnTweet ()) apenas para ver o que está dentro. Confira este exemplo de exibir todos os tweets: gist.github.com/budidino/9681764#file-stackoverflow-returntweet
budidino
1
Se você deseja buscar apenas o último tweet, modifique a matriz $ request e defina count como 1. Digamos que você use $ tweet = returnTweet (); então, se você quiser exibir o último tweet (neste caso, o único), escreva algo como isto: echo "latest tweet:". $ tweet [0] ["text"]; Certifique-se de verificar a estrutura do twitter retornado se desejar extrair mais do que apenas o texto do tweet (exemplo: $ userProfileImageURL = $ tweet [0] ["usuário"] ["profile_image_url"]). dev.twitter.com/docs/api/1.1/get/statuses/user_timeline
budidino
16

Obrigado Kris!

Ele funcionou para mim sem usar parâmetros para a consulta, sempre que eu usava mais de um parâmetro, ele me mostrava o erro: 32 Não foi possível autenticar você.

O problema para mim estava na codificação e comercial. Então, no seu código, onde está a seguinte linha

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

Eu adicionei a seguinte linha abaixo:

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

E funcionou usando dois ou mais parâmetros como screen_name e count.

O código inteiro fica assim:

$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 ajude alguém com o mesmo problema que eu tive.

Frewuill
fonte
muito obrigado, seu aprimoramento de código funciona bem! Uma pergunta é re: "// um nonce mais forte é recomendado". O que poderia ser isso? Tempo()?
22413 Sebastian
Obrigado por apontar isso. Sebastian: um nonce é um token de uso único que deve ser criptograficamente seguro. mt_rand () é muito curto (32 bits) e não um PRNG criptográfico. Em teoria, isso torna o token oauth fraco, mas por uma questão de simplicidade no meu código de exemplo original, eu queria usar algo que estivesse disponível no PHP e fosse facilmente compreensível.
Kris Reeves
recebendo erro 32. Não foi possível autenticar você .. qualquer ajuda por favor ??? Eu usei o código acima
saadk
@frewuill, você é ótimo mano, está me trabalhando como um encanto, obrigado.
Vijay
9

Essa pergunta me ajudou muito, mas não me levou a entender o que precisa acontecer. Esta postagem do blog fez um trabalho incrível ao me guiar por ela.

Aqui estão os bits importantes em um só lugar:

  • Como indicado acima, você DEVE assinar suas solicitações da API 1.1. Se estiver fazendo algo como obter status público, convém uma chave de aplicativo em vez de uma chave de usuário. O link completo para a página que você deseja é: https://dev.twitter.com/apps
  • Você deve fazer o hash TODOS os parâmetros, os oauth E os parâmetros get (ou parâmetros POST) juntos.
  • Você deve ORGANIZAR os parâmetros antes de reduzi-los ao formulário codificado por URL que recebe hash.
  • Você deve codificar algumas coisas várias vezes - por exemplo, você cria uma string de consulta a partir dos valores codificados por URL dos parâmetros e, em seguida, codifica ISSO e concatena com o tipo de método e o URL.

Simpatizo com todas as dores de cabeça, então aqui está um código para encerrar tudo:

$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
fonte
6

Se você possui a biblioteca PHP do OAuth instalada, não precisa se preocupar em formar a solicitação.

$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 mais informações, consulte Os documentos ou o exemplo deles . Você pode usar pecl install oauthpara obter a biblioteca.

jeffaudio
fonte
5

Antes de tudo, queria agradecer a jimbo e ( sua biblioteca simples post / twitter-api-php).

Se você vai usar a API de pesquisa / tweets GET com a biblioteca PHP "twitter-api-php" (TwitterAPIExchange.php):

Primeiro, basta comentar a área de código "Executar uma solicitação POST e repetir a resposta".

Basta usar o código "Executar uma solicitação GET e repetir a resposta", repetir a resposta e alterar estas duas linhas:

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

para

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

(Mude screen_namepara q, é isso :)

Chanuka Asanka
fonte
Eu ainda não tenho sorte: /
Ricardo
2

Você precisará criar um "aplicativo" no Twitter (e uma conta no Twitter para fazer isso).

Em seguida, você precisa usar o OAuth para fazer uma solicitação autorizada ao Twitter .

Você pode usar o recurso GET status / user_timeline para obter uma lista dos tweets recentes.

Matthew Rapati
fonte
4
Por favor, para nós, pessoas estúpidas, explique. Você está dando tantas informações, se não menos, quanto a documentação. Você usa a HttpRequest()função PHP para o passo 2? Existe a biblioteca PHP do TwitterOAuth de Abraham - github.com/abraham/twitteroauth - que também deve fazer isso, mas um exemplo de como implementá-lo não é realmente fornecido.
RCNeil 16/10/12
2
O github.com/abraham/twitteroauth/blob/master/test.php parece ter muitos exemplos!
Matthew Rapati 17/10/12
2
@MatthewRapati Página está ausente.
RN Kushwaha
0

Aqui está um breve resumo para obter um número especificado de tweets em sua linha do tempo. Basicamente, faz a mesma coisa que os outros exemplos, apenas com menos código.

Basta preencher as chaves e ajustar $countao seu gosto:

$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))))))));

Este usa funções anônimas e em file_get_contentsvez da biblioteca cURL. Observe o uso de um nonce de hash MD5. Todo mundo parece concordar com o time()nonce, no entanto, a maioria dos exemplos na Web relativos ao OAuth usa algum tipo de string criptografada (como esta: http://www.sitepoint.com/understanding-oauth-1/ ). Isso faz mais sentido para mim também.

Nota adicional: você precisa do PHP 5.3+ para as funções anônimas (caso seu servidor / computador esteja em alguma caverna da Guerra Fria e você não possa atualizá-lo).

Kasimir
fonte
-1

No gerador de assinaturas , você pode gerar curlcomandos do formulário:

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
fonte
-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
fonte
3
Inclua uma explicação sobre o que esse código faz, para que o OP possa aprender com ele.
Cerbrus
-2

Graças a esta discussão, e especialmente budidino, porque seu código foi o que levou para casa. Só queria contribuir como recuperar os dados JSON de uma solicitação. Faça alterações na matriz de solicitação "// create request" como parte do código para executar solicitações diferentes. Por fim, isso exibirá o JSON na tela do 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
fonte
-2

Se for útil para qualquer pessoa ... No meu blog, implementei o seguinte código PHP para recuperar os últimos tweets, extrair os dados mais relevantes e salvá-los no banco de dados MySQL. Funciona porque eu peguei no meu blog.

A tabela "tweets" onde os armazena:

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
?>

A função para salvar os 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;
}
corre
fonte
'Funciona porque eu o peguei no meu blog' é um dos meus favoritos. Sua postagem não responde à pergunta real. Também o código php que você está usando tem má qualidade. Leia um pouco aqui phptherightway.com . Especialmente sobre DB #
Maciej Paprocki
Além disso, você tornou públicas todas as suas chaves e tokens; portanto, não se surpreenda se alguém pegá-lo e invadir sua conta do Twitter!
garrettlynch