node-red-contrib-line-messaging-api
Version:
Node-RED nodes for LINE Messaging API integration. Build LINE Bots easily with visual programming.
201 lines (170 loc) • 9.09 kB
HTML
<script type="text/javascript">
RED.nodes.registerType('lineConfig', {
category: 'config',
color: '#00afd5',
defaults: {
botName: { value: "" },
botIconUrl: { value: "" }
},
credentials: {
LineChannelSecret: { type: "text" },
LineChannelAccessToken: { type: "text" }
},
label: function () {
return this.botName || 'No Title Bot';
},
oneditprepare: function () {
const node = this;
// --- バリデーションのための設定 ---
const validationTip = $("#node-config-validation-tip");
function validate() {
let errorMessages = [];
const hasWhitespace = /\s/;
const hasFullWidth = /[^\x00-\x7F]/;
// 1. Bot Name のチェック
if ($("#node-config-input-botName").val() === "") {
let message = node._("lineConfig.validation.botNameRequired");
if (!message || message === "lineConfig.validation.botNameRequired") {
message = "Bot名は必須です。";
}
errorMessages.push("・" + message);
}
// 2. Channel Secret のチェック
const secret = $("#node-config-input-LineChannelSecret").val();
if (secret === "") {
let message = node._("lineConfig.validation.channelSecretRequired");
if (!message || message === "lineConfig.validation.channelSecretRequired") {
message = "Channel Secret は必須です。";
}
errorMessages.push("・" + message);
} else if (hasWhitespace.test(secret)) {
errorMessages.push("・Channel Secret にスペースや改行は含められません。");
} else if (hasFullWidth.test(secret)) {
errorMessages.push("・Channel Secret に全角文字は含められません。");
} else if (secret.length !== 32) {
errorMessages.push("・Channel Secret は32文字で入力してください。");
}
// 3. Channel Access Token のチェック
const token = $("#node-config-input-LineChannelAccessToken").val();
if (token === "") {
let message = node._("lineConfig.validation.channelAccessTokenRequired");
if (!message || message === "lineConfig.validation.channelAccessTokenRequired") {
message = "Channel Access Token は必須です。";
}
errorMessages.push("・" + message);
} else if (hasWhitespace.test(token)) {
errorMessages.push("・Channel Access Token にスペースや改行は含められません。");
} else if (hasFullWidth.test(token)) {
errorMessages.push("・Channel Access Token に全角文字は含められません。");
} else if (token.length < 150) {
errorMessages.push("・Channel Access Token が短すぎます。正しい値を貼り付けてください。");
}
if (errorMessages.length > 0) {
$("#node-config-dialog-ok").prop("disabled", true);
validationTip.html(errorMessages.join('<br/>'));
validationTip.show();
} else {
$("#node-config-dialog-ok").prop("disabled", false);
validationTip.hide();
}
}
$("#node-config-input-botName, #node-config-input-LineChannelSecret, #node-config-input-LineChannelAccessToken")
.on('keyup input change', validate);
validate(); // 初期チェック
// --- アイコン取得機能(復元) ---
// 起動時に保存済みのアイコンがあれば表示
if (node.botIconUrl) {
$("#node-config-botIcon").attr("src", node.botIconUrl).show();
}
// 「Bot名&アイコンを取得」ボタンのクリックイベント
$("#node-config-fetch-info").on("click", async () => {
const channelSecret = $("#node-config-input-LineChannelSecret").val();
const channelAccessToken = $("#node-config-input-LineChannelAccessToken").val();
if (!channelSecret || !channelAccessToken) {
RED.notify(node._("message.fetchingBotInfo"), "warning");
return;
}
// ★★★ ここからがAPIに問い合わせる復元部分です ★★★
try {
const response = await fetch("line-config/bot-info", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ channelSecret, channelAccessToken })
});
if (!response.ok) {
const errorText = await response.text();
throw new Error("API Error: " + errorText);
}
const botInfo = await response.json();
// Bot Name をテキストボックスに反映し、バリデーションを再実行
if (botInfo.displayName) {
$("#node-config-input-botName").val(botInfo.displayName).trigger('change');
}
// Icon URL を hidden input にセット + 実際に表示
if (botInfo.pictureUrl) {
$("#node-config-botIcon").attr("src", botInfo.pictureUrl).show();
$("#node-config-input-botIconUrl").val(botInfo.pictureUrl);
} else {
$("#node-config-input-botIconUrl").val("");
$("#node-config-botIcon").hide();
}
RED.notify(node._("message.fetchSuccess"), "success");
} catch (err) {
RED.notify(node._("message.fetchError") + ": " + err.message, "error");
}
// ★★★ ここまでが復元部分です ★★★
});
},
oneditsave: function() {
// ★ alert() を削除し、console.log のみ残しました
if (this.isNew) {
console.log("新しい設定が追加されました。");
} else {
console.log("既存の設定が更新されました。");
}
// ★ アイコンURLを保存する処理を有効にしました
this.botIconUrl = $("#node-config-input-botIconUrl").val();
}
});
</script>
<script type="text/html" data-template-name="lineConfig">
<div class="line-color node-input-form">
<p>LINE Bot Token Settings</p>
<div class="form-row">
<label for="node-config-input-botName">
<i class="fa fa-tag fa-fw"></i> <span data-i18n="label.botName">Bot名</span>
</label>
<input type="text" id="node-config-input-botName" placeholder="BOT Name">
</div>
<div class="form-row">
<label for="node-config-input-LineChannelSecret"><span data-i18n="label.channelSecret">Channel Secret</span></label>
<input type="text" id="node-config-input-LineChannelSecret" placeholder="LINE Channel Secret">
</div>
<div class="form-row">
<label for="node-config-input-LineChannelAccessToken"><span data-i18n="label.channelAccessToken">Channel Access Token</span></label>
<input type="text" id="node-config-input-LineChannelAccessToken" placeholder="LINE Channel Access Token">
</div>
<!-- Bot Icon 表示エリア -->
<div class="form-row">
<label><span data-i18n="label.botIcon">Bot Icon</span></label><br/>
<img id="node-config-botIcon" src=""
style="display:none; max-width: 100px; border-radius: 10%;" />
</div>
<!-- アイコンURLを保存するための隠し入力項目 -->
<input type="hidden" id="node-config-input-botIconUrl" />
<div class="form-row">
<div id="node-config-validation-tip" class="form-tips" style="display: none; color: #a94442;"></div>
</div>
<div class="form-row">
<button type="button" id="node-config-fetch-info"><span data-i18n="label.fetchBotInfo">Bot名&アイコンを取得</span></button>
</div>
</div>
<style>
.line-color {
background-color: #01B301;
padding: 10px;
border-radius: 5px;
color: white;
}
</style>
</script>