discord-freepbx-manager/freepbx.js

186 lines
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 = new FreepbxGqlClient(config.url, {
client: {
id: config.clientId,
secret: config.clientSecret,
},
});
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.client.request(query, variables);
}
async listExtensions() {
const query = gql`
query {
fetchAllExtensions {
extension {
user {
extension
name
}
}
}
}
`;
return await this.client.request(query);
}
async addExtension(ext, name) {
ext = String(ext);
name = String(name);
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.client.request(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.client.request(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.client.request(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.client.request(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;