Construire avec l'API Twitter OAuth, Lecture et Publication

Ce que vous allez créer

Cet article est le deuxième d'une série de trois articles sur l'utilisation de l'API Twitter. Si vous avez manqué la première partie, vous pouvez lis le ici.

Authentification avec Twitter via OAuth

Birdcage utilise une extension Yii appelée Yii Twitter par Will Wharton, qui utilise la bibliothèque open source PHP OAuth de Abraham Williams..

Je place l'extension dans l'arbre Yii sous / app / protected / extensions / yiitwitteroauth. Dans Yii, vous configurez les propriétés d’extension dans main.php fichier de configuration comme ceci:

 // composants d'application 'components' => array ('twitter' => array ('class' => 'ext.yiitwitteroauth.YiiTwitter', 'consumer_key' => "," consumer_secret "=>", "callback" => ",), 

Normalement, je charge ces paramètres depuis mon fichier Yii .ini, mais pour simplifier la configuration de Birdcage, je configure les clés d’application à partir du Paramètres utilisateur modèle. J'ai étendu YiiTwitter.php pour charger les clés d'application de l'utilisateur par défaut lors de l'initialisation:

 public function init () // charge les clés de l'application Twitter depuis la table UserSetting $ result = UserSetting :: model () -> loadPrimarySettings (); $ this-> consumer_key = $ result ['twitter_key']; $ this-> consumer_secret = $ result ['twitter_secret']; $ this-> callback = $ result ['twitter_url']; $ this-> registerScripts (); parent :: init ();  

Une fois que vous avez installé et configuré les paramètres de l’application, vous devez visiter le Comptes menu et cliquez Ajoutez votre compte Twitter

Lorsque vous cliquez sur l'icône Twitter, il exécute le Relier méthode du contrôleur Twitter Birdcage:

 fonction publique actionConnect () unset (Yii :: app () -> session ['account_id'])); Yii :: app () -> session ['account_id'] = $ _ GET ['id']; $ twitter = Yii :: app () -> twitter-> getTwitter (); $ request_token = $ twitter-> getRequestToken (); // définit des informations de session Yii :: app () -> session ['oauth_token'] = $ token = $ request_token ['oauth_token']; Yii :: app () -> session ['oauth_token_secret'] = $ request_token ['oauth_token_secret']; if ($ twitter-> http_code == 200) // récupère l'url de connexion Twitter $ url = $ twitter-> getAuthorizeURL ($ token); // leur envoie Yii :: app () -> request-> redirect ($ url);  else // erreur ici $ this-> redirect (Yii :: app () -> homeUrl); 

Cela vous ramènera à Twitter via OAuth pour authentifier votre compte Twitter:

Une fois que vous êtes connecté, Twitter vous demandera d'autoriser l'application Birdcage:

Twitter renverra le navigateur à votre URL de rappel, notre méthode de rappel du contrôleur Twitter. Cela sauvera votre jeton OAuth de l'utilisateur Twitter et son secret dans la table des comptes:

 fonction publique actionCallback () / * Si oauth_token est ancien, redirige vers la page de connexion. * / if (isset ($ _ REQUEST ['oauth_token'])) && Yii :: app () -> session ['oauth_token']! == $ _REQUEST ['oauth_token']) Yii :: app () -> session ['oauth_status'] = 'oldtoken';  / * Créer un objet TwitteroAuth avec clé / secret et clé / clé de jeton à partir de la phase par défaut * / $ twitter = Yii :: app () -> twitter-> getTwitterTokened (Yii :: app () -> session ['oauth_token' ], Yii :: app () -> session ['oauth_token_secret']); / * Demander des jetons d'accès à Twitter * / $ access_token = $ twitter-> getAccessToken ($ _ REQUEST ['oauth_verifier']); / * Sauvegarde les jetons d’accès. Normalement, ceux-ci seraient sauvegardés dans une base de données pour une utilisation future. * / Yii :: app () -> session ['access_token'] = $ access_token; $ account = Account :: model () -> findByAttributes (array ('utilisateur_id' => Yii :: app () -> utilisateur-> id, 'id' => Yii :: app () -> session ['identifiant de compte ']); $ account ['oauth_token'] = $ access_token ['oauth_token']; $ compte ['oauth_token_secret'] = $ access_token ['oauth_token_secret']; $ compte-> save (); / * Supprimer les jetons de demande dont vous n'avez plus besoin * / unset (Yii :: app () -> session ['oauth_token']); unset (Yii :: app () -> session ['oauth_token_secret']); if (200 == $ twitter-> http_code) / * L'utilisateur a été vérifié et les jetons d'accès peuvent être sauvegardés pour une utilisation future * / Yii :: app () -> session ['status'] = 'vérifié'; $ this-> redirect (array ('compte / admin'));  else / * Enregistrer le statut HTTP pour la boîte de dialogue d'erreur sur la page de connexion. * / // header ('Location: /clearsessions.php'); $ this-> redirect (Yii :: app () -> homeUrl);  

