Add sling api
This commit is contained in:
parent
e6e13b3494
commit
c745054e5a
59
index.js
59
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!');
|
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 = {};
|
const contexts = {};
|
||||||
|
|
||||||
// Generate contexts from buttonsCfg
|
// Generate contexts from buttonsCfg
|
||||||
|
|
@ -35,7 +35,7 @@ Object.keys(buttonsCfg).forEach(category => {
|
||||||
});
|
});
|
||||||
//console.log('Generated contexts:', contexts);
|
//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] does not exist, return an error
|
||||||
if (!contexts[pageType]) {
|
if (!contexts[pageType]) {
|
||||||
throw new Error(`Invalid page type: ${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}`);
|
throw new Error(`Phone number is required for page type: ${pageType}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Slink chat notification
|
originateCall(targetNumber, context, 0, timeout, cid, {initiatingUser: variables.username, slingChannel: sling_chat_id || undefined, slingMessage: sling_chat_message || undefined}).then((output) => {
|
||||||
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) => {
|
|
||||||
console.log(`Call originated: ${output}`);
|
console.log(`Call originated: ${output}`);
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
console.error(`Error originating call: ${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)
|
// 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() {
|
async function slingAuthLoop() {
|
||||||
console.log("Start slingAuthLoop")
|
console.log("Start slingAuthLoop")
|
||||||
if (!slingToken) {
|
if (!global.slingToken) {
|
||||||
console.warn('No Sling token provided.');
|
console.warn('No Sling token provided.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -111,7 +91,7 @@ async function slingAuthLoop() {
|
||||||
const sessionCheck = await fetch('https://api.getsling.com/v1/account/session', {
|
const sessionCheck = await fetch('https://api.getsling.com/v1/account/session', {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': `${slingToken}`
|
'Authorization': `${global.slingToken}`
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
console.log(sessionCheck)
|
console.log(sessionCheck)
|
||||||
|
|
@ -120,12 +100,12 @@ async function slingAuthLoop() {
|
||||||
const sessionRefresh = await fetch('https://api.getsling.com/v1/account/session', {
|
const sessionRefresh = await fetch('https://api.getsling.com/v1/account/session', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': `${slingToken}`
|
'Authorization': `${global.slingToken}`
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const newToken = sessionRefresh.headers.get('Authorization');
|
const newToken = sessionRefresh.headers.get('Authorization');
|
||||||
if (newToken) {
|
if (newToken) {
|
||||||
slingToken = newToken;
|
global.slingToken = newToken;
|
||||||
fs.writeFileSync(path.join(__dirname, 'slingtoken.txt'), newToken, 'utf8');
|
fs.writeFileSync(path.join(__dirname, 'slingtoken.txt'), newToken, 'utf8');
|
||||||
console.log('Sling token refreshed.');
|
console.log('Sling token refreshed.');
|
||||||
}
|
}
|
||||||
|
|
@ -140,7 +120,6 @@ global.contexts = contexts;
|
||||||
global.trigCall = trigCall;
|
global.trigCall = trigCall;
|
||||||
global.buttonsCfg = buttonsCfg;
|
global.buttonsCfg = buttonsCfg;
|
||||||
global.phonesCfg = phonesCfg;
|
global.phonesCfg = phonesCfg;
|
||||||
global.slingToken = slingToken;
|
|
||||||
global.originateCall = originateCall;
|
global.originateCall = originateCall;
|
||||||
global.exec = exec;
|
global.exec = exec;
|
||||||
|
|
||||||
|
|
@ -233,30 +212,6 @@ function loadRoutes(dir, baseRoute = "") {
|
||||||
loadRoutes(ROUTES_DIR);
|
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 convertPasswords = () => { // Read auth.json and convert plaintext to hashed passwords
|
||||||
const authFilePath = path.join(__dirname, 'auth.json');
|
const authFilePath = path.join(__dirname, 'auth.json');
|
||||||
if (fs.existsSync(authFilePath)) {
|
if (fs.existsSync(authFilePath)) {
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ const path = require("path");
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
|
|
||||||
router.post("/trigger", global.apiAuth, (req, res) => {
|
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);
|
global.trigCall(req.body.pageType, req.body.phone);
|
||||||
res.status(200).send('Call triggered');
|
res.status(200).send('Call triggered');
|
||||||
});
|
});
|
||||||
|
|
|
||||||
55
routes/api/sling.js
Normal file
55
routes/api/sling.js
Normal 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;
|
||||||
Loading…
Reference in a new issue