## Getting Started
### Minimal Setup
1. **Install the package**:
```bash
composer require linecorp/line-bot-sdk
.env:
LINE_BOT_CHANNEL_ACCESS_TOKEN=your_channel_access_token
LINE_BOT_CHANNEL_SECRET=your_channel_secret
php artisan vendor:publish --provider="LINE\Laravel\LINEBotServiceProvider" --tag=config
use LINE\LINEBot;
use LINE\Messages\TextMessage;
// In your webhook route/controller
$replyToken = $event->getReplyToken();
$message = new TextMessage(['text' => 'Hello from Laravel!']);
LINEBot::replyMessage($replyToken, [$message]);
routes/web.php:
Route::post('/line-webhook', [LineWebhookController::class, 'handle']);
use LINE\LINEBot;
use LINE\LINEBot\Event\Events\MessageEvent;
public function handle(Request $request) {
$events = LINEBot::parseEvent($request->getContent());
foreach ($events as $event) {
if ($event instanceof MessageEvent) {
$this->handleMessage($event);
}
}
}
protected function handleMessage(MessageEvent $event) {
$replyToken = $event->getReplyToken();
$text = $event->getMessage()->getText();
if (strpos($text, 'help') !== false) {
LINEBot::replyMessage($replyToken, [
new TextMessage(['text' => 'Available commands: help, status'])
]);
}
}
LINEBot::pushMessage('user_id', [
new TextMessage(['text' => 'Proactive message']),
new ImageMessage(['originalContentUrl' => 'https://example.com/image.jpg'])
]);
$columns = [
new CarouselColumn([
new ImageMessage(['originalContentUrl' => 'url1', 'previewImageUrl' => 'preview1']),
new TextMessage(['text' => 'Item 1'])
]),
// Add more columns...
];
LINEBot::pushMessage('user_id', [new CarouselTemplateMessage(['columns' => $columns])]);
use LINE\LINEBot\Middleware\ValidateSignature;
$middleware = app()->make(ValidateSignature::class);
$isValid = $middleware->handle($request, function () {
return response('Invalid signature', 401);
});
$events = LINEBot::parseEvent($request->getContent());
$batch = LINEBot::batch();
foreach ($events as $event) {
$batch->reply($event->getReplyToken(), [new TextMessage(['text' => 'Processed'])]);
}
$batch->send();
Webhook Signature Mismatch:
LINE_BOT_CHANNEL_SECRET matches the one in LINE Developer Console.$signature = $request->header('X-Line-Signature');
$isValid = LINEBot::validateSignature($request->getContent(), $signature);
Rate Limits:
sleep() or queues for high-frequency operations:
sleep(1); // 1-second delay between requests
Reply Token Expiry:
Message Size Limits:
Log HTTP Headers:
withHttpInfo() for API calls to inspect headers:
[$response, $status, $headers] = LINEBot::replyMessageWithHttpInfo($replyToken, [$message]);
logger()->info('Request ID:', $headers['x-line-request-id'][0]);
Handle API Exceptions:
LINE\Clients\MessagingApi\ApiException for errors:
try {
LINEBot::getProfile('invalid_user_id');
} catch (ApiException $e) {
logger()->error('LINE API Error:', [
'code' => $e->getCode(),
'body' => $e->getResponseBody(),
'request_id' => $e->getResponseHeaders()['x-line-request-id'][0] ?? 'N/A'
]);
}
Stateless Tokens:
$token = LINEBot::issueStatelessChannelTokenByJWTAssertion($jwtAssertion);
Custom Message Types:
LINE\Messages\MessageInterface for custom messages:
class CustomMessage extends AbstractMessage {
public function __construct(array $data) {
$this->data = $data;
}
public function getType(): string { return 'custom'; }
}
Middleware Stack:
public function boot() {
LINEBot::getMiddleware()->prepend(MyCustomMiddleware::class);
}
Event Subscribers:
use LINE\LINEBot\Event\EventInterface;
class LineEventSubscriber implements ShouldBroadcast {
public function handle(EventInterface $event) {
if ($event instanceof MessageEvent) {
// Broadcast or process the event
}
}
}
Batch API Calls:
LINEBot::batch() to reduce HTTP overhead:
$batch = LINEBot::batch();
$batch->pushMessage('user1', [$msg1]);
$batch->pushMessage('user2', [$msg2]);
$batch->send();
Lazy-Loading:
$messageFactory = function ($text) {
return new TextMessage(['text' => $text]);
};
LINEBot::replyMessage($replyToken, [$messageFactory('Lazy-loaded')]);
Caching:
$profile = Cache::remember("line_profile_{$userId}", now()->addHours(1), function () use ($userId) {
return LINEBot::getProfile($userId);
});
Service Provider Binding:
$this->app->bind(\GuzzleHttp\ClientInterface::class, function () {
return new \GuzzleHttp\Client(['timeout' => 10]);
});
Queue Jobs:
LineMessageJob::dispatch($replyToken, $messages)->onQueue('line');
class LineMessageJob implements ShouldQueue {
public function handle() {
LINEBot::replyMessage($this->replyToken, $this->messages);
}
}
Testing:
LINEBot::shouldReceive('replyMessage')
->once()
->with($replyToken, [$message]);
---
How can I help you explore Laravel packages today?