diff --git a/index.js b/index.js index 2944898..23f30ad 100644 --- a/index.js +++ b/index.js @@ -15,7 +15,7 @@ if (!fs.existsSync(path.join(__dirname, 'slingtoken.txt'))) { console.warn('slingtoken.txt file created. Please add your Sling token to this file to use sling messaging!'); } -var slingToken = fs.readFileSync(path.join(__dirname, 'slingtoken.txt'), 'utf8').trim(); +global.slingToken = fs.readFileSync(path.join(__dirname, 'slingtoken.txt'), 'utf8').trim(); const contexts = {}; // Generate contexts from buttonsCfg @@ -35,7 +35,7 @@ Object.keys(buttonsCfg).forEach(category => { }); //console.log('Generated contexts:', contexts); -function trigCall(pageType, phone) { +function trigCall(pageType, phone, variables = {}) { // If contexts[pageType] does not exist, return an error if (!contexts[pageType]) { throw new Error(`Invalid page type: ${pageType}`); @@ -46,27 +46,7 @@ function trigCall(pageType, phone) { throw new Error(`Phone number is required for page type: ${pageType}`); } - // Slink chat notification - if (sling_chat_id && sling_chat_message) { - fetch(`https://api.getsling.com/v1/conversations/${sling_chat_id}/messages`, { - method: 'POST', - headers: { - 'Authorization': `${slingToken}`, - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ - 'content': sling_chat_message - }) - }).then(res => res.json()).then(data => { - if (data && data.success) { - console.log('Sling chat message sent successfully.'); - } else { - console.error('Error sending Sling chat message:', data); - } - }); - } - - originateCall(targetNumber, context, 0, timeout, cid).then((output) => { + originateCall(targetNumber, context, 0, timeout, cid, {initiatingUser: variables.username, slingChannel: sling_chat_id || undefined, slingMessage: sling_chat_message || undefined}).then((output) => { console.log(`Call originated: ${output}`); }).catch((error) => { console.error(`Error originating call: ${error}`); @@ -103,7 +83,7 @@ function originateCall(number, context, delay, timeout, cid, variables = {}) { // Sling chat stuff; Check current token with GET https://api.getsling.com/v1/account/session, refresh with POST https://api.getsling.com/v1/account/session (GET NEW TOKEN FROM RETURN AUTHORIZATION HEADER) async function slingAuthLoop() { console.log("Start slingAuthLoop") - if (!slingToken) { + if (!global.slingToken) { console.warn('No Sling token provided.'); return; } @@ -111,7 +91,7 @@ async function slingAuthLoop() { const sessionCheck = await fetch('https://api.getsling.com/v1/account/session', { method: 'GET', headers: { - 'Authorization': `${slingToken}` + 'Authorization': `${global.slingToken}` } }); console.log(sessionCheck) @@ -120,12 +100,12 @@ async function slingAuthLoop() { const sessionRefresh = await fetch('https://api.getsling.com/v1/account/session', { method: 'POST', headers: { - 'Authorization': `${slingToken}` + 'Authorization': `${global.slingToken}` } }); const newToken = sessionRefresh.headers.get('Authorization'); if (newToken) { - slingToken = newToken; + global.slingToken = newToken; fs.writeFileSync(path.join(__dirname, 'slingtoken.txt'), newToken, 'utf8'); console.log('Sling token refreshed.'); } @@ -140,7 +120,6 @@ global.contexts = contexts; global.trigCall = trigCall; global.buttonsCfg = buttonsCfg; global.phonesCfg = phonesCfg; -global.slingToken = slingToken; global.originateCall = originateCall; global.exec = exec; @@ -233,30 +212,6 @@ function loadRoutes(dir, baseRoute = "") { loadRoutes(ROUTES_DIR); -app.post('/trig', async (req, res) => { - console.log('Triggering call with data:', req.body); - trigCall(req.body.pageType, req.body.phone); - res.status(200).send('Call triggered'); -}); - -app.post('/stop', async (req, res) => { - console.log('Stopping page for phone:', req.body.phone); - // Logic to stop the page would go here. - // For now we will just log it, as the specific asterisk command to hangup a channel depends on implementation details not provided. - // Typically it might involve 'asterisk -rx "channel request hangup "' or similar via AMI. - // Assuming we might want to run a command similar to originate but for hangup if we knew the channel. - // Since we don't have the channel ID easily available without tracking it, we might need to implement channel tracking or use a broad command. - exec(`/usr/bin/ast_drop ${process.env.PAGE_GROUP || '9000'}`, (error, stdout, stderr) => { - if (error) { - console.error(`Error stopping page: ${error}`); - return res.status(500).send('Error stopping page'); - } - console.log(`Page stopped: ${stdout}`); - }); - - res.status(200).send('Stop request received'); -}); - const convertPasswords = () => { // Read auth.json and convert plaintext to hashed passwords const authFilePath = path.join(__dirname, 'auth.json'); if (fs.existsSync(authFilePath)) { diff --git a/routes/api/portal.js b/routes/api/portal.js index 62bb8a0..da8e845 100644 --- a/routes/api/portal.js +++ b/routes/api/portal.js @@ -5,7 +5,7 @@ const path = require("path"); const fs = require("fs"); router.post("/trigger", global.apiAuth, (req, res) => { - console.log('Triggering call with data:', req.body); + console.log('Triggering call with data:', req.body, {username: req.session ? req.session.fullname || 'Unknown' : 'Unknown'}); global.trigCall(req.body.pageType, req.body.phone); res.status(200).send('Call triggered'); }); diff --git a/routes/api/sling.js b/routes/api/sling.js new file mode 100644 index 0000000..4c225a9 --- /dev/null +++ b/routes/api/sling.js @@ -0,0 +1,55 @@ +// fetch(`https://api.getsling.com/v1/conversations/${sling_chat_id}/messages`, { +// method: 'POST', +// headers: { +// 'Authorization': `${global.slingToken}`, +// 'Content-Type': 'application/json' +// }, +// body: JSON.stringify({ +// 'content': sling_chat_message +// }) +// }).then(res => res.json()).then(data => { +// if (data && data.success) { +// console.log('Sling chat message sent successfully.'); +// } else { +// console.error('Error sending Sling chat message:', data); +// } +// }); + +const express = require("express"); +const router = express.Router(); +const path = require("path"); +const fs = require("fs"); + +router.post("/message", global.apiAuth, async (req, res) => { + const { channel, content } = req.body; + if (!channel || !content) { + return res.status(400).json({ error: "Missing channel or content" }); + } + if (!global.slingToken) { + return res.status(500).json({ error: "Sling token not configured" }); + } + try { + const response = await fetch(`https://api.getsling.com/v1/conversations/${channel}/messages`, { + method: 'POST', + headers: { + 'Authorization': `${global.slingToken}`, + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + 'content': content + }) + }); + const data = await response.json(); + if (data && data.success) { + return res.json({ success: true, message: "Message sent successfully" }); + } else { + return res.status(500).json({ error: "Error sending message", details: data }); + } + } catch (error) { + console.error('Error sending Sling chat message:', error); + return res.status(500).json({ error: "Internal server error" }); + } +}); + + +module.exports = router;