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.
@@ -3,36 +3,124 @@
3
3
  category: 'config',
4
4
  color: '#00afd5',
5
5
  defaults: {
6
- name: {value: ""}
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.name || 'API Key';
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
- <p>LINE Bot Token Settings </p>
20
- <div class="form-row">
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
- <div class="form-row">
28
- <label for="node-config-input-LineChannelSecret"> Channel Secret</label>
29
- <input type="text" id="node-config-input-LineChannelSecret" placeholder="LINE Channel Secret">
30
- </div>
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
- <div class="form-row">
33
- <label for="node-config-input-LineChannelAccessToken"> Channel Access Token</label>
34
- <input type="text" id="node-config-input-LineChannelAccessToken" placeholder="LINE Channel Access Token">
35
- </div>
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
- </script>
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>
@@ -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
- this.name = n.name;
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
- name: {value: ""}
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.4",
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",