node-red-contrib-line-messaging-api 0.3.3 → 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/README.md +10 -0
- package/nodes/_new/push/push.html +14 -8
- package/nodes/_new/push/push.js +19 -7
- package/nodes/_new/reply/reply.html +14 -4
- package/nodes/_new/reply/reply.js +15 -5
- package/nodes/config/config.html +126 -0
- package/nodes/config/config.js +43 -0
- package/nodes/getBotInfo/getBotInfo.html +44 -0
- package/nodes/getBotInfo/getBotInfo.js +46 -0
- package/nodes/getProfile/getProfile.html +44 -0
- package/nodes/getProfile/getProfile.js +46 -0
- package/nodes/limit/limit.html +2 -1
- package/nodes/loading/loading.html +12 -12
- package/nodes/loading/loading.js +2 -7
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -14,6 +14,15 @@ or
|
|
|
14
14
|
|
|
15
15
|
AdminタブからInstall
|
|
16
16
|
|
|
17
|
+
## Configノード
|
|
18
|
+
|
|
19
|
+
LINE Botの設定(チャンネルシークレット、チャンネルアクセストークン)を設定しておく裏側のノードです。
|
|
20
|
+
このノードはエディターには表示されずReplyやPushなどのノードの設定UIからアクセスできます。
|
|
21
|
+
|
|
22
|
+
> 
|
|
23
|
+
|
|
24
|
+
作成したLINE Botの設定は別のReplyノードやPushノードで使いまわせます。
|
|
25
|
+
|
|
17
26
|
## 利用できるAPIと利用イメージ
|
|
18
27
|
|
|
19
28
|
### Webhook & Reply Message
|
|
@@ -110,6 +119,7 @@ template nodeにJSONを設定してみてください。
|
|
|
110
119
|
|
|
111
120
|
## release
|
|
112
121
|
|
|
122
|
+
- 2024/12/27: Loaging / getProfile / configの追加
|
|
113
123
|
- 2023/12/11: Notify_newを追加。スタンプや画像も送れるように。
|
|
114
124
|
- 2021/8/1: Reply Messageが画像に対応(thanks [@ukkz](https://github.com/ukkz))
|
|
115
125
|
- 2020/12/17: Bloadcast Messageに対応、Reply MessageがFlex Messageに対応(thanks [@gaomar](https://github.com/gaomar))
|
|
@@ -4,10 +4,12 @@
|
|
|
4
4
|
color: '#01B301',
|
|
5
5
|
defaults: {
|
|
6
6
|
name: {value:""},
|
|
7
|
+
// lineConfig: {value: "", type:"lineConfig", required:true}, //共通のlineConfigを使う
|
|
8
|
+
lineConfig: {value: "", type:"lineConfig"}, //共通のlineConfigを使う 後方互換的にrequired:trueを外す
|
|
7
9
|
},
|
|
8
10
|
credentials: {
|
|
9
11
|
// channelSecret: {type:"password", required:true},
|
|
10
|
-
channelAccessToken: {type:"password", required:true
|
|
12
|
+
channelAccessToken: {type:"password"}, //後方互換的にrequired:trueを外す
|
|
11
13
|
targetId:{type:"password", required:true},
|
|
12
14
|
},
|
|
13
15
|
inputs: 1,
|
|
@@ -19,19 +21,23 @@
|
|
|
19
21
|
});
|
|
20
22
|
</script>
|
|
21
23
|
|
|
22
|
-
<script type="text/
|
|
24
|
+
<script type="text/html" data-template-name="PushMessage_New">
|
|
23
25
|
<div class="form-row">
|
|
24
26
|
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
|
25
27
|
<input type="text" id="node-input-name" placeholder="Name">
|
|
26
28
|
</div>
|
|
27
29
|
|
|
28
|
-
<!--
|
|
29
|
-
|
|
30
|
-
<
|
|
31
|
-
|
|
30
|
+
<!-- LINE Config -->
|
|
31
|
+
<div class="form-row">
|
|
32
|
+
<label for="node-input-lineConfig">
|
|
33
|
+
<i class="fa fa-tag"></i>
|
|
34
|
+
LINE Bot
|
|
35
|
+
<span data-i18n="getProfile.label.lineConfig"></span>
|
|
36
|
+
</label> <input type="text" id="node-input-lineConfig" data-i18n="[placeholder]getProfile.desc.lineConfig">
|
|
37
|
+
</div>
|
|
32
38
|
|
|
33
39
|
<div class="form-row">
|
|
34
|
-
<label for="node-input-channelAccessToken"><i class="icon-tag"></i> AccessToken
|
|
40
|
+
<label for="node-input-channelAccessToken"><i class="icon-tag"></i> (AccessToken)</label>
|
|
35
41
|
<input type="password" id="node-input-channelAccessToken" placeholder="ChannelAccessToken">
|
|
36
42
|
</div>
|
|
37
43
|
|
|
@@ -48,6 +54,6 @@
|
|
|
48
54
|
</div> -->
|
|
49
55
|
</script>
|
|
50
56
|
|
|
51
|
-
<script type="text/
|
|
57
|
+
<script type="text/html" data-help-name="PushMessage_New">
|
|
52
58
|
<p>Send a push message by specifying the user ID or group ID.</p>
|
|
53
59
|
</script>
|
package/nodes/_new/push/push.js
CHANGED
|
@@ -6,18 +6,30 @@ module.exports = (RED) => {
|
|
|
6
6
|
const node = this;
|
|
7
7
|
RED.nodes.createNode(node, config);
|
|
8
8
|
|
|
9
|
-
let lineconfig;
|
|
9
|
+
let lineconfig = {};
|
|
10
|
+
|
|
10
11
|
try {
|
|
11
|
-
lineconfig = require('../../env');
|
|
12
|
+
lineconfig = require('../../env'); //環境変数を取得
|
|
12
13
|
} catch (error) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
try {
|
|
15
|
+
node.lineConfig = RED.nodes.getNode(config.lineConfig); //共通のlineConfigを取得
|
|
16
|
+
lineconfig = {
|
|
17
|
+
channelSecret: node.lineConfig.credentials.LineChannelSecret,
|
|
18
|
+
channelAccessToken: node.lineConfig.credentials.LineChannelAccessToken
|
|
19
|
+
};
|
|
20
|
+
console.log(`---共通lineConfigから---`);
|
|
21
|
+
} catch (error) {
|
|
22
|
+
lineconfig = {
|
|
23
|
+
channelSecret: node.credentials.channelSecret,
|
|
24
|
+
channelAccessToken: node.credentials.channelAccessToken
|
|
25
|
+
};
|
|
26
|
+
console.log(`---個別の設定から---`);
|
|
27
|
+
}
|
|
28
|
+
|
|
17
29
|
}
|
|
18
30
|
|
|
19
31
|
if(lineconfig.channelAccessToken === undefined || lineconfig.channelAccessToken === '') {
|
|
20
|
-
console.error('token not found1');
|
|
32
|
+
console.error('LINE token not found1');
|
|
21
33
|
return;
|
|
22
34
|
}
|
|
23
35
|
// const client = new line.messagingApi.MessagingApiClient(lineconfig);
|
|
@@ -4,11 +4,12 @@
|
|
|
4
4
|
color: '#01B301',
|
|
5
5
|
defaults: {
|
|
6
6
|
name: {value:""},
|
|
7
|
+
lineConfig: {value: "", type:"lineConfig"}, //共通のlineConfigを使う 後方互換的にrequired:trueを外す
|
|
7
8
|
replyMessage:{value:""}
|
|
8
9
|
},
|
|
9
10
|
credentials: {
|
|
10
|
-
channelSecret: {type:"password", required:true
|
|
11
|
-
channelAccessToken: {type:"password", required:true
|
|
11
|
+
channelSecret: {type:"password"}, //後方互換的にrequired:trueを外す
|
|
12
|
+
channelAccessToken: {type:"password"}, //後方互換的にrequired:trueを外す
|
|
12
13
|
},
|
|
13
14
|
inputs:1,
|
|
14
15
|
outputs:1,
|
|
@@ -21,12 +22,21 @@
|
|
|
21
22
|
});
|
|
22
23
|
</script>
|
|
23
24
|
|
|
24
|
-
<script type="text/
|
|
25
|
+
<script type="text/html" data-template-name="ReplyMessage_New">
|
|
25
26
|
<div class="form-row">
|
|
26
27
|
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
|
27
28
|
<input type="text" id="node-input-name" placeholder="Name">
|
|
28
29
|
</div>
|
|
29
30
|
|
|
31
|
+
<!-- LINE Config -->
|
|
32
|
+
<div class="form-row">
|
|
33
|
+
<label for="node-input-lineConfig">
|
|
34
|
+
<i class="fa fa-tag"></i>
|
|
35
|
+
LINE Bot
|
|
36
|
+
<span data-i18n="getProfile.label.lineConfig"></span>
|
|
37
|
+
</label> <input type="text" id="node-input-lineConfig" data-i18n="[placeholder]getProfile.desc.lineConfig">
|
|
38
|
+
</div>
|
|
39
|
+
|
|
30
40
|
<div class="form-row">
|
|
31
41
|
<label for="node-input-channelSecret"><i class="icon-tag"></i> Secret</label>
|
|
32
42
|
<input type="password" id="node-input-channelSecret" placeholder="ChannelSecret">
|
|
@@ -43,6 +53,6 @@
|
|
|
43
53
|
</div>
|
|
44
54
|
</script>
|
|
45
55
|
|
|
46
|
-
<script type="text/
|
|
56
|
+
<script type="text/html" data-help-name="ReplyMessage_New">
|
|
47
57
|
<p>A simple node that converts the message payloads into all ReplyMessage characters</p>
|
|
48
58
|
</script>
|
|
@@ -10,14 +10,24 @@ module.exports = (RED) => {
|
|
|
10
10
|
try {
|
|
11
11
|
lineconfig = require('../../env');
|
|
12
12
|
} catch (error) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
try {
|
|
14
|
+
node.lineConfig = RED.nodes.getNode(config.lineConfig); //共通のlineConfigを取得
|
|
15
|
+
lineconfig = {
|
|
16
|
+
channelSecret: node.lineConfig.credentials.LineChannelSecret,
|
|
17
|
+
channelAccessToken: node.lineConfig.credentials.LineChannelAccessToken
|
|
18
|
+
};
|
|
19
|
+
console.log(`---共通lineConfigから---`);
|
|
20
|
+
} catch (error) {
|
|
21
|
+
lineconfig = {
|
|
22
|
+
channelSecret: node.credentials.channelSecret,
|
|
23
|
+
channelAccessToken: node.credentials.channelAccessToken
|
|
24
|
+
};
|
|
25
|
+
console.log(`---個別の設定から---`);
|
|
26
|
+
}
|
|
17
27
|
}
|
|
18
28
|
|
|
19
29
|
if (lineconfig.channelSecret === '' || lineconfig.channelAccessToken === '') {
|
|
20
|
-
this.error(RED._('token not found'));
|
|
30
|
+
this.error(RED._('LINE token not found'));
|
|
21
31
|
}
|
|
22
32
|
|
|
23
33
|
const client = new line.Client(lineconfig);
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
<script type="text/javascript">
|
|
2
|
+
RED.nodes.registerType('lineConfig', {
|
|
3
|
+
category: 'config',
|
|
4
|
+
color: '#00afd5',
|
|
5
|
+
defaults: {
|
|
6
|
+
// botName は既存のまま
|
|
7
|
+
botName: { value: "" },
|
|
8
|
+
// botIconUrl を追加
|
|
9
|
+
botIconUrl: { value: "" }
|
|
10
|
+
},
|
|
11
|
+
credentials: {
|
|
12
|
+
LineChannelSecret: { type: "text" },
|
|
13
|
+
LineChannelAccessToken: { type: "text" }
|
|
14
|
+
},
|
|
15
|
+
label: function () {
|
|
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;
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
</script>
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
<script type="text/html" data-template-name="lineConfig">
|
|
83
|
+
<div class="line-color node-input-form">
|
|
84
|
+
<p>LINE Bot Token Settings</p>
|
|
85
|
+
|
|
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>
|
|
92
|
+
|
|
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>
|
|
97
|
+
|
|
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>
|
|
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>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module.exports = function(RED) {
|
|
2
|
+
const { Client } = require('@line/bot-sdk');
|
|
3
|
+
|
|
4
|
+
function main(n) {
|
|
5
|
+
RED.nodes.createNode(this, n);
|
|
6
|
+
// コンフィグノードの初期化
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
RED.nodes.registerType("lineConfig", main, {
|
|
10
|
+
defaults: {
|
|
11
|
+
botName: { type: "text" }
|
|
12
|
+
},
|
|
13
|
+
credentials: {
|
|
14
|
+
LineChannelSecret: { type: "text" },
|
|
15
|
+
LineChannelAccessToken: { type: "text" }
|
|
16
|
+
}
|
|
17
|
+
});
|
|
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
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
RED.nodes.registerType('getProfile', {
|
|
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 || 'getProfile';
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<script type="text/html" data-template-name="getProfile">
|
|
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="getProfile.label.lineConfig"></span>
|
|
35
|
+
</label> <input type="text" id="node-input-lineConfig" data-i18n="[placeholder]getProfile.desc.lineConfig">
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
</script>
|
|
39
|
+
|
|
40
|
+
<script type="text/html" data-help-name="getProfile">
|
|
41
|
+
<p>プロフィールを取得します。</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.getProfile(msg.payload.userId);
|
|
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("getProfile", main);
|
|
46
|
+
}
|
package/nodes/limit/limit.html
CHANGED
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
});
|
|
19
19
|
</script>
|
|
20
20
|
|
|
21
|
-
<script type="text/
|
|
21
|
+
<script type="text/html" data-template-name="Limit">
|
|
22
|
+
<!-- 名前 -->
|
|
22
23
|
<div class="form-row">
|
|
23
24
|
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
|
24
25
|
<input type="text" id="node-input-name" placeholder="Name">
|
|
@@ -4,12 +4,10 @@
|
|
|
4
4
|
color: '#01B301',
|
|
5
5
|
defaults: {
|
|
6
6
|
name: {value:""},
|
|
7
|
+
targetId: {value:"", required:true},
|
|
8
|
+
lineConfig: {value: "", type:"lineConfig", required:true}, //共通のlineConfigを使う
|
|
7
9
|
loadingSeconds: {value: 20}
|
|
8
10
|
},
|
|
9
|
-
credentials: {
|
|
10
|
-
channelAccessToken: { type: "password", required: true },
|
|
11
|
-
targetId:{type:"password", required:true}
|
|
12
|
-
},
|
|
13
11
|
inputs:1,
|
|
14
12
|
outputs:1,
|
|
15
13
|
icon: "timer.png",
|
|
@@ -20,20 +18,22 @@
|
|
|
20
18
|
});
|
|
21
19
|
</script>
|
|
22
20
|
|
|
23
|
-
<script type="text/
|
|
21
|
+
<script type="text/html" data-template-name="Loading">
|
|
24
22
|
<div class="form-row">
|
|
25
23
|
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
|
26
24
|
<input type="text" id="node-input-name" placeholder="Name">
|
|
27
25
|
</div>
|
|
28
26
|
|
|
27
|
+
<!-- LINE Config -->
|
|
29
28
|
<div class="form-row">
|
|
30
|
-
<label for="node-input-
|
|
31
|
-
<i class="
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
<input type="
|
|
29
|
+
<label for="node-input-lineConfig">
|
|
30
|
+
<i class="fa fa-tag"></i>
|
|
31
|
+
LINE Bot
|
|
32
|
+
<span data-i18n="getProfile.label.lineConfig"></span>
|
|
33
|
+
</label> <input type="text" id="node-input-lineConfig" data-i18n="[placeholder]getProfile.desc.lineConfig">
|
|
35
34
|
</div>
|
|
36
35
|
|
|
36
|
+
<!-- chat ID / User ID -->
|
|
37
37
|
<div class="form-row">
|
|
38
38
|
<label for="node-input-targetId"><i class="icon-tag"></i> User Id</label>
|
|
39
39
|
<input type="text" id="node-input-targetId" placeholder="User Id">
|
|
@@ -67,6 +67,6 @@
|
|
|
67
67
|
</p>
|
|
68
68
|
</script>
|
|
69
69
|
|
|
70
|
-
<script type="text/
|
|
71
|
-
<p
|
|
70
|
+
<script type="text/html" data-help-name="Loading">
|
|
71
|
+
<p>ローディングアニメーションを流します。</p>
|
|
72
72
|
</script>
|
package/nodes/loading/loading.js
CHANGED
|
@@ -38,7 +38,7 @@ module.exports = (RED) => {
|
|
|
38
38
|
|
|
39
39
|
// レスポンスが {}(空のJSONオブジェクト)なら成功らしい
|
|
40
40
|
if (res && Object.keys(res).length === 0) {
|
|
41
|
-
node.log('
|
|
41
|
+
node.log('ローディングが成功したかも?: {} が返却されました');
|
|
42
42
|
} else {
|
|
43
43
|
node.warn('ローディング処理失敗:', res);
|
|
44
44
|
}
|
|
@@ -53,10 +53,5 @@ module.exports = (RED) => {
|
|
|
53
53
|
});
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
RED.nodes.registerType("Loading", main
|
|
57
|
-
credentials: {
|
|
58
|
-
channelAccessToken: {type:"password"},
|
|
59
|
-
targetId: {type:"password"},
|
|
60
|
-
}
|
|
61
|
-
});
|
|
56
|
+
RED.nodes.registerType("Loading", main);
|
|
62
57
|
}
|
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": {
|
|
@@ -18,6 +18,9 @@
|
|
|
18
18
|
"PushMessage_New": "./nodes/_new/push/push.js",
|
|
19
19
|
"BloadcastMessage": "./nodes/bloadcast/bloadcast.js",
|
|
20
20
|
"Limit": "./nodes/limit/limit.js",
|
|
21
|
+
"getProfile": "./nodes/getProfile/getProfile.js",
|
|
22
|
+
"getBotInfo": "./nodes/getBotInfo/getBotInfo.js",
|
|
23
|
+
"config": "./nodes/config/config.js",
|
|
21
24
|
"Loading": "./nodes/loading/loading.js",
|
|
22
25
|
"ReplyMessage": "./nodes/reply/reply.js",
|
|
23
26
|
"PushMessage": "./nodes/push/push.js",
|