Add sling api

This commit is contained in:
Christopher Cookman 2026-01-09 00:25:59 -07:00
parent e6e13b3494
commit c745054e5a
3 changed files with 63 additions and 53 deletions

View file

@ -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 <channel>"' 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)) {

View file

@ -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');
});

55
routes/api/sling.js Normal file
View file

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