Birdcage est maintenant prêt à commencer à faire des demandes de données Twitter via l'API pour le compte de votre compte utilisateur..

Comme vous le verrez, un simple appel avec les jetons permet d'accéder à l'API:

$ twitter = Yii :: app () -> twitter-> getTwitterTokened ($ compte ['oauth_token'], $ compte ['oauth_token_secret']); 

Traitement des tweets en arrière-plan

Pour la deuxième partie de notre didacticiel, nous utilisons l’API REST de Twitter. La troisième partie portera sur l’API de streaming en temps réel et toujours active:

Récupérer les chronologies Twitter

Les timelines de Twitter constituent une pile de tweets en constante expansion. L'activité de surveillance est donc un peu plus compliquée que votre API REST moyenne. Vous pouvez en apprendre davantage sur le problème unique des chronologies Twitter présent ici. Essentiellement, lorsque vous essayez de lire l'historique de la chronologie, de nouveaux tweets sont ajoutés tout le temps:

Twitter fournit un moyen relativement simple de gérer cela. Vous pouvez suivre le code qui effectue cela dans le modèle Tweet de Birdcage, getRecentTweets ().

D'abord, nous cherchons le plus haut (le plus récent) tweet_id dans notre base de données et renvoyer une valeur incrémentée:

 fonction publique getLastTweet ($ account_id) // obtenir le meilleur tweet_it où account_id = $ account_id $ criter = = new CDbCriteria; $ critères-> select = 'max (tweet_id) AS max_tweet_id'; $ criteres-> condition = "account_id =". $ account_id; $ row = Tweet :: model () -> find ($ critères); if ($ row ['max_tweet_id'] == 0) renvoie 1; sinon return $ row ['max_tweet_id'] + 1; 

Ensuite, nous demandons un certain nombre (par exemple 100) de tweets depuis le plus élevé traité précédemment. L'API Twitter reconnaît la depuis_id en tant que pointeur sur le lieu de la chronologie duquel vous souhaitez commencer la récupération. Il renverra tous les tweets plus récents que depuis_id. Dans l'exemple ci-dessous, nous interrogeons la méthode statuses / home_timeline de l'API REST. La chronologie de la maison correspond à ce qu'un utilisateur voit sur son écran principal Twitter.

 $ Since_id = $ this-> getLastTweet ($ account-> id); echo 'depuis:'. $ Since_id; lb (); // récupère les tweets jusqu'à la dernière stockée $ tweets = $ twitter-> get ("statuses / home_timeline", array ('count' => 100, 'Since_id' => $ Since_id)); if (count ($ tweets) == 0) renvoie false; // rien n'est revenu 

Il est également important de vérifier si nous avons été limités par Twitter. Chaque demande d'utilisateur d'application est autorisée à appliquer 180 demandes à la ligne de temps d'origine d'un utilisateur par fenêtre de 15 minutes. Toutefois, les limites de débit varient en fonction de l'activité. La durée de programmation peut donc varier..

Pour chaque tweet reçu, nous appelons notre Parse () méthode pour traiter les données et les stocker dans nos diverses tables de base de données. Au cours du processus, nous suivons le plus ancien / le plus bas tweet_id que nous avons reçu de Twitter:

 foreach ($ tweets comme $ i) if ($ low_id == 0) $ low_id = intval ($ i-> id_str); sinon $ low_id = min (intval ($ i-> id_str), $ low_id); Tweet :: model () -> parse ($ account-> id, $ i); 

La méthode d'analyse ajoute les informations d'utilisateur Twitter référencées, puis le tweet lui-même. Il y a plus de détails dans le Parse.php modèle.

 fonction publique parse ($ account_id, $ tweet) // ajouter un utilisateur $ tu = TwitterUser :: model () -> add ($ tweet-> utilisateur); // ajouter un tweet $ tweet_obj = $ this-> add ($ account_id, $ tweet);

