Skip to content

Commit

Permalink
LINE Notify 註冊與推播
Browse files Browse the repository at this point in the history
1. composer.json 多一個逗號,會無法 install,已修正
2. LINE Notify 註冊與推播已沒問題
3. 為防止一個帳號多次連動,造成多次通知與推播效能,往後可能需要做身份驗證
4. 例外處理沒寫的很好...  需要高手相救
5. 本次有新增 table,務必 migrate
  • Loading branch information
JackKuo-tw committed Jan 3, 2019
1 parent cd0c7b3 commit db8e815
Show file tree
Hide file tree
Showing 11 changed files with 11,861 additions and 2 deletions.
6 changes: 5 additions & 1 deletion .env.example
Expand Up @@ -38,4 +38,8 @@ MAIL_HOST=mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_ENCRYPTION=null

LINE_NOTIFY_CLIENT_ID=
LINE_NOTIFY_CLIENT_SECRET=
LINE_NOTIFY_REDIRECT_URI=https://bot.moli.rocks/line-notify-auth
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -4,3 +4,4 @@ Homestead.yaml
Homestead.json
.env
.idea/
.DS_Store
15 changes: 15 additions & 0 deletions app/Console/Commands/NCNU_RSS.php
Expand Up @@ -4,10 +4,12 @@

use Illuminate\Console\Command;

use MOLiBot\LINE_Notify_User;
use Telegram;
use MOLiBot\Published_NCNU_RSS;
use Fukuball\Jieba\Jieba;
use Fukuball\Jieba\Finalseg;
use MOLiBot\Http\Controllers\LINENotifyController;

class NCNU_RSS extends Command
{
Expand Down Expand Up @@ -77,13 +79,26 @@ public function handle()
$chat_id = env('NEWS_CHANNEL');
}

// send to Telegram Channel
Telegram::sendMessage([
'chat_id' => $chat_id,
'text' => $item['title'] . PHP_EOL . 'http://www.ncnu.edu.tw/ncnuweb/ann/' . $item['link'] . PHP_EOL . PHP_EOL . $hashtag
]);

// send to LINE Notify
$LNU = LINE_Notify_User::getAllToken(); // LINE Notify Users
$msg = PHP_EOL .$item['title'] . PHP_EOL . 'http://www.ncnu.edu.tw/ncnuweb/ann/' . $item['link'];
foreach ($LNU as $key => $at){
LINENotifyController::sendMsg($at, $msg);
// LINE 限制一分鐘上限 1000 次,做一些保留次數
if( ($key+1) % 950 == 0) {
sleep(62);
}
}

$this->Published_NCNU_RSSModel->create(['guid' => $item['guid'], 'title' => $item['title']]);

// 避免太過頻繁發送
sleep(5);
}
}
Expand Down
146 changes: 146 additions & 0 deletions app/Http/Controllers/LINENotifyController.php
@@ -0,0 +1,146 @@
<?php

namespace MOLiBot\Http\Controllers;

use Illuminate\Http\Request;
use MOLiBot\LINE_Notify_User;
use SoapBox\Formatter\Formatter;
use \GuzzleHttp\Client as GuzzleHttpClient;
use \GuzzleHttp\Exception\TransferException as GuzzleHttpTransferException;


class LINENotifyController extends Controller
{

private $redirect_uri;
private $client_id;
private $client_secret;

public function __construct()
{
$this->redirect_uri = \Config::get('line.line_notify_redirect_uri');
$this->client_id = \Config::get('line.line_notify_client_id');
$this->client_secret = \Config::get('line.line_notify_client_secret');
}

public static function sendMsg($access_token, $msg)
{
$client = new GuzzleHttpClient();
try {
$response = $client->request('POST', 'https://notify-api.line.me/api/notify', [
'headers' => [
'Authorization' => 'Bearer ' . $access_token,
],
'form_params' => [
'message' => $msg,
],
'timeout' => 10
]);
} catch (GuzzleHttpTransferException $e) {
$status = $e->getCode();
if ($status == 400) {
throw new \Exception('400 - Unauthorized request');
} elseif ($status == 401) {
throw new \Exception('401 - Invalid access token');
} elseif ($status == 500) {
throw new \Exception('500 - Failure due to server error');
} else {
throw new \Exception('Processed over time or stopped');
}
}
return $response;
}

public function getStatus($access_token)
{
$client = new GuzzleHttpClient();
try {
$response = $client->request('GET', 'https://notify-api.line.me/api/status', [
'headers' => [
'Authorization' => 'Bearer ' . $access_token,
],
'timeout' => 10
]);
$response = $response->getBody()->getContents();
$formatter = Formatter::make($response, Formatter::JSON);
$json = $formatter->toArray();

return $json;
} catch (GuzzleHttpTransferException $e) {
return $e;
}

}

public function auth(Request $request)
{
$code = $request->query('code', false);
$state = $request->query('state', false);
if ($code) {
$client = new GuzzleHttpClient();
// get access_token
try {
$response = $client->request('POST', 'https://notify-bot.line.me/oauth/token', [
'headers' => [
'User-Agent' => 'MOLi Bot',
'cache-control' => 'no-cache'
],
'form_params' => [
'grant_type' => 'authorization_code',
'code' => $code,
'redirect_uri' => $this->redirect_uri,
'client_id' => $this->client_id,
'client_secret' => $this->client_secret
],
'timeout' => 10
]);

$response = $response->getBody()->getContents();
$formatter = Formatter::make($response, Formatter::JSON);
$json = $formatter->toArray();
$access_token = $json['access_token'];
$success = true;
LINE_Notify_User::create([
'access_token' => $access_token
]);
} catch (GuzzleHttpTransferException $e) {
$status = $e->getCode();
if ($status == 400) {
$error = '400 - Unauthorized request';
return view('LINE/notify_auth', compact('error'));
} else {
$error = 'Other - Processed over time or stopped';
return view('LINE/notify_auth', compact('error'));
}
}

// send a welcome message
try {
$msg = "\n歡迎使用暨大通知,此服務由 MOLi 實驗室維護\n如有疑問可至粉專或群組詢問\nhttps://moli.rocks";
$this->sendMsg($access_token, $msg);
} catch (\Exception $e) {
return $e->getCode();
}

// get status
try {
$json = $this->getStatus($access_token);
LINE_Notify_User::where('access_token', $access_token)
->update([
'targetType' => $json['targetType'],
'target' => $json['target']
]);
} catch (\Exception $e) {
return $e->getCode();
}

return view('LINE/notify_auth', compact('success'));

} else {
// 歡迎畫面
$client_id = $this->client_id;
$redirect_uri = $this->redirect_uri;
return view('LINE/notify_auth', compact('client_id', 'redirect_uri'));
}
}
}
2 changes: 2 additions & 0 deletions app/Http/routes.php
Expand Up @@ -13,6 +13,8 @@

