purityselect/app/Http/Controllers/Admin/Api/CalendlyControllerOld.php
2024-10-25 01:05:27 +05:00

367 lines
15 KiB
PHP

<?php
namespace App\Http\Controllers\Admin\Api;
use App\Http\Controllers\Controller;
use Carbon\Carbon;
use DateTime;
use Illuminate\Http\Request;
use GuzzleHttp\Client;
use Illuminate\Support\Facades\Cache;
class CalendlyControllerOld extends Controller
{
protected $clientId = "eOk7Vb-60_l6U4WmAe9y9MThi-WKGzEuyru_B3I2jwk";
protected $clientSecret = "EYLgGEHLudI65wdqG7Qz1azZwFCFx8kvikXYoM2EbiE";
protected $redirectUri = 'https://hgh.codelfi.com/calendly/redirect-code/';
// Generate Calendly authorization URL
public function getCalendlyAuthUrl()
{
$url = 'https://auth.calendly.com/oauth/authorize';
$url .= '?client_id=' . urlencode($this->clientId);
$url .= '&response_type=code';
$url .= '&redirect_uri=' . urlencode($this->redirectUri);
return response()->json(['url' => $url]);
}
// Handle the redirect with authorization code and exchange for access token
public function getRedirectCode(Request $request)
{
// Get the authorization code from the request
$authorizationCode = $request->input('code');
if (!$authorizationCode) {
return response()->json(['error' => 'Authorization code is missing'], 400);
}
//return $this->getCalendlyUserAndAvailability();
// Call method to fetch access token and cache it
$this->getAccessTokenFromCode($authorizationCode);
return response()->json(['message' => 'Admin has been authenticated.'], 200);
}
// Handle the redirect with authorization code and exchange for access token
public function getAvailabeSlotDates(Request $request)
{
return $this->getCalendlyUserAndAvailability();
// Call method to fetch access token and cache it
}
// Fetch or refresh access token if needed
public function getAccessToken()
{
// Check if the access token exists in cache
if (Cache::has('calendly_access_token')) {
return Cache::get('calendly_access_token');
}
// If no token is available, return error or trigger refresh
return response()->json(['error' => 'No valid access token. Please authenticate again.'], 401);
}
// Exchange authorization code for access token and store it in cache
private function getAccessTokenFromCode($authorizationCode)
{
$tokenUrl = 'https://auth.calendly.com/oauth/token';
// Use GuzzleHttp client to make the POST request
$client = new Client();
try {
$response = $client->post($tokenUrl, [
'form_params' => [
'grant_type' => 'authorization_code',
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
'redirect_uri' => $this->redirectUri,
'code' => $authorizationCode,
],
'headers' => [
'Content-Type' => 'application/x-www-form-urlencoded',
],
]);
// Decode the JSON response
$data = json_decode($response->getBody()->getContents(), true);
// Store access token and refresh token in cache with an expiration
//Cache::put('calendly_access_token', $data['access_token'], now()->addSeconds($data['expires_in']));
//Cache::put('calendly_refresh_token', $data['refresh_token'], now()->addDays(30)); // Refresh tokens don't expire until used
return response()->json([
'access_token' => $data['access_token'],
'refresh_token' => $data['refresh_token'],
'token_type' => $data['token_type'],
'expires_in' => $data['expires_in']
]);
} catch (\Exception $e) {
// Handle errors
return response()->json(['error' => 'Failed to fetch access token: ' . $e->getMessage()], 500);
}
}
// Use refresh token to get a new access token when expired
private function refreshAccessToken()
{
if (!Cache::has('calendly_refresh_token')) {
return response()->json(['error' => 'Refresh token not available.'], 401);
}
$refreshToken = Cache::get('calendly_refresh_token');
$tokenUrl = 'https://auth.calendly.com/oauth/token';
$client = new Client();
try {
$response = $client->post($tokenUrl, [
'form_params' => [
'grant_type' => 'refresh_token',
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
'refresh_token' => $refreshToken,
],
'headers' => [
'Content-Type' => 'application/x-www-form-urlencoded',
],
]);
// Decode the response
$data = json_decode($response->getBody()->getContents(), true);
// Store the new access token and refresh token in cache
Cache::put('calendly_access_token', $data['access_token'], now()->addSeconds($data['expires_in']));
Cache::put('calendly_refresh_token', $data['refresh_token'], now()->addDays(30)); // New refresh token
return $data['access_token'];
} catch (\Exception $e) {
return response()->json(['error' => 'Failed to refresh access token: ' . $e->getMessage()], 500);
}
}
function getCalendlyUserAndAvailability()
{
// Get the access token from cache
$accessToken = Cache::get('calendly_access_token');
// If the token is not in cache, fetch a new one
if (!$accessToken) {
$accessToken = $this->fetchCalendlyAccessToken();
}
if (!$accessToken) {
return response()->json(['error' => 'Token Expired!'], 500);
}
// 1. Call the /users/me API to get user information
$client = new Client();
try {
$response = $client->request('GET', 'https://api.calendly.com/users/me', [
'headers' => [
'Authorization' => 'Bearer ' . $accessToken,
'Content-Type' => 'application/json',
]
]);
$data = json_decode($response->getBody(), true);
$userUri = $data['resource']['uri'];
} catch (\Exception $e) {
return response()->json(['error' => 'Failed to fetch user details: ' . $e->getMessage()], 500);
}
// 2. Use the user URI to fetch availability schedules
try {
$availabilityResponse = $client->request('GET', 'https://api.calendly.com/user_availability_schedules', [
'headers' => [
'Authorization' => 'Bearer ' . $accessToken,
'Content-Type' => 'application/json',
],
'query' => [
'user' => $userUri
]
]);
$availabilityData = json_decode($availabilityResponse->getBody(), true);
// Get the rules from the availability data
$rules = $availabilityData['collection'][0]['rules'];
// Map day of the week to the date in the current week
$weekDates = $this->getCurrentWeekDates(); // Get this week's dates
// Add the corresponding date to each rule
$updatedRules = array_map(function ($rule) use ($weekDates) {
$wday = $rule['wday'];
// Check if we have a corresponding date for this weekday
if (isset($weekDates[$wday])) {
$rule['date'] = $weekDates[$wday]; // Add date to the rule
} else {
$rule['date'] = null; // No availability on that day
}
return $rule;
}, $rules);
// Add the updated rules with dates back to the response
$availabilityData['collection'][0]['rules'] = $updatedRules; // Get the rules from the availability data
$rules = $availabilityData['collection'][0]['rules'];
// Map day of the week to the date in the current week
$weekDates = $this->getCurrentWeekDates(); // Get this week's dates
// Add the corresponding date to each rule
$updatedRules = array_map(function ($rule) use ($weekDates) {
$wday = $rule['wday'];
// Check if we have a corresponding date for this weekday
if (isset($weekDates[$wday])) {
$rule['date'] = $weekDates[$wday]; // Add date to the rule
} else {
$rule['date'] = null; // No availability on that day
}
return $rule;
}, $rules);
$filteredDates = array_values(array_filter(array_map(function ($rule) {
return !empty($rule['intervals']) ? $rule['date'] : null;
}, $updatedRules)));
// Add the updated rules with dates back to the response
$availabilityData['collection'][0]['rules'] = $updatedRules;
return response()->json($availabilityData, 200);
} catch (\Exception $e) {
return response()->json(['error' => 'Failed to fetch availability: ' . $e->getMessage()], 500);
}
}
private function getCurrentWeekDates()
{
$weekDates = [];
// Start from Sunday as 0, loop through the week
for ($day = 0; $day < 7; $day++) {
$carbonDate = Carbon::now()->startOfWeek()->addDays($day); // Start on Sunday
$weekday = strtolower($carbonDate->format('l')); // Get the day name (sunday, monday, etc.)
$weekDates[$weekday] = $carbonDate->toDateString(); // Store the date for that day
}
return $weekDates; // Return array of week dates
}
// Helper function to fetch access token
function fetchCalendlyAccessToken()
{
$client = new Client();
try {
$response = $client->post('https://auth.calendly.com/oauth/token', [
'form_params' => [
'grant_type' => 'authorization_code',
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
'redirect_uri' => $this->redirectUri,
'code' => request()->input('code'), // Get authorization code from request
],
'headers' => [
'Content-Type' => 'application/x-www-form-urlencoded',
]
]);
$data = json_decode($response->getBody(), true);
$accessToken = $data['access_token'];
// Store access token in cache for 2 hours
Cache::put('calendly_access_token', $accessToken, 120 * 60);
return $accessToken;
} catch (\Exception $e) {
return null;
}
}
public function getAvailableTimes(Request $request)
{
try {
// Validate start_time and end_time input
/* $validatedData = $request->validate([
'start_time' => 'required|date_format:Y-m-d\TH:i:s\Z',
'end_time' => 'required|date_format:Y-m-d\TH:i:s\Z',
]); */
// Get the access token from cache
$accessToken = Cache::get('calendly_access_token');
// If the token is not in cache, fetch a new one
if (!$accessToken) {
$accessToken = $this->fetchCalendlyAccessToken();
}
if (!$accessToken) {
return response()->json(['error' => 'Unable to retrieve access token'], 500);
}
// 1. Call the /users/me API to get user information
$client = new Client();
$response = $client->request('GET', 'https://api.calendly.com/users/me', [
'headers' => [
'Authorization' => 'Bearer ' . $accessToken,
'Content-Type' => 'application/json',
]
]);
$data = json_decode($response->getBody(), true);
$userUri = $data['resource']['uri'];
// 1. Call the /users/me API to get user information
$client = new Client();
$responseEvent = $client->request('GET', 'https://api.calendly.com/event_types?user=' . $userUri, [
'headers' => [
'Authorization' => 'Bearer ' . $accessToken,
'Content-Type' => 'application/json',
]
]);
$dataEvent = json_decode($responseEvent->getBody(), true);
$even_type_url = $dataEvent['collection'][0]['uri'];
$userUri = $data['resource']['uri'];
$client = new Client();
// Prepare API endpoint with the required parameters
$eventTypeUrl = 'https://api.calendly.com/event_type_available_times';
$queryParams = [
'event_type' => $even_type_url, //'https://api.calendly.com/event_types/60992c14-2f0b-42c2-af7b-95062d065600', // Use your event_type URL
'start_time' => $request->input('start_time'),
'end_time' => $request->input('end_time')
];
$str = "event_type=" . urlencode($queryParams['event_type']) . "&" . "start_time=" . urlencode($queryParams['start_time']) . "&" . "end_time=" . urlencode($queryParams['end_time']);
$eventTypeUrl = $eventTypeUrl . "?" . ($str);
// Send the request to Calendly
$response = $client->request('GET', $eventTypeUrl, [
'headers' => [
'Authorization' => 'Bearer ' . $accessToken,
'Content-Type' => 'application/json',
],
// 'query' => $queryParams
]);
$data = json_decode($response->getBody(), true);
$processedTimes = array_map(function ($item) {
$dateTime = new DateTime($item['start_time']);
$readableTime = $dateTime->format('Y-m-d H:i'); // Format: YYYY-MM-DD h:mm AM/PM
return [
'status' => $item['status'],
'start_time' => $readableTime,
'invitees_remaining' => $item['invitees_remaining'],
'scheduling_url' => $item['scheduling_url']
];
}, $data['collection']);
// Extract scheduling URLs from available time slots
$availableTimes = array_map(function ($slot) {
return $slot['scheduling_url'];
}, $data['collection']);
return response()->json([
'available_times' => $processedTimes
], 200);
} catch (\Exception $e) {
return response()->json(['error' => 'Failed to fetch available times: ' . $e->getMessage()], 500);
}
}
}