Membangun Dengan API Twitter: Tweet Storms
Indonesian (Bahasa Indonesia) translation by Muhammad Gufron (you can also view the original English article)



Pada bulan April, investor dan pendiri Netscape, Marc Andreessen mulai memperluas batas-batas 140 karakter alami Twitter dengan menerbitkan pemikirannya dalam urutan tweet, yang beberapa orang telah menjuluki bunyi tweet storms (pengusaha Yvo Schaap mengkompilasi ini di situs webnya).
Tidak butuh waktu lama sebelum BuzzFeed (pemula listel yang harus dihentikan) bangkit melawan praktik ini: Mengapa Twitter Tweetstorm ™ Trend Terbaru Harus Dihentikan. Secara pribadi, saya mungkin untuk apa pun BuzzFeed melawan.
Beberapa layanan muncul untuk memudahkan manusia seperti diri kita sendiri untuk mempublikasikan tweet storms, tetapi mereka tampaknya agak tidak dapat diandalkan dan tidak konsisten. Saya memutuskan untuk membuat fitur sendiri dan menurut saya ada manfaat dalam melakukan ini dengan aplikasi Anda sendiri.
Dalam tutorial ini, saya akan memandu Anda melalui membangun fitur tweet storm Anda sendiri menggunakan Twitter API. Ini adalah kelanjutan dari seri tutorial Twitter API di Tuts +; Anda dapat menemukan link ke semua dari mereka pada halaman author saya.
Persyaratan Fitur Tweet Storm
Pertama, mari putuskan apa yang kita perlukan dari fitur TweetStorm kami.
- Buat grup tweets.
- Beri nomor secara berurutan.
- Mempublikasikan mereka secara berurutan di Twitter.
- Berikan halaman web publik yang memungkinkan orang untuk membacanya bersama.
- Publikasikan tautan ke halaman ini dalam tweet terakhir.
Hasil akan terlihat seperti ini:



