ken_nogi/NodeJS/express/modules/lwSendMessage.js
Kenichiro NOGI 51a95c5e21 NodeJS
2025-07-10 10:12:37 +09:00

145 lines
5.1 KiB
JavaScript

const fs = require('fs'); // ファイル操作用モジュール
const jwt = require('jsonwebtoken'); // JWT生成用モジュール
const { API_KEY } = require('../config.js'); // API_KEYをインポート
module.exports = (app) => {
app.post('/lwSendMessage', async (req, res) => {
let rawBody = '';
req.on('data', (chunk) => {
rawBody += chunk; // リクエストデータをそのまま取得
});
req.on('end', async () => {
// reqのすべてのパラメータを表示
// console.log('Request Headers:', req.headers);
// console.log('Request Body:', rawBody);
const apiKey = req.headers['x-api-key'];
if (!apiKey || apiKey !== API_KEY) {
console.log('APIキーが不正です');
return res.status(401).json({ error: 'APIキーが不正です' });
}
// botIdとuserIdをヘッダーから取得
const botId = req.headers['x-bot-id'];
const userId = req.headers['x-user-id'];
if (!botId || !userId) {
console.log('x-bot-id, x-user-idは必須です');
return res.status(400).json({ error: 'x-bot-id, x-user-idは必須です' });
}
const userIds = userId.split(';').map(id => id.trim()).filter(id => id);
// リクエストボディからメッセージテキストを取得
const messageText = rawBody;
if (!messageText) {
console.log('messageTextは必須です');
return res.status(400).json({ error: 'messageTextは必須です' });
}
try {
for (const uid of userIds) {
const result = await sendLineworksMessage(botId, uid, messageText);
if (result.success) {
console.log(`送信成功: ${uid}:`, result.message);
} else {
console.log(`送信失敗: ${uid}:`, result.message);
}
}
res.json({ result: 'ok', message: '全ユーザーに送信処理完了' });
return;
} catch (e) {
console.log('エラーが発生しました:', e.message);
res.status(500).json({ error: e.message });
}
});
});
};
// メッセージ送信
async function sendLineworksMessage(botId, userId, messageText) {
const accessToken = await getAccessToken();
if (!accessToken) {
console.log('アクセストークンの取得に失敗しました');
throw new Error('アクセストークンの取得に失敗しました');
}
// userIdに@が含まれない場合はchannelIdとして扱う
let apiUrl;
if (userId.includes('@')) {
apiUrl = `https://www.worksapis.com/v1.0/bots/${botId}/users/${userId}/messages`;
} else {
apiUrl = `https://www.worksapis.com/v1.0/bots/${botId}/channels/${userId}/messages`;
}
const body = {
'content': {
'type': 'text',
'text': messageText
}
};
const response = await fetch(apiUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json;charset=UTF-8',
'Authorization': `Bearer ${accessToken}`
},
body: JSON.stringify(body)
});
if (response.ok) {
console.log('メッセージ送信成功');
return { success: true, message: '送信成功' };
} else {
const errorText = await response.text();
console.log('メッセージ送信失敗:', errorText);
return { success: false, message: `送信失敗: ${errorText}` };
}
}
// アクセストークン取得
async function getAccessToken() {
const clientId = 'V58hNobcAqRcQPerySMz';
const clientSecret = 'gJ84XQtigD';
const serviceAccount = 'x94xh.serviceaccount@works-nextgroup2';
const privateKey = fs.readFileSync('./modules/private_20250530180606.key', 'utf8');
const apiUrl = 'https://auth.worksmobile.com/oauth2/v2.0/token';
const now = Math.floor(Date.now() / 1000);
// JWT生成
const payload = {
'iss': clientId,
'sub': serviceAccount,
'iat': now,
'exp': now + 60 * 5,
'aud': apiUrl
};
const assertion = jwt.sign(payload, privateKey, { 'algorithm': 'RS256' });
const body = new URLSearchParams({
'assertion': assertion,
'grant_type': 'urn:ietf:params:oauth:grant-type:jwt-bearer',
'client_id': clientId,
'client_secret': clientSecret,
'scope': 'bot'
});
const response = await fetch(apiUrl, {
'method': 'POST',
'headers': { 'Content-Type': 'application/x-www-form-urlencoded' },
'body': body.toString()
});
if (response.ok) {
const data = await response.json();
console.log('アクセストークン取得成功');
return data.access_token;
} else {
const errorText = await response.text();
console.log('アクセストークン取得失敗:', errorText);
return null;
}
}