@@ -1057,10 +1057,22 @@ function _help(input, channel) {
1057
1057
const adminMessage = fs . readFileSync ( helpTextPathAdmin , 'utf8' ) ;
1058
1058
let message = fs . readFileSync ( helpTextPath , 'utf8' ) ;
1059
1059
1060
+ // Read configuration values
1061
+ const gongLimit = config . get ( 'gongLimit' ) ;
1062
+ const voteLimit = config . get ( 'voteLimit' ) ;
1063
+ const flushVoteLimit = config . get ( 'flushVoteLimit' ) ;
1064
+ const maxVolume = config . get ( 'maxVolume' ) ;
1065
+
1066
+ // Replace placeholders in help text
1067
+ message = message . replace ( / { { gongLimit} } / g, gongLimit ) ;
1068
+ message = message . replace ( / { { voteLimit} } / g, voteLimit ) ;
1069
+ message = message . replace ( / { { flushVoteLimit} } / g, flushVoteLimit ) ;
1070
+ message = message . replace ( / { { maxVolume} } / g, maxVolume ) ;
1071
+
1060
1072
if ( channel === global . adminChannel ) {
1061
1073
message += '\n' + adminMessage ;
1062
1074
}
1063
- _slackMessage ( message , channel )
1075
+ _slackMessage ( message , channel ) ;
1064
1076
}
1065
1077
1066
1078
function _play ( input , channel , userName , state ) {
@@ -1788,49 +1800,19 @@ function _status(channel, state) {
1788
1800
} )
1789
1801
}
1790
1802
1791
- // Ensure the _debug function is defined
1803
+
1804
+
1792
1805
async function _debug ( channel , userName ) {
1793
1806
_logUserAction ( userName , 'debug' ) ;
1794
1807
var url = 'http://' + sonosIp + ':1400/xml/device_description.xml' ;
1795
1808
1796
- // Function to get the IP address of the machine (Docker container if inside Docker)
1797
- function getIPAddress ( ) {
1798
- const interfaces = os . networkInterfaces ( ) ;
1799
- for ( const name of Object . keys ( interfaces ) ) {
1800
- for ( const iface of interfaces [ name ] ) {
1801
- if ( iface . family === 'IPv4' && ! iface . internal ) {
1802
- return iface . address ;
1803
- }
1804
- }
1805
- }
1806
- return 'IP address not found' ;
1807
- }
1808
-
1809
- // Improved function to check if running inside Docker
1810
- function isRunningInDocker ( ) {
1811
- try {
1812
- // Check if running in Docker by inspecting /proc/1/cgroup and the presence of .dockerenv
1813
- const cgroup = fs . readFileSync ( '/proc/1/cgroup' , 'utf8' ) ;
1814
- if ( cgroup . includes ( 'docker' ) ) {
1815
- return true ;
1816
- }
1817
- } catch ( err ) {
1818
- // Ignore errors, continue to next check
1819
- }
1820
-
1821
- try {
1822
- // Check if .dockerenv file exists (another indication of being inside Docker)
1823
- if ( fs . existsSync ( '/.dockerenv' ) ) {
1824
- return true ;
1825
- }
1826
- } catch ( err ) {
1827
- // Ignore errors
1809
+ function maskSensitiveInfo ( value ) {
1810
+ if ( typeof value === 'string' && value . length > 6 ) {
1811
+ return value . slice ( 0 , 3 ) + '--xxx-MASKED-xxx--' + value . slice ( - 3 ) ;
1828
1812
}
1829
-
1830
- return false ; // Default to not inside Docker if all checks fail
1813
+ return value ;
1831
1814
}
1832
1815
1833
- // Function to get the host's IP address if running inside Docker
1834
1816
function getHostIPAddress ( ) {
1835
1817
try {
1836
1818
const result = fs . readFileSync ( '/proc/net/route' , 'utf8' ) ;
@@ -1853,7 +1835,6 @@ async function _debug(channel, userName) {
1853
1835
}
1854
1836
}
1855
1837
1856
- // Helper function to convert hex IP from /proc/net/route to a readable IP address
1857
1838
function hexToIp ( hex ) {
1858
1839
return [
1859
1840
parseInt ( hex . slice ( 6 , 8 ) , 16 ) ,
@@ -1863,25 +1844,36 @@ async function _debug(channel, userName) {
1863
1844
] . join ( '.' ) ;
1864
1845
}
1865
1846
1866
- const isDocker = isRunningInDocker ( ) ; // Improved check for Docker environment
1847
+ const isRunningInDocker = ( ) => {
1848
+ try {
1849
+ const cgroup = fs . readFileSync ( '/proc/1/cgroup' , 'utf8' ) ;
1850
+ if ( cgroup . includes ( 'docker' ) ) {
1851
+ return true ;
1852
+ }
1853
+ } catch ( err ) { }
1854
+
1855
+ try {
1856
+ if ( fs . existsSync ( '/.dockerenv' ) ) {
1857
+ return true ;
1858
+ }
1859
+ } catch ( err ) { }
1860
+
1861
+ return false ;
1862
+ } ;
1863
+
1864
+ const isDocker = isRunningInDocker ( ) ;
1867
1865
1868
1866
if ( isDocker ) {
1869
- // Check if IP is defined in the environment
1870
- // Get the IP address from the configuration
1871
- console . log ( 'IP Address from config:' , ipAddress ) ;
1872
1867
if ( ! ipAddress ) {
1873
- // Log error and set a default value for IP
1874
1868
const warningMessage = 'Make sure you have configured IP in the config.json' ;
1875
1869
logger . error ( warningMessage ) ;
1876
- ipAddress = warningMessage ; // Set the value of IP to the warning message
1870
+ ipAddress = warningMessage ;
1877
1871
}
1878
1872
} else {
1879
- ipAddress = getIPAddress ( ) ; // IP of the machine if not in Docker
1873
+ ipAddress = getIPAddress ( ) ;
1880
1874
}
1881
1875
1882
- const dockerIPAddress = isDocker ? getHostIPAddress ( ) : null ; // Host IP if running inside Docker
1883
-
1884
- // Define nodeVersion outside the if block
1876
+ const dockerIPAddress = isDocker ? getHostIPAddress ( ) : null ;
1885
1877
const nodeVersion = JSON . stringify ( process . versions ) ;
1886
1878
1887
1879
xmlToJson ( url , async function ( err , data ) {
@@ -1890,86 +1882,35 @@ async function _debug(channel, userName) {
1890
1882
logger . error ( 'Error occurred ' + err ) ;
1891
1883
sonosInfo = 'SONOS device is offline or not responding.' ;
1892
1884
} else {
1893
- logger . info ( 'BuildNumber of SlackONOS: ' , buildNumber ) ;
1894
- logger . info ( 'Platform: ' , process . platform ) ;
1895
- logger . info ( 'Node version: ' , process . version ) ;
1896
- logger . info ( 'Node dependencies: ' , process . versions ) ;
1897
-
1898
- // Log Sonos information
1899
- logger . info ( data . root . device [ 0 ] . modelDescription ) ;
1900
- logger . info ( data . root . device [ 0 ] . softwareVersion ) ;
1901
- logger . info ( data . root . device [ 0 ] . displayName ) ;
1902
- logger . info ( data . root . device [ 0 ] . hardwareVersion ) ;
1903
- logger . info ( data . root . device [ 0 ] . apiVersion ) ;
1904
- logger . info ( data . root . device [ 0 ] . roomName ) ;
1905
- logger . info ( data . root . device [ 0 ] . friendlyName ) ;
1906
- logger . info ( data . root . device [ 0 ] . modelNumber ) ;
1907
- logger . info ( data . root . device [ 0 ] . serialNum ) ;
1908
- logger . info ( data . root . device [ 0 ] . MACAddress ) ;
1909
-
1910
1885
sonosInfo =
1911
1886
'\n*Sonos Info*' +
1912
- '\nFriendly Name: ' + ( data . root . device [ 0 ] . friendlyName ) +
1913
- '\nRoom Name: ' + ( data . root . device [ 0 ] . roomName ) +
1914
- '\nDisplay Name: ' + ( data . root . device [ 0 ] . displayName ) +
1915
- '\nModel Description: ' + ( data . root . device [ 0 ] . modelDescription ) +
1916
- '\nModelNumber: ' + ( data . root . device [ 0 ] . modelNumber ) +
1917
- '\nSerial Number: ' + ( data . root . device [ 0 ] . serialNum ) +
1918
- '\nMAC Address: ' + ( data . root . device [ 0 ] . MACAddress ) +
1919
- '\nSW Version: ' + ( data . root . device [ 0 ] . softwareVersion ) +
1920
- '\nHW Version: ' + ( data . root . device [ 0 ] . hardwareVersion ) +
1921
- '\nAPI Version: ' + ( data . root . device [ 0 ] . apiVersion ) ;
1887
+ '\nFriendly Name: ' + data . root . device [ 0 ] . friendlyName ;
1922
1888
}
1923
1889
1924
- // Get memory usage
1925
1890
const memoryUsage = process . memoryUsage ( ) ;
1926
- const formattedMemoryUsage = `
1927
- *Memory Usage*:
1928
- RSS: ${ Math . round ( memoryUsage . rss / 1024 / 1024 ) } MB
1929
- Heap Total: ${ Math . round ( memoryUsage . heapTotal / 1024 / 1024 ) } MB
1930
- Heap Used: ${ Math . round ( memoryUsage . heapUsed / 1024 / 1024 ) } MB
1931
- External: ${ Math . round ( memoryUsage . external / 1024 / 1024 ) } MB
1932
- Array Buffers: ${ Math . round ( memoryUsage . arrayBuffers / 1024 / 1024 ) } MB
1933
- ` ;
1934
-
1935
- // Get uptime
1936
- const uptime = process . uptime ( ) ;
1937
- const formattedUptime = `
1938
- *Uptime*: ${ Math . floor ( uptime / 60 ) } minutes ${ Math . floor ( uptime % 60 ) } seconds
1939
- ` ;
1940
-
1941
- // Get network interfaces
1942
- const networkInterfaces = os . networkInterfaces ( ) ;
1943
- const formattedNetworkInterfaces = Object . entries ( networkInterfaces ) . map ( ( [ name , addresses ] ) => {
1944
- return addresses . map ( addr => `${ name } : ${ addr . address } ` ) . join ( '\n' ) ;
1945
- } ) . join ( '\n' ) ;
1946
-
1947
- // Get disk usage (example for Unix-like systems)
1948
- const diskUsage = execSync ( 'df -h /' ) . toString ( ) ;
1949
- const formattedDiskUsage = `
1950
- *Disk Usage*:
1951
- ${ diskUsage }
1952
- ` ;
1953
-
1954
-
1955
-
1956
- // Read configuration values only from config.json
1957
- const configKeys = Object . keys ( config . stores . file . store ) ; // Access only the file-based store
1958
- const configValues = configKeys . map ( key => `${ key } : ${ config . get ( key ) } ` ) . join ( '\n' ) ;
1959
-
1960
- // Debug log for verification
1961
- logger . info ( 'DEBUG -- Config values from config.json: ' + configValues ) ;
1962
-
1963
- // Ensure environment variables are handled separately
1964
- const envVars = `
1965
- *Environment Variables*:
1966
- NODE_VERSION: ${ process . env . NODE_VERSION || 'not set' }
1967
- HOSTNAME: ${ process . env . HOSTNAME || 'not set' }
1968
- YARN_VERSION: ${ process . env . YARN_VERSION || 'not set' }
1969
- HOME: ${ process . env . HOME || 'not set' }
1970
- PATH: ${ process . env . PATH }
1971
- PWD: ${ process . env . PWD }
1972
- ` ;
1891
+ const formattedMemoryUsage = `\n*Memory Usage*:\n RSS: ${ Math . round ( memoryUsage . rss / 1024 / 1024 ) } MB` ;
1892
+
1893
+ const envVars = `\n*Environment Variables*:\n NODE_VERSION: ${ process . env . NODE_VERSION || 'not set' } \n HOSTNAME: ${ process . env . HOSTNAME || 'not set' } \n YARN_VERSION: ${ process . env . YARN_VERSION || 'not set' } ` ;
1894
+
1895
+ const sensitiveKeys = [ 'token' , 'spotifyClientId' , 'spotifyClientSecret' , 'openaiApiKey' ] ;
1896
+ const configKeys = Object . keys ( config . stores . file . store ) ;
1897
+ const configValues = configKeys
1898
+ . map ( key => {
1899
+ const value = config . get ( key ) ;
1900
+ return sensitiveKeys . includes ( key ) ? `${ key } : ${ maskSensitiveInfo ( value ) } ` : `${ key } : ${ value } ` ;
1901
+ } )
1902
+ . join ( '\n' ) ;
1903
+
1904
+ // Identify missing configuration values
1905
+ const defaultConfig = config . stores . defaults . store ;
1906
+ const missingConfigValues = Object . keys ( defaultConfig )
1907
+ . filter ( key => ! configKeys . includes ( key ) )
1908
+ . map ( key => {
1909
+ const value = defaultConfig [ key ] . value || defaultConfig [ key ] ;
1910
+ return value === 'literal' ? null : `${ key } : ${ value } ` ;
1911
+ } )
1912
+ . filter ( line => line !== null ) // Remove excluded entries
1913
+ . join ( '\n' ) ;
1973
1914
1974
1915
const blocks = [
1975
1916
{
@@ -2012,16 +1953,6 @@ ${diskUsage}
2012
1953
{
2013
1954
type : 'divider'
2014
1955
} ,
2015
- {
2016
- type : 'section' ,
2017
- text : {
2018
- type : 'mrkdwn' ,
2019
- text : formattedUptime
2020
- }
2021
- } ,
2022
- {
2023
- type : 'divider'
2024
- } ,
2025
1956
{
2026
1957
type : 'section' ,
2027
1958
text : {
@@ -2032,45 +1963,30 @@ ${diskUsage}
2032
1963
{
2033
1964
type : 'divider'
2034
1965
} ,
2035
- {
2036
- type : 'section' ,
2037
- text : {
2038
- type : 'mrkdwn' ,
2039
- text : '*Network Interfaces*\n' + formattedNetworkInterfaces
2040
- }
2041
- } ,
2042
- {
2043
- type : 'divider'
2044
- } ,
2045
- {
2046
- type : 'section' ,
2047
- text : {
2048
- type : 'mrkdwn' ,
2049
- text : formattedDiskUsage
2050
- }
2051
- } ,
2052
- {
2053
- type : 'divider'
2054
- } ,
2055
1966
{
2056
1967
type : 'section' ,
2057
1968
text : {
2058
1969
type : 'mrkdwn' ,
2059
1970
text : '*Configuration Values*\n' + configValues
2060
1971
}
2061
- } ,
2062
- {
2063
- type : 'divider'
2064
- } ,
2065
- {
2066
- type : 'section' ,
2067
- text : {
2068
- type : 'mrkdwn' ,
2069
- text : envVars
2070
- }
2071
1972
}
2072
1973
] ;
2073
1974
1975
+ if ( missingConfigValues ) {
1976
+ blocks . push (
1977
+ {
1978
+ type : 'divider'
1979
+ } ,
1980
+ {
1981
+ type : 'section' ,
1982
+ text : {
1983
+ type : 'mrkdwn' ,
1984
+ text : '*Missing Configuration Values*\n' + missingConfigValues
1985
+ }
1986
+ }
1987
+ ) ;
1988
+ }
1989
+
2074
1990
const message = {
2075
1991
channel : channel ,
2076
1992
blocks : blocks
@@ -2089,6 +2005,7 @@ ${diskUsage}
2089
2005
2090
2006
2091
2007
2008
+
2092
2009
async function _blacklist ( input , channel , userName ) {
2093
2010
_logUserAction ( userName , 'blacklist' ) ;
2094
2011
if ( channel !== global . adminChannel ) {
0 commit comments