Route::get('/', 'MOLiBotController@getIndex');

Route::get('/line-notify-auth', 'LINENotifyController@auth')->name('line_notify_auth');

Route::any('/connect-test', 'MOLiBotController@connectTester');

Route::get('/ncnu-rss', 'MOLiBotController@getNCNU_RSS');
Expand Down
18 changes: 18 additions & 0 deletions app/LINE_Notify_User.php
@@ -0,0 +1,18 @@
<?php

namespace MOLiBot;

use Illuminate\Database\Eloquent\Model;


class LINE_Notify_User extends Model
{
protected $table = 'line_notify_users';

protected $fillable = ['access_token', 'targetType', 'target', 'sid', 'email'];

public static function getAllToken()
{
return static::all()->pluck('access_token')->toArray();
}
}
2 changes: 1 addition & 1 deletion composer.json
Expand Up @@ -61,7 +61,7 @@
"post-update-cmd": [
"Illuminate\\Foundation\\ComposerScripts::postUpdate",
"php artisan ide-helper:generate",
"php artisan ide-helper:meta",
"php artisan ide-helper:meta"
]
},
"config": {
Expand Down
46 changes: 46 additions & 0 deletions config/line.php
@@ -0,0 +1,46 @@
<?php

return [
/*
|--------------------------------------------------------------------------
| LINE Notify Client ID [REQUIRED]
|--------------------------------------------------------------------------
|
| Your LINE Notify's Access Client ID.
| Example: adTHJiKiA39mELihBinK
|
| Refer for more details:
| https://notify-bot.line.me/doc/
|
*/
'line_notify_client_id' => env('LINE_NOTIFY_CLIENT_ID', 'YOUR-ID'),

/*
|--------------------------------------------------------------------------
| LINE Notify Client Secret [REQUIRED]
|--------------------------------------------------------------------------
|
| Your LINE Notify's Access Client ID.
| Example: 3VF2nKo3RdYIUUilOPdUXIZeDfIOPsy0rgSi4
|
| Refer for more details:
| https://notify-bot.line.me/doc/
|
*/
'line_notify_client_secret' => env('LINE_NOTIFY_CLIENT_SECRET', 'YOUR-SECRET'),

/*
|--------------------------------------------------------------------------
| Line Notify Redirect URI [REQUIRED]
|--------------------------------------------------------------------------
|
| Your LINE Notify's Authentication page URI.
| The format should be "https://{YOUR_DOMAIN}/auth"
| Example: https://api.moli.rocks/line-notify-auth
|
| Refer for more details:
| https://notify-bot.line.me/
|
*/
'line_notify_redirect_uri' => env('LINE_NOTIFY_REDIRECT_URI', 'https://bot.moli.rocks/line-notify-auth'),
];
@@ -0,0 +1,36 @@
<?php

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

class CreateLINENotifyUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('line_notify_users', function (Blueprint $table) {
$table->increments('id');
$table->string('access_token');
$table->string('targetType')->nullable();
$table->string('target')->nullable();
$table->string('sid')->nullable(); // 學號,保留用來辨識
$table->string('email')->nullable(); // Email,保留用來辨識
$table->timestamps();
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('line_notify_users');
}
}

3 comments on commit db8e815

@zxp86021
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

學長好猛

@bluet
Copy link
Member

@bluet bluet commented on db8e815 Mar 1, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

要加哪個帳號?

@JackKuo-tw
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

要加哪個帳號?

學長請:https://bot.moli.rocks/line-notify-auth
功能跟 Telegram 版本的一樣

Please sign in to comment.