Ensuite, nous continuons à demander des blocs de tweets en utilisant l’ID le plus bas de la dernière demande en tant que max_id paramètre que nous envoyons à Twitter. Nous faisons ces demandes ultérieures en utilisant le depuis_id du tweet nous avons commencé avec et la max_id du dernier tweet le plus ancien que nous avons récupéré.

 // récupère le bloc suivant jusqu'à ce que notre limite de code atteigne while ($ count_tweets <= $limit)  lb(2); $max_id = $low_id-1; $tweets= $twitter->get ("statuses / home_timeline", array ('count' => 100, 'max_id' => $ max_id, 'Since_id' => $ Since_id)); if (count ($ tweets) == 0) pause; if ($ this-> isRateLimited ($ tweets)) renvoie false; echo 'count'.count ($ tweets); lb (); $ count_tweets + = count ($ tweets); foreach ($ tweets en tant que $ i) $ low_id = min (intval ($ i-> id_str), $ low_id); Tweet :: model () -> parse ($ account-> id, $ i); 

Ainsi, par exemple, lorsque de nouveaux tweets arrivent, nous ne les voyons pas, car Twitter ne fait que nous envoyer des tweets depuis le plus haut tweet_id (depuis_id) de notre base de données. Nous devrons revenir plus tard pour obtenir de nouveaux tweets, qui sont plus élevés que notre première depuis_id.

Il est important de noter que nous ne recevons pas un nombre infini de tweets plus anciens. Twitter ne nous renvoie que le nombre de tweets que nous demandons qui sont plus anciens que l’ID inférieur précédent ou (max_id lors de notre prochain appel).

Une fois que vous vous êtes habitué au modèle et à la nomenclature, c'est assez simple.

Alors qu'il y a un Chercher commande de menu qui exécutera cette opération, nous configurons également un cron travail d'appeler notre DaemonController méthode toutes les cinq minutes:

# Pour définir l'heure, vous pouvez fournir des valeurs concrètes pour # minute (m), heure (h), jour du mois (dom), mois (lun), # et jour de la semaine (Dow) ou utilisez '*' dans ces champs. (pour 'any'). # # Notez que les tâches seront démarrées en fonction de la notion de temps et de fuseaux horaires du démon système de cron. # # Par exemple, vous pouvez exécuter une sauvegarde de tous vos comptes utilisateurs # à 5 heures du matin chaque semaine avec: # 0 5 * * 1 tar -zcf /var/backups/home.tgz / home / # # mh commande mon mon * / 5 * * * * wget -O / dev / null http://birdcage.votredomaine.com/daemon/index

Cela appelle à notre tour getStreams méthode qui effectue les opérations décrites ci-dessus (remarque, la fonctionnalité des flux sera décrite dans la troisième partie de cette série):

 fonction publique actionIndex () // si nous n'utilisons pas les flux Twitter, nous traiterons les tweets par l'API REST si (! Yii :: app () -> params ['twitter_stream']) Tweet :: model () -> getStreams ();  else Stream :: model () -> process (); 

Le résultat final ressemble à ceci:

Une fois, j'ai rencontré des problèmes de fiabilité des API Twitter. Vous pouvez vérifier le statut des services de l'API Twitter ici.

Poster un Tweet

La publication de tweets sur votre compte Twitter est en réalité assez simple. Nous devons juste utiliser la méthode REST statuses / update. Effectuer un décompte précis des caractères demande un peu plus de travail. 

Twitter résout toutes les URL en raccourcis http://t.co, de sorte que toutes les URL comptent pour 20 caractères. J'avais besoin de JavaScript qui compterait les caractères et ajusterait n'importe quelle URL de 20 caractères quelle que soit la longueur d'une URL. J'ai opté pour une combinaison de solutions jQuery et JavaScript, que je vais détailler ci-dessous..

J'ai choisi de créer un modèle spécifiquement pour composer des tweets appelés Status.php. Cela facilitait le travail avec Yii pour générer des formulaires à publier dans l'API.. 

