Skip to content

Commit

Permalink
fix: add reply message and join one room
Browse files Browse the repository at this point in the history
  • Loading branch information
lili668668 committed Jan 8, 2021
1 parent 6a54849 commit 8a04ead
Show file tree
Hide file tree
Showing 12 changed files with 281 additions and 7 deletions.
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,4 @@ MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

LINE_BOT_CHANNEL_SECRET=
LINE_BOT_CHANNEL_ACCESS_TOKEN=
27 changes: 27 additions & 0 deletions app/Events/ReplyLineMessage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace App\Events;

use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class ReplyLineMessage
{
use Dispatchable, InteractsWithSockets, SerializesModels;

public string $replyToken;
public array $messages;

/**
*
* @param string $replyToken
* @param array $messages
* @return void
*/
public function __construct(string $replyToken, array $messages)
{
$this->replyToken = $replyToken;
$this->messages = $messages;
}
}
16 changes: 15 additions & 1 deletion app/Http/Controllers/LineBotController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,32 @@

namespace App\Http\Controllers;

use App\Services\LineBotService;
use Illuminate\Http\Request;

class LineBotController extends Controller
{
protected LineBotService $service;

/**
*
* @param LineBotService $service
* @return void
*/
public function __construct(LineBotService $service)
{
$this->service = $service;
}

public function onEvent(Request $request)
{
$secret = env('LINE_BOT_CHANNEL_SECRET', '');
$body = $request->getContent();
$signature = base64_encode(hash_hmac('sha256', $body, $secret, true));
$header = $request->header('X-Line-Signature');
if ($signature === $header) {
// TODO
$evnets = $request->input('evnets');
$this->service->router($evnets);
}
return response('', 200);
}
Expand Down
34 changes: 34 additions & 0 deletions app/Listeners/SendLineMessage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace App\Listeners;

use App\Events\ReplyLineMessage;
use App\Services\LineBotService;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;

class SendLineMessage
{
protected LineBotService $service;

/**
*
* @param LineBotService $service
* @return void
*/
public function __construct(LineBotService $service)
{
$this->service = $service;
}

/**
* Handle the event.
*
* @param ReplyLineMessage $event
* @return void
*/
public function reply(ReplyLineMessage $event)
{
$this->service->replyMessage($event->replyToken, $event->messages);
}
}
14 changes: 14 additions & 0 deletions app/Models/Group.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

/**
*
* @property integer $id
* @property string $group_id
*/
class Group extends Model
{
}
5 changes: 4 additions & 1 deletion app/Providers/EventServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace App\Providers;

use App\Events\ReplyLineMessage;
use App\Listeners\SendLineMessage;
use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
Expand All @@ -17,6 +19,7 @@ class EventServiceProvider extends ServiceProvider
protected $listen = [
Registered::class => [
SendEmailVerificationNotification::class,
SendLineMessage::class
],
];

Expand All @@ -27,6 +30,6 @@ class EventServiceProvider extends ServiceProvider
*/
public function boot()
{
//
Event::listen(ReplyLineMessage::class, [SendLineMessage::class, 'reply']);
}
}
71 changes: 71 additions & 0 deletions app/Services/LineBotService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

namespace App\Services;

use App\Events\ReplyLineMessage;
use App\Models\Group;
use Exception;
use Illuminate\Contracts\Container\BindingResolutionException;
use Illuminate\Support\Facades\Http;
use InvalidArgumentException;

class LineBotService
{
/**
*
* @param array $events
* @return void
*/
public function router(array $events)
{
foreach ($events as $value)
{
switch ($value['type'])
{
case "join":
return $this->join($value);
}
}
}

/**
*
* @param array $event
* @return void
* @throws InvalidArgumentException
* @throws BindingResolutionException
*/
public function join(array $event)
{
$type = $event['source']['type'];
if ($type !== 'group') return;
$replyToken = $event['replyToken'];
$text = '我是值日生提醒小精靈,請到這裡 -> https://duty-web.ballfish.io 設定值日生';
$group = new Group();
$group->group_id = $event['source']['groupId'];
$group->save();
ReplyLineMessage::dispatch($replyToken, [
[
'type' => 'text',
'text' => $text
]
]);
}

/**
*
* @param string $replyToken
* @param array $messages
* @return void
* @throws InvalidArgumentException
* @throws Exception
*/
public function replyMessage(string $replyToken, array $messages)
{
$token = env('LINE_BOT_CHANNEL_ACCESS_TOKEN', '');
Http::withToken($token)->post('https://api.line.me/v2/bot/message/reply', [
'replyToken' => $replyToken,
'messages' => $messages
]);
}
}
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"php": "^7.4|^8.0",
"fideloper/proxy": "^4.4",
"fruitcake/laravel-cors": "^2.0",
"guzzlehttp/guzzle": "^7.0.1",
"guzzlehttp/guzzle": "^7.2",
"laravel/framework": "^8.12",
"laravel/tinker": "^2.5"
},
Expand Down
4 changes: 2 additions & 2 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 32 additions & 0 deletions database/migrations/2021_01_08_090324_create_groups_table.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateGroupsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('groups', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->string('group_id');
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('groups');
}
}
4 changes: 2 additions & 2 deletions tests/Feature/Hooks/LineBotTest.php
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<?php

namespace Tests\Feature;
namespace Tests\Feature\Hooks;

use Tests\TestCase;

class LineBotTest extends TestCase
{
public function test_example()
public function testOnEvent()
{
$response = $this->post('/line-bot');

Expand Down
78 changes: 78 additions & 0 deletions tests/Feature/Services/LineBotTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php

namespace Tests\Feature\Services;

use App\Events\ReplyLineMessage;
use App\Models\Group;
use App\Services\LineBotService;
use Illuminate\Http\Client\Request;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Http;
use Tests\TestCase;

use function PHPUnit\Framework\assertEquals;

class LineBotTest extends TestCase
{
use RefreshDatabase;

public function testJoin()
{
Event::fake();
$service = new LineBotService();
$service->join([
'replyToken' => 'test',
'type' => 'join',
'source' => [
'type' => 'group',
'groupId' => 'test'
]
]);
$count = Group::where('group_id', 'test')->get()->count();
assertEquals(1, $count);
Event::assertDispatched(function (ReplyLineMessage $event)
{
return $event->replyToken === 'test' &&
$event->messages[0]['text'] === '我是值日生提醒小精靈,請到這裡 -> https://duty-web.ballfish.io 設定值日生';
});
}

public function testNotJoin()
{
Event::fake();
$service = new LineBotService();
$service->join([
'replyToken' => 'test',
'type' => 'join',
'source' => [
'type' => 'room',
'groupId' => 'test'
]
]);
$count = Group::where('group_id', 'test')->get()->count();
assertEquals(0, $count);
Event::assertNotDispatched(ReplyLineMessage::class);
}

public function testReplyMessage()
{
Http::fake();
$service = new LineBotService();
$service->replyMessage('test', [
[
"type" => "text",
"text" => "test"
]
]);
Http::assertSent(function (Request $request)
{
$token = env('LINE_BOT_CHANNEL_ACCESS_TOKEN', '');
return $request->hasHeader('Authorization', 'Bearer '.$token) &&
$request->url() === 'https://api.line.me/v2/bot/message/reply' &&
$request->method() === 'POST' &&
$request['replyToken'] === 'test' &&
is_array($request['messages']);
});
}
}

0 comments on commit 8a04ead

Please sign in to comment.