LineNotify
npm init
持續按enter
{
"name": "linenotify",
"version": "1.0.0",
"description": "lineNotify",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "[email protected]",
"license": "ISC"
}
接著安裝需要的套件
npm install express nodemon request
在package.json 中的script 加入 nodemon執行語法
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"s": "nodemon index.js"
}
執行nodemon語法的話 不用每次改動程式碼都要重新啟動nodeServer
npm run s
即可使用
右上角帳號資料 點開的選單 選 登錄服務
將資料填齊
其中將 callbackurl 填寫 (不要漏掉最後的斜線)
http://localhost:3000/
等下登錄服務的時候會用到
跟著流程成到下一步後
回到服務一覽表 就可以看到 剛剛 註冊的服務
點進去 會看到ClientId 及ClientSecert(要點擊旁邊按鈕才看到的內容)
回到程式碼部分
開啟到剛剛npm init 後的目錄
新增三個檔案 index.js , index.html , auth.html
先將index.js 的server寫好
const express = require("express");
const app = express();
app.get("/", function (req, res) {
res.sent("helloWorld");
});
app.listen(3000, function () {
console.log("Example app listening on port 3000!");
});
存檔
在cmd 打入指令
npm run s
打開chrome 連線到 http://localhost:3000/ 看到 helloWorld 代表成功將server 寫好並開啟了
現在準備要使用得畫面
用編輯器 (visual code or 記事本) 開啟檔案 index.html 寫入
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<form method="post" action="/registerLineNotify">
<div>
<label> 要註冊的臨時碼</label>
<input type="text" name="token" value="{token}" readonly />
</div>
<div>
<label> 要註冊的Client ID</label>
<input type="text" name="clientId" />
</div>
<div>
<label> 要註冊的Client Secret</label>
<input type="text" name="clientSecret" />
</div>
<input type="submit" value="註冊" />
</form>
</body>
</html>
回到 index.js 撰寫 相關觸發的程式碼
將畫面(index.html) 對到 http://localhost:3000 的 get 方法
//準備 用變數取代html 中需要取代變數的function ,準備好後要利用callBackMethod 將畫面傳去前端
const fs = require("fs");
function render(filename, params, callback) {
fs.readFile(filename, "utf8", function (err, data) {
if (err) return cabllack(err);
for (var key in params) {
data = data.replace("{" + key + "}", params[key]);
}
callback(null, data); // 用 callback 傳回結果
});
}
app.get("/", function (req, res) {
console.log("req", req.query.code);
render(
"index.html",
{
token: req.query.code,
},
function (err, data) {
res.send(data); // 準備 傳去前端 的callBackMethod
}
);
});
為了要讓express 看得懂 http傳回來的body 要再加入(放在所有function 和route 的上面 避免順序問題影響)
const bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({ extended: false }));
撰寫 寫註冊lineNotify服務的route
app.get("/register/:clientId", function (req, res) {
render(
"auth.html",
{
clientId: req.params.clientId,
},
function (err, data) {
res.send(data);
}
);
});
撰寫發送訊息的網頁
修改index.js
app.post("/pushLineNotifyMessage", function (req, res) {
console.log(req.body.message);
pushMessage(req.body.message, req.cookies.accessToken, function (data) {
render(
"pushLineNotify.html",
{
accessToken: req.cookies.accessToken,
},
function (err, data) {
res.send(data); // 這邊要寫一個 function 才能接收到資料
}
);
});
});
app.get("/pushLineNotify", function (req, res) {
if (req.cookies.accessToken) {
render(
"pushLineNotify.html",
{
accessToken: req.cookies.accessToken,
},
function (err, data) {
res.send(data); // 這邊要寫一個 function 才能接收到資料
}
);
} else {
res.send("token不存在請去註冊");
}
});
新增一個 pushLineNotify.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<form method="post" action="/pushLineNotifyMessage">
<div>
<label>發送的token</label>
<input type="text" name="accessToken" value="{accessToken}" readonly />
</div>
<div>
<label> 要送出的訊息</label>
<input type="text" name="message" />
</div>
<input type="submit" value="送出" />
</form>
</body>
</html>
撰寫 註冊完後 要取得 傳輸token 的postMethod
const request = require("request");
function registerLineNotify(token, clientId, clientSecret, callback) {
const clientServerOptions = {
method: "POST",
uri: "https://notify-bot.line.me/oauth/token",
form: {
grant_type: "authorization_code",
code: token,
redirect_uri: "http://localhost:3000/",
client_id: clientId,
client_secret: clientSecret,
},
};
request(clientServerOptions, function (error, response, body) {
console.log(body);
let accessToken = JSON.parse(body).access_token;
console.log("accessToken:", accessToken);
if (body.status == 200) {
callback(accessToken);
} else {
callback("註冊失敗,請重新註冊");
}
return;
});
}
app.post("/registerLineNotify", function (req, res) {
registerLineNotify(
req.body.token,
req.body.clientId,
req.body.clientSecret,
function (data) {
if (data !== "註冊失敗,請重新註冊") {
res.cookie("accessToken", data, { maxAge: 24 * 60 * 60 * 1000 });
} else {
res.clearCookie("accessToken");
}
res.send(data);
}
);
});
撰寫 cookie 操作的method 把註冊完成的accessToken 存在cookie中
npm install cookie-parser
app.use(cookieParser());
最後寫完的index.js 會如下
const express = require("express");
const app = express();
const bodyParser = require("body-parser");
const fs = require("fs");
const request = require("request");
const cookieParser = require("cookie-parser");
app.use(cookieParser());
app.use(bodyParser.urlencoded({ extended: false }));
function render(filename, params, callback) {
fs.readFile(filename, "utf8", function (err, data) {
if (err) return cabllack(err);
for (var key in params) {
data = data.replace("{" + key + "}", params[key]);
}
callback(null, data); // 用 callback 傳回結果
});
}
function registerLineNotify(token, clientId, clientSecret, callback) {
const clientServerOptions = {
method: "POST",
uri: "https://notify-bot.line.me/oauth/token",
form: {
grant_type: "authorization_code",
code: token,
redirect_uri: "http://localhost:3000/",
client_id: clientId,
client_secret: clientSecret,
},
};
request(clientServerOptions, function (error, response, body) {
console.log(body);
let accessToken = JSON.parse(body).access_token;
console.log("accessToken:", accessToken);
if (JSON.parse(body).status == 200) {
callback(accessToken);
} else {
callback("註冊失敗,請重新註冊");
}
return;
});
}
app.post("/registerLineNotify", function (req, res) {
console.log(req.body.token);
console.log(req.body.clientId);
console.log(req.body.clientSecret);
registerLineNotify(
req.body.token,
req.body.clientId,
req.body.clientSecret,
function (data) {
console.log("accessToken:", data);
if (data !== "註冊失敗,請重新註冊") {
res.cookie("accessToken", data, { maxAge: 24 * 60 * 60 * 1000 });
} else {
res.clearCookie("accessToken");
}
res.send(data); // 這邊要寫一個 function 才能接收到資料
}
);
});
function pushMessage(message, token, callback) {
const clientServerOptions = {
method: "POST",
uri: "https://notify-api.line.me/api/notify",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
auth: {
bearer: token,
},
form: {
message: message,
},
};
request(clientServerOptions, function (error, response, body) {
console.log(error, response, body);
callback(body);
return;
});
}
app.get("/register/:clientId", function (req, res) {
render(
"auth.html",
{
clientId: req.params.clientId,
},
function (err, data) {
res.send(data);
}
);
});
app.post("/pushLineNotifyMessage", function (req, res) {
console.log(req.body.message);
pushMessage(req.body.message, req.cookies.accessToken, function (data) {
render(
"pushLineNotify.html",
{
accessToken: req.cookies.accessToken,
},
function (err, data) {
res.send(data); // 這邊要寫一個 function 才能接收到資料
}
);
});
});
app.get("/pushLineNotify", function (req, res) {
if (req.cookies.accessToken) {
render(
"pushLineNotify.html",
{
accessToken: req.cookies.accessToken,
},
function (err, data) {
res.send(data); // 這邊要寫一個 function 才能接收到資料
}
);
} else {
res.send("token不存在請去註冊");
}
});
app.get("/", function (req, res) {
console.log("req", req.query.code);
render(
"index.html",
{
token: req.query.code,
},
function (err, data) {
res.send(data); // 這邊要寫一個 function 才能接收到資料
}
);
});
app.listen(3000, function () {
console.log("Example app listening on port 3000!");
});
用編輯器 (visual code or 記事本) 開啟檔案 auth.html 寫入
<!doctype html>
<html lang="tw">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script>
function oAuth() {
var URL = 'https://notify-bot.line.me/oauth/authorize?';
URL += 'response_type=code';
URL += '&client_id={clientId}';
URL += '&redirect_uri=http://localhost:3000/';
URL += '&scope=notify';
URL += '&state=NO_STATE';
window.location.href = URL;
</script>
</head>
<body>
<button onclick="oAuth();">連結到 LineNotify 按鈕</button>
</body>
</html>
存檔
現在要去登入 自己的 lineNotify 服務
用chrome 開啟剛剛寫好的auth.html
會看到 連結到 LineNotify 按鈕 點下去後 回連結到 lineNotify 的官網 會問你 要連結到哪個群組
lineNotify 僅可以連結到 lineNotify 的 聊天室 或是群組
選完會出現剛剛做的畫面
再將clientId及clientSecert 填入 輸入方塊 後 按註冊
若成功會收到一組 亂數產生的token
以後就可以利用這個來傳送訊息到你的 lineNotify了