Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

change Readme.md #317

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Open
5 changes: 5 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,8 @@ TWILIO_AUTH_TOKEN=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
# Twilio phone number
# Purchase one at https://www.twilio.com/user/account/phone-numbers
TWILIO_NUMBER=+15552737123

# You need to create a TwiML app to use this project.
# Create one at https://www.twilio.com/user/account/apps/add,
# then use its "Sid" value here
TWILIO_APPLICATION_SID=APXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
158 changes: 143 additions & 15 deletions app/Http/Controllers/ReservationController.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,36 @@
use App\User;
use App\VacationProperty;
use DB;
use Services_Twilio as TwilioRestClient;
use Services_Twilio_Twiml as TwilioTwiml;
use Twilio\Rest\Client;
use Twilio\Twiml;
use Log;

class ReservationController extends Controller
{
public function index(Authenticatable $user)
{
$reservations = array();

foreach ($user->propertyReservations as $reservation)
{
array_push($reservations, $reservation->fresh());
}
return view(
'reservation.index',
[
'hostReservations' => $reservations,
'guestReservations' => $user->reservations
]
);
}

/**
* Store a new reservation
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function create(TwilioRestClient $client, Request $request, Authenticatable $user, $id)
public function create(Client $client, Request $request, Authenticatable $user, $id)
{
$this->validate(
$request, [
Expand All @@ -28,8 +46,8 @@ public function create(TwilioRestClient $client, Request $request, Authenticatab
);
$property = VacationProperty::find($id);
$reservation = new Reservation($request->all());
$reservation->respond_phone_number = $user->fullNumber();
$reservation->user()->associate($property->user);

$reservation->user()->associate($user);

$property->reservations()->save($reservation);

Expand All @@ -39,23 +57,26 @@ public function create(TwilioRestClient $client, Request $request, Authenticatab
'status',
"Sending your reservation request now."
);
return redirect()->route('property-show', ['id' => $property->id]);
return redirect()->route('reservation-index', ['id' => $property->id]);
}

public function acceptReject(Request $request)
public function acceptReject(Client $client, Request $request)
{
$hostNumber = $request->input('From');
$smsInput = strtolower($request->input('Body'));
$host = User::where(DB::raw("CONCAT('+',country_code::text, phone_number::text)"), 'LIKE', "%".$hostNumber."%")
->get()
->first();
->get()
->first();

$reservation = $host->pendingReservations()->first();
$smsResponse = null;
if (!is_null($reservation))
{
$reservation = $reservation->fresh();

if (strpos($smsInput, 'yes') !== false || strpos($smsInput, 'accept') !== false)
{
$reservation->confirm();
$reservation->confirm($this->getNewTwilioNumber($client, $host));
}
else
{
Expand All @@ -72,16 +93,84 @@ public function acceptReject(Request $request)
return response($this->respond($smsResponse, $reservation))->header('Content-Type', 'application/xml');
}

public function connectSms(Request $request)
{
$twilioNumber = $request->input('To');
$incomingNumber = $request->input('From');
$messageBody = $request->input('Body');

$reservation = $this->getReservationFromNumber($twilioNumber);
$host = $reservation->property->user;
$guest = $reservation->user;

if ($incomingNumber === $host->fullNumber())
{
$outgoingNumber = $guest->fullNumber();
}
else
{
$outgoingNumber = $host->fullNumber();
}

return response($this->connectSmsResponse($messageBody, $outgoingNumber))->header('Content-Type', 'application/xml');
}

public function connectVoice(Request $request)
{
$twilioNumber = $request->input('To');
$incomingNumber = $request->input('From');

$reservation = $this->getReservationFromNumber($twilioNumber);
$host = $reservation->property->user;
$guest = $reservation->user;

if ($incomingNumber === $host->fullNumber())
{
$outgoingNumber = $guest->fullNumber();
}
else
{
$outgoingNumber = $host->fullNumber();
}

return response($this->connectVoiceResponse($outgoingNumber))->header('Content-Type', 'application/xml');
}

private function getReservationFromNumber($twilioNumber)
{
return Reservation::where('twilio_number', '=', $twilioNumber)->first();
}

private function connectVoiceResponse($outgoingNumber)
{
$response = new Twiml();
$response->play('http://howtodocs.s3.amazonaws.com/howdy-tng.mp3');
$response->dial($outgoingNumber);

return $response;
}

private function connectSmsResponse($messageBody, $outgoingNumber)
{
$response = new Twiml();
$response->message(
$messageBody,
['to' => $outgoingNumber]
);

return $response;
}

private function respond($smsResponse, $reservation)
{
$response = new TwilioTwiml;
$response = new Twiml();
$response->message($smsResponse);

if (!is_null($reservation))
{
$response->message(
'Your reservation has been ' . $reservation->status . '.',
['to' => $reservation->respond_phone_number]
['to' => $reservation->user->fullNumber()]
);
}
return $response;
Expand All @@ -93,14 +182,53 @@ private function notifyHost($client, $reservation)

$twilioNumber = config('services.twilio')['number'];

$messageBody = $reservation->message . ' - Reply \'yes\' or \'accept\' to confirm the reservation, or anything else to reject it.';

try {
$client->account->messages->sendMessage(
$twilioNumber, // From a Twilio number in your account
$client->messages->create(
$host->fullNumber(), // Text any number
$reservation->message
[
'from' => $twilioNumber, // From a Twilio number in your account
'body' => $messageBody
]
);
} catch (Exception $e) {
Log::error($e->getMessage());
}
}

private function getNewTwilioNumber($client, $host)
{
$numbers = $client->availablePhoneNumbers('US')->local->read(
[
'areaCode' => $host->areaCode(),
'voiceEnabled' => 'true',
"smsEnabled" => 'true'
]
);

if (empty($numbers)) {
$numbers = $client->availablePhoneNumbers('US')->local->read(
[
'voiceEnabled' => 'true',
"smsEnabled" => 'true'
]
);
}
$twilioNumber = $numbers[0]->phoneNumber;

$newNumber = $client->incomingPhoneNumbers->create(
[
"phoneNumber" => $twilioNumber,
"smsApplicationSid" => config('services.twilio')['applicationSid'],
"voiceApplicationSid" => config('services.twilio')['applicationSid']
]
);

if ($newNumber) {
return $twilioNumber;
} else {
return 0;
}
}
}
4 changes: 3 additions & 1 deletion app/Http/Middleware/VerifyCsrfToken.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ class VerifyCsrfToken extends BaseVerifier
* @var array
*/
protected $except = [
'reservation/incoming'
'reservation/incoming',
'reservation/connect_sms',
'reservation/connect_voice'
];
}
19 changes: 19 additions & 0 deletions app/Http/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,27 @@ function() {
'middleware' => 'auth']
);