Saya berasumsi bahwa Anda sudah familiar dengan tutorial Birdcage sebelumnya dan sudah memiliki kode yang mengautentikasi akun Anda melalui OAuth dengan API Twitter.
Database Model
Birdcage menggunakan tabel Status untuk tweet. Pertama, kita akan memperluas tabel ini dengan migrasi Yii ActiveRecord untuk memasukkan bidang untuk tweet_id yang diterbitkan dan urutan numerik tweet storm.
Memperluas model database kami yang sudah ada cukup mudah dengan migrasi ActiveRecord Yii:
1 |
./app/protected/yiic migrate create extend_status_table |
Ini kode migrasi:
1 |
<?php
|
2 |
|
3 |
class m141020_182509_extend_status_table_for_groups extends CDbMigration |
4 |
{
|
5 |
protected $MySqlOptions = 'ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_unicode_ci'; |
6 |
public $tablePrefix; |
7 |
public $tableName; |
8 |
|
9 |
public function before() { |
10 |
$this->tablePrefix = Yii::app()->getDb()->tablePrefix; |
11 |
if ($this->tablePrefix <> '') |
12 |
$this->tableName = $this->tablePrefix.'status'; |
13 |
}
|
14 |
|
15 |
public function safeUp() |
16 |
{
|
17 |
$this->before(); |
18 |
$this->addColumn($this->tableName,'tweet_id','BIGINT(20) DEFAULT 0'); |
19 |
$this->addColumn($this->tableName,'sequence','TINYINT DEFAULT 0'); |
20 |
$this->addColumn($this->tableName,'error_code','INTEGER DEFAULT 0'); |
21 |
}
|
22 |
|
23 |
public function safeDown() |
24 |
{
|
25 |
$this->before(); |
26 |
$this->dropColumn($this->tableName,'tweet_id'); |
27 |
$this->dropColumn($this->tableName,'sequence'); |
28 |
$this->dropColumn($this->tableName,'error_code'); |
29 |
}
|
30 |
|
31 |
}
|
Kami akan menggunakan tweet_ids untuk menampilkan secara umum seluruh badai tweet pada halaman web setelah publikasi. Urutan numerik akan menentukan urutan status tweet dalam badai kita.
Selanjutnya, kita perlu membuat tabel untuk penampung status tweet, pada dasarnya sebuah wadah untuk tweet storm. Saya akan menggunakan istilah Group, karena kami akan menggunakannya kembali untuk fitur pengelompokan lain dalam tutorial tindak lanjut, tweet berulang dari dalam grup. Kunjungi halaman author saya untuk melihat kapan keluar atau ikuti saya di Twitter @reifman.
Mari kita membuat migrasi baru untuk membuat tabel Group:
1 |
./app/protected/yiic migrate create create_group_table |
Kode di bawah ini membangun skema. Perhatikan hubungan foreign key untuk menghubungkan tweet storm ke akun Twitter tertentu:
1 |
<?php
|
2 |
|
3 |
class m141018_004954_create_group_table extends CDbMigration |
4 |
{
|
5 |
protected $MySqlOptions = 'ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_unicode_ci'; |
6 |
public $tablePrefix; |
7 |
public $tableName; |
8 |
|
9 |
public function before() { |
10 |
$this->tablePrefix = Yii::app()->getDb()->tablePrefix; |
11 |
if ($this->tablePrefix <> '') |
12 |
$this->tableName = $this->tablePrefix.'group'; |
13 |
}
|
14 |
|
15 |
public function safeUp() |
16 |
{
|
17 |
$this->before(); |
18 |
$this->createTable($this->tableName, array( |
19 |
'id' => 'pk', |
20 |
'account_id'=>'integer default 0', |
21 |
'name'=>'string default NULL', |
22 |
'slug'=>'string default NULL', |
23 |
'group_type'=>'tinyint default 0', |
24 |
'stage'=>'integer default 0', |
25 |
'created_at' => 'DATETIME NOT NULL DEFAULT 0', |
26 |
'modified_at' => 'TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP', |
27 |
), $this->MySqlOptions); |
28 |
$this->addForeignKey('fk_group_account', $this->tableName, 'account_id', $this->tablePrefix.'account', 'id', 'CASCADE', 'CASCADE'); |
29 |
}
|
30 |
|
31 |
public function safeDown() |
32 |
{
|
33 |
$this->before(); |
34 |
$this->dropForeignKey('fk_group_account', $this->tableName); |
35 |
$this->dropTable($this->tableName); |
36 |
}
|
37 |
}
|
Kami juga akan membangun tabel relasional yang disebut GroupStatus
yang melacak tweet Status dalam setiap Grup:
1 |
<?php
|
2 |
|
3 |
class m141018_020428_create_group_status_table extends CDbMigration |
4 |
{
|
5 |
protected $MySqlOptions = 'ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_unicode_ci'; |
6 |
public $tablePrefix; |
7 |
public $tableName; |
8 |
|
9 |
public function before() { |
10 |
$this->tablePrefix = Yii::app()->getDb()->tablePrefix; |
11 |
if ($this->tablePrefix <> '') |
12 |
$this->tableName = $this->tablePrefix.'group_status'; |
13 |
}
|
14 |
|
15 |
public function safeUp() |
16 |
{
|
17 |
$this->before(); |
18 |
$this->createTable($this->tableName, array( |
19 |
'id' => 'pk', |
20 |
'group_id' => 'INTEGER NOT NULL', |
21 |
'status_id' => 'INTEGER default 0', |
22 |
), $this->MySqlOptions); |
23 |
$this->addForeignKey('fk_group_status_group', $this->tableName, 'group_id', $this->tablePrefix.'group', 'id', 'CASCADE', 'CASCADE'); |
24 |
$this->addForeignKey('fk_group_status_status', $this->tableName, 'status_id', $this->tablePrefix.'status', 'id', 'CASCADE', 'CASCADE'); |
25 |
}
|
26 |
|
27 |
public function safeDown() |
28 |
{
|
29 |
$this->before(); |
30 |
$this->dropForeignKey('fk_group_status_group', $this->tableName); |
31 |
$this->dropForeignKey('fk_group_status_status', $this->tableName); |
32 |
$this->dropTable($this->tableName); |
33 |
}
|
34 |
}
|
Untuk menampilkan secara publik tweet storm di halaman web, kita sebenarnya membutuhkan tabel lain untuk menyimpan kode HTML dengan twitter_id dari metode Oembed API Twitter:
1 |
<?php
|
2 |
|
3 |
class m141021_203519_create_embed_table extends CDbMigration |
4 |
{
|
5 |
protected $MySqlOptions = 'ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_unicode_ci'; |
6 |
public $tablePrefix; |
7 |
public $tableName; |
8 |
|
9 |
public function before() { |
10 |
$this->tablePrefix = Yii::app()->getDb()->tablePrefix; |
11 |
if ($this->tablePrefix <> '') |
12 |
$this->tableName = $this->tablePrefix.'embed'; |
13 |
}
|
14 |
|
15 |
public function safeUp() |
16 |
{
|
17 |
$this->before(); |
18 |
$this->createTable($this->tableName, array( |
19 |
'id' => 'pk', |
20 |
'tweet_id' => 'bigint(20) unsigned NOT NULL', |
21 |
'html' => 'text default null', |
22 |
'created_at' => 'DATETIME NOT NULL DEFAULT 0', |
23 |
'modified_at' => 'TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP', |
24 |
), $this->MySqlOptions); |
25 |
$this->createIndex('tweet_id', $this->tableName , 'tweet_id', false); |
26 |
}
|
27 |
|
28 |
public function safeDown() |
29 |
{
|
30 |
$this->before(); |
31 |
$this->dropIndex('tweet_id', $this->tableName); |
32 |
$this->dropTable($this->tableName); |
33 |
}
|
34 |
}
|
Membangun Kode
Kontroler dan Model Grup
Selanjutnya, kita akan menggunakan Yii's scaffolding kode generator, Gii untuk membangun model, controller dan CRUD. Lingkungan lokal saya, saya mengunjungi http://localhost:8888/twitter/app/gii untuk mengakses Gii. Pertama, saya membuat model:



