node-red-contrib-line-messaging-api 0.3.4 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/nodes/config/config.html +108 -20
- package/nodes/config/config.js +33 -8
- package/nodes/getBotInfo/getBotInfo.html +44 -0
- package/nodes/getBotInfo/getBotInfo.js +46 -0
- package/package.json +2 -1
package/nodes/config/config.html
CHANGED
|
@@ -3,36 +3,124 @@
|
|
|
3
3
|
category: 'config',
|
|
4
4
|
color: '#00afd5',
|
|
5
5
|
defaults: {
|
|
6
|
-
|
|
6
|
+
// botName は既存のまま
|
|
7
|
+
botName: { value: "" },
|
|
8
|
+
// botIconUrl を追加
|
|
9
|
+
botIconUrl: { value: "" }
|
|
7
10
|
},
|
|
8
11
|
credentials: {
|
|
9
|
-
LineChannelSecret: {},
|
|
10
|
-
LineChannelAccessToken: {}
|
|
12
|
+
LineChannelSecret: { type: "text" },
|
|
13
|
+
LineChannelAccessToken: { type: "text" }
|
|
11
14
|
},
|
|
12
15
|
label: function () {
|
|
13
|
-
return this.
|
|
16
|
+
return this.botName || 'No Title Bot';
|
|
17
|
+
},
|
|
18
|
+
|
|
19
|
+
oneditprepare: function () {
|
|
20
|
+
const node = this;
|
|
21
|
+
|
|
22
|
+
// すでに保存されている botIconUrl があれば表示する
|
|
23
|
+
if (node.botIconUrl) {
|
|
24
|
+
const botIconImg = document.getElementById("node-config-botIcon");
|
|
25
|
+
botIconImg.src = node.botIconUrl;
|
|
26
|
+
botIconImg.style.display = "block";
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// 「Bot名&アイコンを取得」ボタンイベント
|
|
30
|
+
const btnFetch = document.getElementById("node-config-fetch-info");
|
|
31
|
+
btnFetch.addEventListener("click", async () => {
|
|
32
|
+
const channelSecret = document.getElementById("node-config-input-LineChannelSecret").value;
|
|
33
|
+
const channelAccessToken = document.getElementById("node-config-input-LineChannelAccessToken").value;
|
|
34
|
+
|
|
35
|
+
if (!channelSecret || !channelAccessToken) {
|
|
36
|
+
alert("Channel Secret と Access Token を入力してください。");
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
const response = await fetch("line-config/bot-info", {
|
|
42
|
+
method: "POST",
|
|
43
|
+
headers: { "Content-Type": "application/json" },
|
|
44
|
+
body: JSON.stringify({ channelSecret, channelAccessToken })
|
|
45
|
+
});
|
|
46
|
+
if (!response.ok) {
|
|
47
|
+
throw new Error(await response.text());
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const botInfo = await response.json();
|
|
51
|
+
|
|
52
|
+
// Bot Name をテキストボックスに反映
|
|
53
|
+
if (botInfo.displayName) {
|
|
54
|
+
document.getElementById("node-config-input-botName").value = botInfo.displayName;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Icon URL を hidden input にセット + 実際に表示
|
|
58
|
+
if (botInfo.pictureUrl) {
|
|
59
|
+
const botIconImg = document.getElementById("node-config-botIcon");
|
|
60
|
+
botIconImg.src = botInfo.pictureUrl;
|
|
61
|
+
botIconImg.style.display = "block";
|
|
62
|
+
|
|
63
|
+
document.getElementById("node-config-input-botIconUrl").value = botInfo.pictureUrl;
|
|
64
|
+
} else {
|
|
65
|
+
// pictureUrl がない or 取得失敗時
|
|
66
|
+
document.getElementById("node-config-input-botIconUrl").value = "";
|
|
67
|
+
}
|
|
68
|
+
} catch (err) {
|
|
69
|
+
alert("Bot情報を取得できませんでした: " + err.message);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
oneditsave: function() {
|
|
75
|
+
// Save 時に hidden input から this.botIconUrl に反映
|
|
76
|
+
this.botIconUrl = document.getElementById("node-config-input-botIconUrl").value;
|
|
14
77
|
}
|
|
15
78
|
});
|
|
16
79
|
</script>
|
|
17
80
|
|
|
81
|
+
|
|
18
82
|
<script type="text/html" data-template-name="lineConfig">
|
|
19
|
-
<
|
|
20
|
-
|
|
21
|
-
<label for="node-input-name">
|
|
22
|
-
<i class="fa fa-tag fa-fw"></i> Bot Name
|
|
23
|
-
</label>
|
|
24
|
-
<input type="text" id="node-config-input-name" placeholder="Name">
|
|
25
|
-
</div>
|
|
83
|
+
<div class="line-color node-input-form">
|
|
84
|
+
<p>LINE Bot Token Settings</p>
|
|
26
85
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
86
|
+
<div class="form-row">
|
|
87
|
+
<label for="node-config-input-botName">
|
|
88
|
+
<i class="fa fa-tag fa-fw"></i> Bot Name
|
|
89
|
+
</label>
|
|
90
|
+
<input type="text" id="node-config-input-botName" placeholder="BOT Name">
|
|
91
|
+
</div>
|
|
31
92
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
93
|
+
<div class="form-row">
|
|
94
|
+
<label for="node-config-input-LineChannelSecret">Channel Secret</label>
|
|
95
|
+
<input type="text" id="node-config-input-LineChannelSecret" placeholder="LINE Channel Secret">
|
|
96
|
+
</div>
|
|
36
97
|
|
|
37
|
-
|
|
98
|
+
<div class="form-row">
|
|
99
|
+
<label for="node-config-input-LineChannelAccessToken">Channel Access Token</label>
|
|
100
|
+
<input type="text" id="node-config-input-LineChannelAccessToken" placeholder="LINE Channel Access Token">
|
|
101
|
+
</div>
|
|
102
|
+
|
|
103
|
+
<!-- Bot Icon 表示エリア -->
|
|
104
|
+
<div class="form-row">
|
|
105
|
+
<label>Bot Icon</label><br/>
|
|
106
|
+
<img id="node-config-botIcon" src=""
|
|
107
|
+
style="display:none; max-width: 100px; border-radius: 10%;" />
|
|
108
|
+
</div>
|
|
38
109
|
|
|
110
|
+
<!-- アイコンURLを保存するための隠し入力項目 -->
|
|
111
|
+
<input type="hidden" id="node-config-input-botIconUrl" />
|
|
112
|
+
|
|
113
|
+
<div class="form-row">
|
|
114
|
+
<button type="button" id="node-config-fetch-info">Bot名&アイコンを取得</button>
|
|
115
|
+
</div>
|
|
116
|
+
</div>
|
|
117
|
+
|
|
118
|
+
<style>
|
|
119
|
+
.line-color {
|
|
120
|
+
background-color: #01B301;
|
|
121
|
+
padding: 10px;
|
|
122
|
+
border-radius: 5px;
|
|
123
|
+
color: white;
|
|
124
|
+
}
|
|
125
|
+
</style>
|
|
126
|
+
</script>
|
package/nodes/config/config.js
CHANGED
|
@@ -1,18 +1,43 @@
|
|
|
1
1
|
module.exports = function(RED) {
|
|
2
|
+
const { Client } = require('@line/bot-sdk');
|
|
3
|
+
|
|
2
4
|
function main(n) {
|
|
3
5
|
RED.nodes.createNode(this, n);
|
|
4
|
-
|
|
5
|
-
this.LineChannelSecret = this.credentials.LineChannelSecret;
|
|
6
|
-
this.LineChannelAccessToken = this.credentials.LineChannelAccessToken;
|
|
6
|
+
// コンフィグノードの初期化
|
|
7
7
|
}
|
|
8
|
-
|
|
8
|
+
|
|
9
9
|
RED.nodes.registerType("lineConfig", main, {
|
|
10
10
|
defaults: {
|
|
11
|
-
|
|
11
|
+
botName: { type: "text" }
|
|
12
12
|
},
|
|
13
13
|
credentials: {
|
|
14
|
-
LineChannelSecret: {type: "text"},
|
|
15
|
-
LineChannelAccessToken: {type: "text"}
|
|
14
|
+
LineChannelSecret: { type: "text" },
|
|
15
|
+
LineChannelAccessToken: { type: "text" }
|
|
16
16
|
}
|
|
17
17
|
});
|
|
18
|
-
|
|
18
|
+
|
|
19
|
+
// Admin HTTP API 用のエンドポイント
|
|
20
|
+
RED.httpAdmin.post('/line-config/bot-info', async function(req, res) {
|
|
21
|
+
try {
|
|
22
|
+
const channelSecret = req.body.channelSecret;
|
|
23
|
+
const channelAccessToken = req.body.channelAccessToken;
|
|
24
|
+
if (!channelSecret || !channelAccessToken) {
|
|
25
|
+
return res.status(400).send("No channelSecret or channelAccessToken");
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const clientConfig = {
|
|
29
|
+
channelSecret,
|
|
30
|
+
channelAccessToken
|
|
31
|
+
};
|
|
32
|
+
const client = new Client(clientConfig);
|
|
33
|
+
|
|
34
|
+
const botInfo = await client.getBotInfo();
|
|
35
|
+
// botInfo.displayName, botInfo.pictureUrl などを含む
|
|
36
|
+
return res.json(botInfo);
|
|
37
|
+
|
|
38
|
+
} catch (err) {
|
|
39
|
+
console.error("Failed to getBotInfo:", err);
|
|
40
|
+
res.status(500).send(err.message || "Failed to get botInfo");
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
RED.nodes.registerType('getBotInfo', {
|
|
3
|
+
category: 'LINE',
|
|
4
|
+
color: '#01B301',
|
|
5
|
+
defaults: {
|
|
6
|
+
name: {value: ''},
|
|
7
|
+
lineConfig: {value: "", type:"lineConfig", required:true},
|
|
8
|
+
},
|
|
9
|
+
inputs: 1,
|
|
10
|
+
outputs: 1,
|
|
11
|
+
icon: "watch.png",
|
|
12
|
+
align: 'right',
|
|
13
|
+
label: function () {
|
|
14
|
+
return this.name || 'getBotInfo';
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<script type="text/html" data-template-name="getBotInfo">
|
|
20
|
+
<!-- 名前 -->
|
|
21
|
+
<div class="form-row">
|
|
22
|
+
<label for="node-input-name">
|
|
23
|
+
<i class="fa fa-tag"></i>
|
|
24
|
+
<span data-i18n="node-red:common.label.name"></span>
|
|
25
|
+
</label>
|
|
26
|
+
<input type="text" id="node-input-name" data-i18n="[placeholder]node-red:common.label.name">
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
<!-- LINE Config -->
|
|
30
|
+
<div class="form-row">
|
|
31
|
+
<label for="node-input-lineConfig">
|
|
32
|
+
<i class="fa fa-tag"></i>
|
|
33
|
+
LINE Bot
|
|
34
|
+
<span data-i18n="getBotInfo.label.lineConfig"></span>
|
|
35
|
+
</label> <input type="text" id="node-input-lineConfig" data-i18n="[placeholder]getBotInfo.desc.lineConfig">
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
</script>
|
|
39
|
+
|
|
40
|
+
<script type="text/html" data-help-name="getBotInfo">
|
|
41
|
+
<p>BOTの情報を取得します。</p>
|
|
42
|
+
</script>
|
|
43
|
+
|
|
44
|
+
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
module.exports = (RED) => {
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const line = require('@line/bot-sdk');
|
|
5
|
+
|
|
6
|
+
const main = function(config){
|
|
7
|
+
const node = this;
|
|
8
|
+
RED.nodes.createNode(node, config);
|
|
9
|
+
|
|
10
|
+
let lineconfig = {};
|
|
11
|
+
try {
|
|
12
|
+
lineconfig = require('../../env');
|
|
13
|
+
} catch (error) {
|
|
14
|
+
node.lineConfig = RED.nodes.getNode(config.lineConfig); //共通のlineConfigを取得
|
|
15
|
+
|
|
16
|
+
lineconfig = {
|
|
17
|
+
channelSecret: node.lineConfig.credentials.LineChannelSecret,
|
|
18
|
+
channelAccessToken: node.lineConfig.credentials.LineChannelAccessToken
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
if(lineconfig.channelAccessToken === undefined || lineconfig.channelAccessToken === '') {
|
|
22
|
+
console.error('LINE token not found');
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const client = new line.messagingApi.MessagingApiClient(lineconfig);
|
|
26
|
+
|
|
27
|
+
// ここでLINE APIを呼び出す処理
|
|
28
|
+
node.on('input', async(msg, send, done) => {
|
|
29
|
+
|
|
30
|
+
try {
|
|
31
|
+
const res = await client.getBotInfo();
|
|
32
|
+
msg.payload = res;
|
|
33
|
+
send(msg);
|
|
34
|
+
} catch (error) {
|
|
35
|
+
console.error(error.body);
|
|
36
|
+
node.error(error.body, msg.payload);
|
|
37
|
+
send(msg);
|
|
38
|
+
done(error);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
console.log("Message received:", msg.payload);
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
RED.nodes.registerType("getBotInfo", main);
|
|
46
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-red-contrib-line-messaging-api",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Node-REDでLINE Botが作れます。",
|
|
5
5
|
"main": "line.js",
|
|
6
6
|
"repository": {
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"BloadcastMessage": "./nodes/bloadcast/bloadcast.js",
|
|
20
20
|
"Limit": "./nodes/limit/limit.js",
|
|
21
21
|
"getProfile": "./nodes/getProfile/getProfile.js",
|
|
22
|
+
"getBotInfo": "./nodes/getBotInfo/getBotInfo.js",
|
|
22
23
|
"config": "./nodes/config/config.js",
|
|
23
24
|
"Loading": "./nodes/loading/loading.js",
|
|
24
25
|
"ReplyMessage": "./nodes/reply/reply.js",
|