Railsを使って実装している、Twilio Dosにあるチュートリアル Appointment Reminder と同じアプリケーションをFuelPHPで実装してみます。

TwilioのAPIを呼び出すライブラリは、Twilio APIライブラリ – PHP, C#, Python, Java, RubyのPHPのところにも載っている Fuel-Twilio というFuelPHPパッケージを利用します。
Github: fuel-packages/fuel-twilio

FuelPHPプロジェクトを作成した後、まずは、fuel-twilioパッケージをセットアップしていきます。

[Download ZIP]からパッケージを落として fuel/packages にコピーします。

$ mv ~/Downloads/fuel-twilio-master.zip fuel/packages/
$ cd fuel/packages
$ unzip fuel-twilio-master.zip 
$ mv fuel-twilio-master fuel-twilio

always_loadにfuel-twilioパッケージを指定

	'always_load'  => array(
		...
		'packages'  => array(
		 	//'orm',
			'fuel-twilio',
		),
		...
	),

次に、fuel/packages/fuel-twilio/config/twilio.php を fuel/app/configにコピーしてアクセスキーなどを設定します。

$ cp fuel/packages/fuel-twilio/config/twilio.php fuel/app/config/
    'account_sid' => 'XXXXX',
    'auth_token' => 'YYYYY',
    'from' => '+815011112222',

ACCOUNT SIDとAUTH TOKENは、Twilioのダッシュボードで確認できます。
fromには、発信元の電話番号を指定します。

補足:
fuel-twilioはTwilioへのhttpリクエストにPHP cURLを使います。
インストールされていない場合は、インストールしておきます。
UbuntuなどAPT利用時のコマンド

$ sudo apt-get install php5-curl
$ sudo service apache2 reload

fuel-twilioパッケージのセットアップは以上です。

以降、Appointment Reminderを実装して行きます。

homeコントローラを作成して、必要なアクションを追加します。

$ oil g controller home index makecall reminder directions goodbye
	Creating view: /path/to/fuel/app/views/template.php
	Creating view: /path/to/fuel/app/views/home/index.php
	Creating view: /path/to/fuel/app/views/home/makecall.php
	Creating view: /path/to/fuel/app/views/home/reminder.php
	Creating view: /path/to/fuel/app/views/home/directions.php
	Creating view: /path/to/fuel/app/views/home/goodbye.php
	Creating controller: /path/to/fuel/app/classes/controller/home.php

Viewが必要なのはindexだけなので、それ以外のビューは削除しておきます。

$ rm fuel/app/views/home/makecall.php
$ rm fuel/app/views/home/reminder.php
$ rm fuel/app/views/home/directions.php
$ rm fuel/app/views/home/goodbye.php

Twilioからのリクエストの応答は、Twilio::twimlを利用してXMLを生成するので、Controller_Restを継承したコントローラに分けることはせずController_Homeですべて実装しています。

ルートへのアクセスをすべてHomeControllerのアクションにルーティングします。

<?php
return array(
	'_root_'  => 'home/index',  // The default route
	'(:segment)' => 'home/$1',
);

参照: やや高度なルーティング – FuelPHP Documentation

次に、各アクションを実装していきます。

1. index ページ

Appointment Reminderのhowtos/appointmentreminder/index.html.erbをFuelPHPのindex.phpに実装します。
Flashメッセージは、template.phpのコードを利用できるので省略します。

<h1>Twilio phone reminder demo</h1>
<h3>Enter your phone number to receive an automated reminder</h3>
<?php echo Form::open(array('action' => 'makecall')) ?>
    <?php echo Form::input('number'); ?>
    <?php echo Form::submit('Call me!'); ?>
<?php echo Form::close(); ?>

homeコントローラのindexアクションはそのまま利用します。

2. makecall アクション

元のサンプルのhowtos/appointmentreminder/appointmentreminder_controller.rbのmakecallアクションをFuelPHPのhomeコントローラのmakecallアクションとして実装します。

	public function action_makecall()
	{
		if (!Input::post('number'))
		{
			Session::set_flash('error', 'Invalid phone number');
			Response::redirect('/');
		}

		$call = Twilio\Twilio::request('MakeCall');
		try
		{
			$response = $call->create(array(
				'To' => Input::post('number'),
				'From' => '+815011112222',
				'Url' => Uri::create(Uri::base(false). "reminder"),
			));
			
			if ($response->status !== 'queued')
                        {
                                Session::set_flash('error', $response->message);
                                Response::redirect('/');
                        }
		}
		catch (Exception $e)
		{
			Session::set_flash('error', $e->getMessage());
			Response::redirect('/');
		}

		Session::set_flash('success', 'Calling '.Input::post('number').'...');
		Response::redirect('/');
	}

ハイライト箇所がTwilioから電話をかけるコードです。
他はエラーハンドリングになります。

3. reminderアクション

howtos/appointmentreminder/appointmentreminder_controller.rbのreminderアクション
howtos/appointmentreminder/reminder.xml.builderビュー
をFuelPHP homeコントローラのreminderアクションに実装します。

	public function action_reminder()
	{
		$question = new Twilio\Twilio_Twiml();
		$question->say('こんにちはこの電話はTwilioから発信しています。明日の午前9時からアポイントメントがあります。', array('language' => 'ja-jp'));
		$question->say('このメニューを繰り返す場合は1を、順路を聞く場合は2を、終了する場合は3をプッシュしてください。', array('language' => 'ja-jp'));
		$twiml = Twilio\Twilio::twiml();
		$twiml->gather(
			$question,
			array(
				'action' => Uri::create(Uri::base(false). "directions"),
				'method' => 'GET',
				'numDigits' => 1,
			)
		);

		$response = Response::forge($twiml->render());
                $response->set_header('Content-type', 'text/xml; charset=utf-8');
		return $twiml->render();
	}

元のサンプルではレスポンスのXMLをビューで構築していますが、fuel-twilioにはTwilio\Twilio_Twimlクラスが用意されているので、アクション内で応答を構築して返しています。
メッセージは、日本語にしています。日本語の場合は、Sayの属性languageja-jpを指定します。
Gatherの使い方は、Grabbing key presses during a call を参考にしました。

4. directionsアクション

howtos/appointmentreminder/appointmentreminder_controller.rbのdirectionsアクションとhowtos/appointmentreminder/directions.xml.builderをhomeコントローラのdirectionsアクションに実装します。

	public function action_directions()
	{
		if (Input::get('Digits') == 3)
		{
			Response::redirect('goodbye');
		}

		else if (Input::get('Digits') == 1)
		{
			Response::redirect('reminder');
		}

		$twiml = new Twilio\Twilio_Twiml();
		$twiml->say('アポイントメントは通り近くの建物で行われます。', array('language' => 'ja-jp'));
		$twiml->redirect(Uri::create(Uri::base(false). "reminder"));

		$response = Response::forge($twiml->render());
		$response->set_header('Content-type', 'text/xml; charset=utf-8');
		return $response;
	}

5. goodbyeアクション

goodbyeは元記事には載ってせんが以下のように実装しました。

	public function action_goodbye()
	{
		$twiml = new Twilio\Twilio_Twiml();
		$twiml->say('さようなら。', array('language' => 'ja-jp'));

		$response = Response::forge($twiml->render());
		$response->set_header('Content-type', 'text/xml; charset=utf-8');
		return $response;
	}

以上で、Railsのチュートリアル Appointment Reminder と同じ動作のアプリケーションをFuelPHPできました。