Route::get(
'/reservations',
['as' => 'reservation-index',
'middleware' => 'auth',
'uses' => 'ReservationController@index']
);

Route::post(
'/reservation/incoming',
['uses' => 'ReservationController@acceptReject',
'as' => 'reservation-incoming']
);

Route::get(
'/reservation/connect_sms',
['uses' => 'ReservationController@connectSms',
'as' => 'reservation-connect-sms']
);

Route::get(
'/reservation/connect_voice',
['uses' => 'ReservationController@connectVoice',
'as' => 'reservation-connect-voice']
);
6 changes: 3 additions & 3 deletions app/Providers/TwilioRestClientProvider.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Services_Twilio;
use Twilio\Rest\Client;

class TwilioRestClientProvider extends ServiceProvider
{
Expand All @@ -13,10 +13,10 @@ class TwilioRestClientProvider extends ServiceProvider
public function register()
{
$this->app->bind(
'Services_Twilio', function ($app) {
Client::class, function ($app) {
$accountSid = config('services.twilio')['accountSid'];
$authToken = config('services.twilio')['authToken'];
return new Services_Twilio($accountSid, $authToken);
return new Client($accountSid, $authToken);
}
);
}
Expand Down
5 changes: 3 additions & 2 deletions app/Reservation.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,13 @@ public function property()
*/
public function user()
{
return $this->belongsTo('App\User');
return $this->belongsTo('App\User', 'user_id');
}

public function confirm()
public function confirm($twilioNumber)
{
$this->status = 'confirmed';
$this->twilio_number = $twilioNumber;
$this->save();
}

Expand Down
5 changes: 5 additions & 0 deletions app/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,9 @@ public function fullNumber()
{
return '+' . $this->country_code . $this->phone_number;
}

public function areaCode()
{
return substr($this->phone_number, 0, 3);
}
}
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"require": {
"php": ">=5.5.9",
"laravel/framework": "5.1.*",
"twilio/sdk": "~4.5",
"twilio/sdk": "^5.0",
"laravelcollective/html": "5.1.*"
},
"require-dev": {
Expand Down