Kemudian, Saya pengguna generator Bootstrap CRUD:



Kami juga akan menggunakan Gii untuk membuat default model untuk tabel GroupStatus dan Embed. Mereka tidak perlu controller dan view.
Di navigation bar view (/ app/protected/views/layouts/main.php
), saya akan menambahkan pilihan dalam menu Compose saya ke Group Tweets:
1 |
array('label'=>'Compose', 'items'=> array( |
2 |
array('url'=>array('/status/compose'), 'label'=>'Schedule a tweet'), |
3 |
array('url'=>array('/group'), 'label'=>'Group tweets'), |
4 |
array('url'=>array('/status/admin'), 'label'=>'Manage schedule'), |
5 |
array('url'=>array('/statuslog/admin'), 'label'=>'Review log'), |
6 |
)),
|
Halaman Pengelolaan Tweets Grup terlihat seperti ini:



Mengklik ikon paling kiri dalam setiap baris membuka grup untuk menambahkan tweets untuk dan pengurutan mereka.
Mengeklik tautan menambahkan tautan grup akan memunculkan formulir yang memungkinkan Anda menamai badai Tweet dan memilih akun Twitter untuknya:



Kita perlu memperluas default pembuatan behaviour untuk menyelesaikan model. Saya menggunakan kembali metode Slugify saya dari Geogram untuk membuat slug mirip URL dari namanya. Tambahkan ini ke Group.php
:
1 |
/**
|
2 |
* Modifies a string to remove all non ASCII characters and spaces.
|
3 |
*/
|
4 |
public function slugify($text) |
5 |
{
|
6 |
//sourcecookbook.com/en/recipes/8/function-to-slugify-strings-in-php
|
7 |
// replace non letter or digits by -
|
8 |
$text = preg_replace('~[^\\pL\d]+~u', '-', $text); |
9 |
// trim
|
10 |
$text = trim($text, '-'); |
11 |
// transliterate
|
12 |
if (function_exists('iconv')) |
13 |
{
|
14 |
$text = iconv('utf-8', 'us-ascii//TRANSLIT', $text); |
15 |
}
|
16 |
// lowercase
|
17 |
$text = strtolower($text); |
18 |
// remove unwanted characters
|
19 |
$text = preg_replace('~[^-\w]+~', '', $text); |
20 |
if (empty($text)) |
21 |
{
|
22 |
return 'error-generating-slug'; |
23 |
}
|
24 |
return $text; |
25 |
}
|
Berikut adalah actionCreate
diubah dalam GroupController.php
:
1 |
public function actionCreate() |
2 |
{
|
3 |
$model=new Group; |
4 |
// Uncomment the following line if AJAX validation is needed
|
5 |
// $this->performAjaxValidation($model);
|
6 |
if(isset($_POST['Group'])) |
7 |
{
|
8 |
$model->attributes=$_POST['Group']; |
9 |
$model->slug=Group::model()->slugify($model->name); |
10 |
$model->created_at = new CDbExpression('NOW()'); |
11 |
$model->modified_at =new CDbExpression('NOW()'); |
12 |
if($model->save()) |
13 |
$this->redirect(array('view','id'=>$model->id)); |
14 |
}
|
15 |
$this->render('create',array( |
16 |
'model'=>$model, |
17 |
));
|
18 |
}
|
Menambahkan Tweets ke Storm
Anda kemudian menambahkan tweet status untuk storm Anda dan pilih urutan numerik yang akan muncul:



