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; } }