christhompsontldr/laravel-asana
Laravel package to integrate Asana’s API. Includes artisan commands to list workspace custom fields (find gids) and users, optional config publishing, and an AsanaResponse event you can listen to whenever an API response is received.
Installation:
composer require christhompsontldr/laravel-asana
Publish Config (optional but recommended):
php artisan vendor:publish --provider="ChrisThompsonTLDR\Asana\AsanaServiceProvider"
config/asana.php with your Asana API token and workspace ID.First Use Case: Fetch a project by ID in a controller or service:
use ChrisThompsonTLDR\Asana\Facades\Asana;
$project = Asana::projects()->find('1234567890123456');
return response()->json($project);
Asana::projects(), Asana::tasks(), etc., for direct API access.php artisan asana:custom-fields [workspace_id].php artisan asana:users.CRUD Operations:
// Create a task
$task = Asana::tasks()->create([
'name' => 'Complete API integration',
'projects' => ['1234567890123456'],
'custom_fields' => ['1234567890123456' => 'value']
]);
// Update a task
Asana::tasks()->update('1234567890123456', ['name' => 'Updated task']);
// Delete a task
Asana::tasks()->delete('1234567890123456');
Querying Data:
// Get tasks with pagination
$tasks = Asana::tasks()->all(['opt_fields' => 'name,projects', 'limit' => 10]);
// Filter tasks by project
$tasks = Asana::tasks()->where('projects', '1234567890123456')->get();
Custom Fields:
asana:custom-fields command to fetch GIDs for your workspace.$task = Asana::tasks()->create([
'custom_fields' => ['1234567890123456' => 'High']
]);
Event Listeners:
// In EventServiceProvider
protected $listen = [
'ChrisThompsonTLDR\Asana\Events\AsanaResponse' => [
'App\Listeners\LogAsanaResponse',
],
];
class AsanaTaskService {
public function createTask(array $data) {
return Asana::tasks()->create($data);
}
}
try {
$task = Asana::tasks()->find('1234567890123456');
} catch (\ChrisThompsonTLDR\Asana\Exceptions\AsanaException $e) {
Log::error($e->getMessage());
return response()->json(['error' => 'Failed to fetch task'], 500);
}
$tasks = Cache::remember("asana_tasks_{$projectId}", now()->addHours(1), function() use ($projectId) {
return Asana::tasks()->where('projects', $projectId)->get();
});
Deprecated Laravel Support:
Custom Field GIDs:
asana:custom-fields command to fetch them:
php artisan asana:custom-fields WORKSPACE_ID
Pagination Quirks:
?opt_fields and ?limit for partial data:
$tasks = Asana::tasks()->all(['limit' => 50, 'opt_fields' => 'name,due_on']);
Webhooks:
Rate Limit Headers:
X-RateLimit-Remaining headers. Parse them to avoid hitting limits:
$response = Asana::tasks()->all();
$remainingRequests = $response->headers->get('X-RateLimit-Remaining');
Enable Debugging:
debug to true in config/asana.php to log raw API responses:
'debug' => env('ASANA_DEBUG', false),
storage/logs/laravel.log) for errors.Common Errors:
config/asana.php.errors array of the response.Custom API Methods:
class CustomAsana extends \ChrisThompsonTLDR\Asana\Asana {
public function customMethod() {
return $this->get('custom/endpoint');
}
}
$this->app->bind('asana', function() {
return new CustomAsana(config('asana'));
});
Add New Resources:
projects, tasks). Add support for unsupported resources (e.g., stories, sections) by extending the base class:
class AsanaStories extends \ChrisThompsonTLDR\Asana\Resources\BaseResource {
protected $endpoint = 'stories';
}
Asana::extend('stories', function() {
return new AsanaStories(config('asana'));
});
Testing:
$this->mock(\ChrisThompsonTLDR\Asana\Facades\Asana::class)->shouldReceive('tasks')->andReturnSelf();
$this->mock()->shouldReceive('find')->andReturn($mockTask);
How can I help you explore Laravel packages today?