Lorsque vous cliquez sur Composer dans le menu Birdcage, cela vous mènera au Composer méthode du StatusController:

 fonction publique actionCompose ($ id = 0) if (! UserSetting :: model () -> checkConfiguration (Yii :: app () -> utilisateur-> id)) Yii :: app () -> utilisateur-> setFlash ('warning', 'Veuillez configurer vos paramètres Twitter.'); $ this-> redirect (array ('/ usersetting / update'));  $ model = new Status; $ model-> account_id = $ id; // Décommentez la ligne suivante si la validation AJAX est nécessaire // $ this-> performAjaxValidation ($ model); if (isset ($ _ POST ['Statut'])) $ modèle-> attributs = $ _ POST ['Statut']; if ($ model-> account_id == "ou $ model-> account_id == 0) Yii :: app () -> utilisateur-> setFlash ('no_account', 'Vous devez sélectionner un compte avant de tweeter.'); $ this-> redirect (array ('status / compose')); $ model-> created_at = new CDbExpression ('NOW ()'); $ model-> modified_at = new CDbExpression ('NOW ()'); if ($ model-> save ()) $ account = Account :: model () -> findByPK ($ model-> account_id); $ twitter = Yii :: app () -> twitter-> getTwitterTokened ($ account [' oauth_token '], $ account [' oauth_token_secret ']); // récupère les tweets jusqu'à la dernière fois stockés $ tweets = $ twitter-> post ("statuses / update", array (' status '=> $ model-> tweet_text )); $ this-> redirect (array ('view', 'id' => $ model-> id)); $ this-> render ('compose', array ('model' => $ model, ));

Cela chargera le formulaire HTML pour créer un élément d'état. Vérifiez _form.php dans / app / protected / views / status /.

Premièrement, je vais charger plusieurs bibliothèques jQuery et JavaScript pour le comptage de caractères:

$ baseUrl = Yii :: app () -> baseUrl; $ cs = Yii :: app () -> getClientScript (); $ cs-> registerScriptFile ($ baseUrl. '/ js / jquery.simplyCountable.js'); $ cs-> registerScriptFile ($ baseUrl. '/ js / twitter-text.js'); $ cs-> registerScriptFile ($ baseUrl. '/ js / twitter_count.js'); 

J'ai utilisé une combinaison du plugin jQuery simplyCountable, de twitter-text.js (un script de traitement de texte Twitter basé sur JavaScript) et d'un script qui faisait le gros du travail de réglage des URL: twitter_count.js.

Le code suivant crée ensuite le reste du formulaire de composition et active les scripts de comptage de caractères:

beginWidget ('bootstrap.widgets.TbActiveForm', array ('id' => 'status-form', 'enableAjaxValidation' => false,)); ?> user-> hasFlash ('no_account')) $ this-> widget ('bootstrap.widgets.TbAlert', array ('alerts' => array (// configurations par type d'alerte 'no_account' => array ('block' => true, 'fade' => true, 'closeText' => '×'),),)); ?> 

Champs avec * sont requis.

errorSummary ($ model); ?> account_id == 0) echo CHtml :: activeLabel ($ model, 'account_id', array ('label' => 'Tweet avec le compte:')); $ model-> account_id = 1; echo CHtml :: activeDropDownList ($ model, 'account_id', Account :: model () -> getList (), array ('empty' => 'sélectionner un compte')); else echo CHtml :: hiddenField ('account_id', $ model-> account_id); ?>
textAreaRow ($ model, 'tweet_text', array ('id' => 'tweet_text', 'rows' => 6, 'cols' => 50, 'class' => 'span8')); ?>

Restant: 0

widget ('bootstrap.widgets.TbButton', array ('buttonType' => 'submit', 'type' => 'primaire', 'label' => $ model-> isNewRecord? 'Create': 'Save', ) ?>
endWidget (); ?>

Le résultat ressemble à ceci:

Lorsque le tweet est enregistré, il exécute ce code dans StatusController, qui publie le résultat. tweet_text sur Twitter via OAuth:

 if ($ model-> save ()) $ account = Account :: model () -> findByPK ($ model-> account_id); $ twitter = Yii :: app () -> twitter-> getTwitterTokened ($ compte ['oauth_token'], $ compte ['oauth_token_secret']); // récupère les tweets jusqu'à la dernière stockée $ tweets = $ twitter-> post ("statuses / update", array ('status' => $ modèle-> tweet_text)); $ this-> redirect (array ('view', 'id' => $ model-> id)); 

Prochaines étapes

Dans cette partie de la série, nous avons expliqué comment s'authentifier auprès de l'API Twitter via OAuth, comment interroger des plages de tweets dans la chronologie de l'utilisateur et comment compter les caractères et publier des tweets via l'API. J'espère que vous avez trouvé cela utile.

La troisième partie traitera de l’utilisation de l’API Twitter Streaming et de l’implémentation open source Phirehose Stream.

S'il vous plaît poster des commentaires, des corrections ou des idées supplémentaires ci-dessous. Vous pouvez parcourir mes autres tutoriels Tuts + sur ma page d’auteur ou me suivre sur Twitter @reifman.