207 lines
5.5 KiB
JavaScript
207 lines
5.5 KiB
JavaScript
const { FreepbxGqlClient, gql } = require("freepbx-graphql-client");
|
|
|
|
class FreepbxManager {
|
|
/**
|
|
* Creates an instance of the FreepbxGqlClient and initializes the connection pool.
|
|
*
|
|
* @param {Object} config - Configuration object for the FreepbxGqlClient.
|
|
* @param {string} config.url - The URL of the FreePBX GraphQL endpoint.
|
|
* @param {string} config.clientId - The client ID for authentication.
|
|
* @param {string} config.clientSecret - The client secret for authentication.
|
|
* @param {Object} config.dbPool - The connection pool for managing database connections.
|
|
*/
|
|
constructor(config) {
|
|
this.client = null;
|
|
this.renewClient = async () => {
|
|
this.client = new FreepbxGqlClient(config.url, {
|
|
client: {
|
|
id: config.clientId,
|
|
secret: config.clientSecret,
|
|
},
|
|
});
|
|
}
|
|
this.renewClient();
|
|
|
|
this.pbxCall = async (query, variables) => {
|
|
try {
|
|
return await this.client.request(query, variables);
|
|
} catch (err) {
|
|
if (err.response && err.response.error && err.response.error.message === "The resource owner or authorization server denied the request.") {
|
|
await this.renewClient();
|
|
console.log("Client renewed");
|
|
return await this.pbxCall(query, variables);
|
|
} else {
|
|
throw err;
|
|
}
|
|
}
|
|
}
|
|
|
|
this.pool = config.dbPool;
|
|
|
|
if (!this.pool) {
|
|
throw new Error("Connection pool is required");
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
async getExtension(ext) {
|
|
ext = String(ext);
|
|
|
|
const query = gql`
|
|
query fetchExtension($extensionId: ID!) {
|
|
fetchExtension(extensionId: $extensionId) {
|
|
user {
|
|
extension
|
|
name
|
|
extPassword
|
|
voicemail
|
|
}
|
|
}
|
|
}
|
|
`;
|
|
|
|
const variables = {
|
|
extensionId: ext.match(/\d+/)[0],
|
|
};
|
|
|
|
return await this.pbxCall(query, variables);
|
|
}
|
|
|
|
async listExtensions() {
|
|
const query = gql`
|
|
query {
|
|
fetchAllExtensions {
|
|
extension {
|
|
user {
|
|
extension
|
|
name
|
|
}
|
|
}
|
|
}
|
|
}
|
|
`;
|
|
|
|
return await this.pbxCall(query);
|
|
}
|
|
|
|
async addExtension(ext, name) {
|
|
ext = String(ext);
|
|
name = String(name);
|
|
name = name.replace(/[^a-zA-Z0-9\s]/g, '');
|
|
const query = gql`
|
|
mutation addExtension($ext: ID!, $name: String!, $vmPassword: String!) {
|
|
addExtension(input: {
|
|
extensionId: $ext
|
|
name: $name
|
|
vmEnable: true
|
|
vmPassword: $vmPassword
|
|
email: ""
|
|
maxContacts: "100"
|
|
umEnable: false
|
|
}) {
|
|
status
|
|
}
|
|
}
|
|
`;
|
|
|
|
const variables = {
|
|
ext,
|
|
name,
|
|
vmPassword: ext,
|
|
};
|
|
|
|
return await this.pbxCall(query, variables);
|
|
}
|
|
|
|
async deleteExtension(ext) {
|
|
ext = String(ext);
|
|
const query = gql`
|
|
mutation deleteExtension($ext: ID!) {
|
|
deleteExtension(input: { extensionId: $ext }) {
|
|
status
|
|
}
|
|
}
|
|
`;
|
|
|
|
const variables = {
|
|
ext,
|
|
};
|
|
|
|
const fpbxQuery = this.pbxCall(query, variables);
|
|
const dbQuery = this.pool.query('DELETE FROM paging_groups WHERE ext = ?', [ext]);
|
|
return await Promise.all([fpbxQuery, dbQuery]);
|
|
}
|
|
|
|
async reload() {
|
|
const query = gql`
|
|
mutation {
|
|
doreload(input: { clientMutationId: "${Math.random().toString(36).substring(2, 14)}" }) {
|
|
status
|
|
}
|
|
}
|
|
`;
|
|
|
|
return await this.pbxCall(query);
|
|
}
|
|
|
|
// async updateName(ext, name) {
|
|
// const query = gql`
|
|
// mutation updateName($ext: ID!, $name: String!) {
|
|
// updateExtension(input: {extensionId: $ext, name: $name}) {
|
|
// status,
|
|
// message
|
|
// }
|
|
// }`;
|
|
|
|
// const variables = {
|
|
// ext,
|
|
// name,
|
|
// };
|
|
|
|
// return await this.pbxCall(query, variables);
|
|
// }
|
|
// TODO: Implement updateName method, Current implementation resets extension for some reason
|
|
|
|
async joinPageGroup(ext, pageGroup) {
|
|
const [lookup] = await this.pool.query('SELECT * FROM paging_groups WHERE page_number = ? AND ext = ?', [pageGroup, ext]);
|
|
if (lookup) {
|
|
return false;
|
|
}
|
|
|
|
await this.pool.query('INSERT INTO paging_groups (page_number, ext) VALUES (?, ?)', [pageGroup, ext]);
|
|
return true;
|
|
};
|
|
|
|
async leavePageGroup(ext, pageGroup) {
|
|
const [lookup] = await this.pool.query('SELECT * FROM paging_groups WHERE page_number = ? AND ext = ?', [pageGroup, ext]);
|
|
if (!lookup) {
|
|
return false;
|
|
}
|
|
|
|
await this.pool.query('DELETE FROM paging_groups WHERE page_number = ? AND ext = ?', [pageGroup, ext]);
|
|
return true;
|
|
};
|
|
|
|
async getNextAvailableExtension() {
|
|
const extList = await this.listExtensions();
|
|
const exts = extList.fetchAllExtensions.extension;
|
|
const startExt = process.env.START_EXT ? parseInt(process.env.START_EXT, 10) : 1000;
|
|
const existingExts = exts.map(ext => parseInt(ext.user.extension, 10)).sort((a, b) => a - b);
|
|
|
|
let nextExt = startExt;
|
|
for (let i = 0; i < existingExts.length; i++) {
|
|
if (existingExts[i] !== nextExt) {
|
|
break;
|
|
}
|
|
nextExt++;
|
|
}
|
|
|
|
return nextExt;
|
|
}
|
|
}
|
|
|
|
module.exports = FreepbxManager;
|