Kami menggunakan bentuk turunan dari formulir komposisi status dari Birdcage:
1 |
<?php
|
2 |
$this->breadcrumbs=array( |
3 |
'Statuses'=>array('index'), |
4 |
'Create', |
5 |
);
|
6 |
|
7 |
/*
|
8 |
$this->menu=array(
|
9 |
array('label'=>'Manage schedule','url'=>array('admin')),
|
10 |
array('label'=>'Review log','url'=>array('statuslog/admin')),
|
11 |
);
|
12 |
*/
|
13 |
?>
|
14 |
|
15 |
<h1>Compose a Tweet for your Group</h1> |
16 |
<?php
|
17 |
echo $this->renderPartial('_groupform', array('model'=>$model,'maxCount'=>$maxCount)); ?> |
Berikut adalah file view _groupform.php
:
1 |
<?php
|
2 |
|
3 |
$baseUrl = Yii::app()->baseUrl; |
4 |
$cs = Yii::app()->getClientScript(); |
5 |
$cs->registerScriptFile($baseUrl.'/js/jquery.simplyCountable.js'); |
6 |
$cs->registerScriptFile($baseUrl.'/js/twitter-text.js'); |
7 |
$cs->registerScriptFile($baseUrl.'/js/twitter_count.js'); |
8 |
|
9 |
?>
|
10 |
<?php $form=$this->beginWidget('bootstrap.widgets.TbActiveForm',array( |
11 |
'id'=>'status-form', |
12 |
'enableAjaxValidation'=>false, |
13 |
)); ?> |
14 |
|
15 |
<?php
|
16 |
if(Yii::app()->user->hasFlash('no_account') |
17 |
) { |
18 |
$this->widget('bootstrap.widgets.TbAlert', array( |
19 |
'alerts'=>array( // configurations per alert type |
20 |
'no_account'=>array('block'=>true, 'fade'=>true, 'closeText'=>'×'), |
21 |
),
|
22 |
));
|
23 |
}
|
24 |
?>
|
25 |
|
26 |
<p class="help-block">Fields with <span class="required">*</span> are required.</p> |
27 |
|
28 |
<?php echo $form->errorSummary($model); ?> |
29 |
|
30 |
<?php echo $form->hiddenField($model,'account_id',array('value'=>$model->account_id)); ?> |
31 |
<br /> |
32 |
<?php
|
33 |
echo $form->textAreaRow($model,'tweet_text',array('id'=>'tweet_text','rows'=>6, 'cols'=>50, 'class'=>'span8')); |
34 |
?>
|
35 |
<p class="right">Remaining: <span id="counter2">0</span></p> |
36 |
|
37 |
<?php
|
38 |
echo CHtml::activeLabel($model,'sequence',array('label'=>'Sequence:')); |
39 |
?>
|
40 |
|
41 |
<?php echo $form->dropDownList($model,'sequence', $model->getSequence()); ?> |
42 |
|
43 |
|
44 |
</div> <!-- end section method --> |
45 |
<div class="form-actions"> |
46 |
<?php $this->widget('bootstrap.widgets.TbButton', array( |
47 |
'buttonType'=>'submit', |
48 |
'type'=>'primary', |
49 |
'label'=>$model->isNewRecord ? 'Create' : 'Save', |
50 |
)); ?> |
51 |
</div>
|
52 |
|
53 |
<?php $this->endWidget(); ?> |
54 |
<script type="text/javascript" charset="utf-8"> |
55 |
$(document).ready(function() |
56 |
{
|
57 |
$('#section_schedule').hide(); |
58 |
$('#section_method').hide(); |
59 |
$('#tweet_text').simplyCountable({ |
60 |
counter: '#counter2', |
61 |
maxCount: <?php echo $maxCount ?>, |
62 |
countDirection: 'down' |
63 |
});
|
64 |
});
|
65 |
|
66 |
</script>
|
Berikut adalah metode getSequence
menggunakan form, dari Status.php
:
1 |
public function getSequence() { |
2 |
$i=1; |
3 |
$seq = array('default'=>'select sequence below'); |
4 |
while ($i<=99) { |
5 |
$seq[$i]=$i; |
6 |
$i++; |
7 |
}
|
8 |
return $seq; |
9 |
}
|
Tweet status dalam grup adalah empat karakter yang lebih pendek dari 140 untuk memungkinkan penyisipan penomoran urutan.
Saat Anda menambahkan tweet status ke grup Anda, halaman Kelola Grup akan terlihat seperti ini:



Penyempurnaan di masa mendatang mungkin termasuk kontrol urutan naik/turun untuk item status serta beberapa penomoran otomatis saat Anda menambahkan tweet baru.
Mempublikasikan Storm
Meskipun Anda hanya dapat mempublikasikan tweets secara berurutan, sangat membantu untuk mengelola ini dalam proses latar belakang untuk ketahanan, jika ada kegagalan di tengah jalan.
Karena banyak fungsi Twitter API membutuhkan cursoring atau paging, saya sudah membangun model proses latar belakang ke dalam framework lanjutan saya, Birdhouse. Saya akan menunjukkan dasar-dasar menambahkan penerbitan badai tweet ke aplikasi Anda.
Ketika Anda klik Publish storm, kita membuat action untuk mengelola proses ini di latar belakang:
1 |
public function publish($group_id) { |
2 |
// create an action to publish the storm in the background
|
3 |
$gp = Group::model()->findByPK($group_id); |
4 |
$check_dup = Action::model()->findByAttributes(array('action'=>Action::ACTION_STORM,'item_id'=>$group_id,'status'=>Action::STATUS_ACTIVE)); |
5 |
if (empty($check_dup)) { |
6 |
$a = new Action; |
7 |
$a->account_id = $gp->account_id; |
8 |
$a->action = Action::ACTION_STORM; |
9 |
$a->status = Action::STATUS_ACTIVE; |
10 |
$a->item_id = $group_id; |
11 |
$a->created_at = new CDbExpression('NOW()'); |
12 |
$a->modified_at =new CDbExpression('NOW()'); |
13 |
$a->save(); |
14 |
}
|
15 |
}
|
Kemudian, tugas-tugas latar belakang cron normal mengelola tabel Action dan akan memanggil Action::model()->publishStorm
:
1 |
public function publishStorm($action) { |
2 |
// publish group twitter storm
|
3 |
$results = Group::model()->publishStormItems($action->account_id,$action->item_id); |
4 |
if ($results) { |
5 |
// if true, action is complete
|
6 |
$a = Action::model()->findByPk($action->id); |
7 |
$a->status=self::STATUS_COMPLETE; |
8 |
$a->save(); |
9 |
}
|
10 |
}
|
Ini pada gilirannya menyebut model grup ini publishStormItems
:
1 |
// publish the group as a twitter storm
|
2 |
public function publishStormItems($account_id,$group_id) { |
3 |
$error = false; |
4 |
$account = Account::model()->findByPK($account_id); |
5 |
// make the connection to Twitter
|
6 |
$twitter = Yii::app()->twitter->getTwitterTokened($account['oauth_token'], $account['oauth_token_secret']); |
7 |
// get unpublished statuses in specific group
|
8 |
$statuses = Status::model()->in_account($account_id)->stage_zero()->in_specific_group($group_id)->findAll(array('order'=>'sequence ASC')); |
9 |
$tweet_id = 0; |
10 |
foreach ($statuses as $status) { |
11 |
$prefix = $status->sequence.'. '; |
12 |
// add sequence count as prefix
|
13 |
echo $prefix.$status->tweet_text;lb(); |
14 |
$tweet_id = Status::model()->postTweet($twitter,$status,$prefix); |
15 |
if ($tweet_id!=0) { |
16 |
// update stage to published = 1
|
17 |
$ns = Yii::app()->db->createCommand()->update(Yii::app()->getDb()->tablePrefix.'status',array('stage'=>1,'tweet_id'=>$tweet_id),'id=:id', array(':id'=>$status->id)); |
18 |
} else { |
19 |
$error = true; |
20 |
}
|
21 |
}
|
22 |
// if finishing up
|
23 |
if (count($statuses)>0 and !$error) { |
24 |
// publish final tweet with link to the storm
|
25 |
$group = Group::model()->findByPk($group_id); |
26 |
$status = 'Read or share my tweet storm on '.$group->name.' in its entirety here: '.$_SERVER["SERVER_NAME"].'/storm/'.$group->slug; |
27 |
if (strlen($status)>120) { |
28 |
$status = 'Read or share all of my tweet storm: '.$_SERVER["SERVER_NAME"].'/storm/'.$group->slug; |
29 |
}
|
30 |
$tweet= $twitter->post("statuses/update",array('status'=>$status)); |
31 |
}
|
32 |
// if done, return true
|
33 |
return !$error; |
34 |
}
|
Queri ActiveRecord yang kami gunakan untuk menemukan status tweet dalam grup yang tidak dipublikasikan adalah sebagai berikut:
1 |
$statuses = Status::model()->in_account($account_id)->stage_zero()->in_specific_group($group_id)->findAll(array('order'=>'sequence ASC')); |
Query ini menggunakan scopes yang didefinisikan sebagai berikut dalam model Status:
1 |
public function scopes() |
2 |
{
|
3 |
return array( |
4 |
// part of a group of tweets
|
5 |
'in_group'=>array( |
6 |
'condition'=>'status_type='.self::STATUS_TYPE_IN_GROUP, |
7 |
),
|
8 |
'stage_zero'=>array( |
9 |
'condition'=>'stage=0', |
10 |
),
|
11 |
'has_tweet_id'=>array( |
12 |
'condition'=>'tweet_id<>0', |
13 |
),
|
14 |
);
|
15 |
}
|
16 |
|
17 |
public function in_specific_group($group_id) |
18 |
{
|
19 |
$crit = $this->getDbCriteria(); |
20 |
$crit->addCondition(" |
21 |
id IN (
|
22 |
SELECT status_id FROM tw_group_status
|
23 |
WHERE
|
24 |
group_id = :group_id
|
25 |
)
|
26 |
"); |
27 |
$crit->params[':group_id'] = $group_id; |
28 |
return $this; |
29 |
}
|
30 |
|
31 |
// custom scopes
|
32 |
public function in_account($account_id=0) |
33 |
{
|
34 |
$this->getDbCriteria()->mergeWith( array( |
35 |
'condition'=>'account_id='.$account_id, |
36 |
));
|
37 |
return $this; |
38 |
}
|
Saat kami mengulang setiap status yang perlu di-tweet, kami menambahkan awalan untuk nomor urut misal. '1. Tweet pertama saya adalah ...':
1 |
foreach ($statuses as $status) { |
2 |
$prefix = $status->sequence.'. '; |
3 |
// add sequence count as prefix
|
4 |
echo $prefix.$status->tweet_text;lb(); |
5 |
$tweet_id = Status::model()->postTweet($twitter,$status,$prefix); |
6 |
if ($tweet_id!=0) { |
7 |
// update stage to published = 1
|
8 |
$ns = Yii::app()->db->createCommand()->update(Yii::app()->getDb()->tablePrefix.'status',array('stage'=>1,'tweet_id'=>$tweet_id),'id=:id', array(':id'=>$status->id)); |
9 |
} else { |
10 |
$error = true; |
11 |
}
|
12 |
}
|
Ketika status diposting, panggung bertambah. Penyempurnaan masa depan dapat mencakup memungkinkan tweet storm untuk diposkan ulang beberapa kali. Saat ini, kami hanya mengizinkan satu posting (Anda dipersilakan, Buzzfeed).
Jika semua tweet berhasil diposting, kami memposting tweet terakhir dengan tautan ke tweet storm:
1 |
// if finishing up
|
2 |
if (count($statuses)>0 and !$error) { |
3 |
// publish final tweet with link to the storm
|
4 |
$group = Group::model()->findByPk($group_id); |
5 |
$status = 'Read or share my tweet storm on '.$group->name.' in its entirety here: '.$_SERVER["SERVER_NAME"].'/storm/'.$group->slug; |
6 |
if (strlen($status)>130) { |
7 |
$status = 'Read or share all of my tweet storm: '.$_SERVER["SERVER_NAME"].'/storm/'.$group->slug; |
8 |
}
|
9 |
$tweet= $twitter->post("statuses/update",array('status'=>$status)); |
10 |
}
|
Inilah tampilan Tweet Storm ketika dipublikasikan:



Melihat Storm di Web
Jadi, sementara kami dapat menampilkan Tweet Sorm secara publik di web dalam bentuk teks seperti Yvo Schaap, saya pikir akan lebih baik menggunakan embeddings Twitter yang dapat digunakan pengguna untuk berinteraksi dengan mis. follow, reply, retweet dll.



Awalnya, saya pikir saya mungkin bisa menggunakan kode HTML statis dan hanya mengganti twitter_id dalam view, tetapi Twitter lebih suka Anda membuat panggilan OEmbed dan menyimpan HTML untuk setiap tweet. Saya membuat tabel Sematan di atas untuk melakukan ini.
Jadi, pertama, mari buat rute di UrlManager milik Yii sehingga jalur aplikasi kami dapat mengalihkan ke view tweetstorms dendan slug yang URL-friendly. Di /app/protected/config/main.php
, tambahkan pengalihan slug storm di bawah ini. Itu akan mengarahkan queri ke http://yourdomain/storm/my-thoughts-on-twitters-api untuk tindakan pengontrol Group Controller dengan my-thoughts-on-twitters-api sebagai parameter:
1 |
'urlManager'=>array( |
2 |
'urlFormat'=>'path', |
3 |
'showScriptName'=>false, |
4 |
'caseSensitive'=>false, |
5 |
'rules'=>array( |
6 |
'<controller:\w+>/<id:\d+>'=>'<controller>/view', |
7 |
'<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>', |
8 |
'<controller:\w+>/<action:\w+>'=>'<controller>/<action>', |
9 |
'/hybridauth' => '/hybridauth', |
10 |
'/storm/<slug>' => '/group/lookup/', |
11 |
'' => 'site/index' |
12 |
), |
13 |
), |
Menggunakan filter akses pengontrol Yii, mari kita membuatnya sehingga setiap pengunjung publik dapat melihat badai tetapi tindakan CRUD hanya terlihat oleh pengguna yang diautentikasi. Ubah accessRules
di GroupController.php
sebagai berikut:
1 |
public function accessRules() |
2 |
{ |
3 |
return array( |
4 |
array('allow', // allow all users to perform 'storm' |
5 |
'actions'=>array('lookup'), |
6 |
'users'=>array('*'), |
7 |
), |
8 |
array('allow', // allow authenticated user to perform these actions |
9 |
'actions'=>array('index','view','create','update','delete'), |
10 |
'users'=>array('@'), |
11 |
), |
12 |
array('allow', // allow admin user to perform 'admin' actions |
13 |
'actions'=>array(''), |
14 |
'users'=>array('admin'), |
15 |
), |
16 |
array('deny', // deny all users |
17 |
'users'=>array('*'), |
18 |
), |
19 |
); |
20 |
} |
Saat request tiba untuk http://yourdomain.com/storm/your-storm-name Anda, ia akan mengarahkan ke action pengontrol Group controller:
1 |
public function actionLookup($slug) { |
2 |
$success = false; |
3 |
$this->layout = 'storm'; |
4 |
// try look up by slug
|
5 |
$group = Group::model()->findByAttributes(array('slug'=>$slug)); |
6 |
$embeds = Group::model()->fetchEmbeds($group->id); |
7 |
if ($group !== null) { |
8 |
$success = true; |
9 |
$this->render('lookup',array( |
10 |
'embeds'=>$embeds, |
11 |
'name'=>$group->name, |
12 |
));
|
13 |
}
|
14 |
}
|
Metode fetchEmbeds
terlihat pertama dalam database kami untuk salinan cache dan kemudian secara lahiriah Twitter API untuk mengambil HTML. Metode fetchEmbeds
membangun sebuah array dari HTML tweets:
1 |
public function fetchEmbeds($group_id) { |
2 |
$e = new Embed(); |
3 |
$group = Group::model()->findByPk($group_id); |
4 |
$embed =array(); |
5 |
$statuses = Status::model()->in_account($group->account_id)->has_tweet_id()->in_specific_group($group_id)->findAll(array('order'=>'sequence ASC')); |
6 |
foreach ($statuses as $status) { |
7 |
$embed[]=$e->fetch($group->account_id, $status->tweet_id); |
8 |
}
|
9 |
return $embed; |
10 |
}
|
Ia menggunakan metode pengambilan model Embed:
1 |
public function fetch($account_id,$tweet_id) { |
2 |
// is it in embed table
|
3 |
$data = Embed::model()->findByAttributes(array('tweet_id'=>$tweet_id)); |
4 |
if (empty($data)) { |
5 |
// is there a connection
|
6 |
if (is_null($this->twitter)) { |
7 |
$account = Account::model()->findByPK($account_id); |
8 |
// make the connection to Twitter
|
9 |
$this->twitter = Yii::app()->twitter->getTwitterTokened($account['oauth_token'], $account['oauth_token_secret']); |
10 |
}
|
11 |
$result= $this->twitter->get("statuses/oembed",array('id'=>$tweet_id)); |
12 |
$html = $result->html; |
13 |
$this->add($tweet_id,$html); |
14 |
} else { |
15 |
$html = $data->html; |
16 |
}
|
17 |
return $html; |
18 |
}
|
19 |
|
20 |
public function add($tweet_id,$html) { |
21 |
$e = new Embed(); |
22 |
$e->html = $html; |
23 |
$e->tweet_id=$tweet_id; |
24 |
$e->modified_at = new CDbExpression('NOW()'); |
25 |
$e->created_at = new CDbExpression('NOW()'); |
26 |
$e->save(); |
27 |
}
|
Ini hanya menginisiasi koneksi OAuth ke Twitter jika setidaknya ada satu tweet_id yang perlu diambil, dan itu hanya satu kali untuk alasan kinerja.
Penutup
Saya harap Anda menemukan tutorial tweet storm ini berguna. Itu pasti fitur yang menyenangkan untuk dibangun. Silakan poskan koreksi, pertanyaan, atau komentar di bawah ini. Saya mencoba untuk mengikuti comment threads Tuts +. Anda juga dapat menghubungi saya di Twitter @reifman atau mengirim email kepada saya secara langsung.
Anda dapat menemukan tutorial Twitter API awal untuk Birdcage di sini, dan tautan ke semua tutorial Twitter API saya di halaman penulis Tuts + saya saat diterbitkan. Birdcage menawarkan repositori Github gratis dan open source untuk memulai dengan fitur dasar Twitter API.