|
@@ -1,5 +1,4 @@
|
|
|
-
|
|
|
|
|
-import { WebClient } from '@slack/web-api';
|
|
|
|
|
|
|
+import type { WebClient } from '@slack/web-api';
|
|
|
import axios, { type AxiosError } from 'axios';
|
|
import axios, { type AxiosError } from 'axios';
|
|
|
|
|
|
|
|
import { requiredScopes } from '../consts';
|
|
import { requiredScopes } from '../consts';
|
|
@@ -14,11 +13,12 @@ import { generateWebClient } from './webclient-factory';
|
|
|
* @param serverUri Server URI to connect
|
|
* @param serverUri Server URI to connect
|
|
|
* @returns AxiosError when error is occured
|
|
* @returns AxiosError when error is occured
|
|
|
*/
|
|
*/
|
|
|
-export const connectToHttpServer = async(serverUri: string): Promise<void|AxiosError> => {
|
|
|
|
|
|
|
+export const connectToHttpServer = async (
|
|
|
|
|
+ serverUri: string,
|
|
|
|
|
+): Promise<undefined | AxiosError> => {
|
|
|
try {
|
|
try {
|
|
|
await axios.get(serverUri, { maxRedirects: 0, timeout: 3000 });
|
|
await axios.get(serverUri, { maxRedirects: 0, timeout: 3000 });
|
|
|
- }
|
|
|
|
|
- catch (err) {
|
|
|
|
|
|
|
+ } catch (err) {
|
|
|
return err as AxiosError;
|
|
return err as AxiosError;
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
@@ -28,7 +28,9 @@ export const connectToHttpServer = async(serverUri: string): Promise<void|AxiosE
|
|
|
*
|
|
*
|
|
|
* @returns AxiosError when error is occured
|
|
* @returns AxiosError when error is occured
|
|
|
*/
|
|
*/
|
|
|
-export const connectToSlackApiServer = async(): Promise<void|AxiosError> => {
|
|
|
|
|
|
|
+export const connectToSlackApiServer = async (): Promise<
|
|
|
|
|
+ undefined | AxiosError
|
|
|
|
|
+> => {
|
|
|
return connectToHttpServer('https://slack.com/api/');
|
|
return connectToHttpServer('https://slack.com/api/');
|
|
|
};
|
|
};
|
|
|
|
|
|
|
@@ -36,7 +38,8 @@ export const connectToSlackApiServer = async(): Promise<void|AxiosError> => {
|
|
|
* Test Slack API
|
|
* Test Slack API
|
|
|
* @param client
|
|
* @param client
|
|
|
*/
|
|
*/
|
|
|
-const testSlackApiServer = async(client: WebClient): Promise<any> => {
|
|
|
|
|
|
|
+// biome-ignore lint/suspicious/noExplicitAny: ignore
|
|
|
|
|
+const testSlackApiServer = async (client: WebClient): Promise<any> => {
|
|
|
const result = await client.api.test();
|
|
const result = await client.api.test();
|
|
|
|
|
|
|
|
if (!result.ok) {
|
|
if (!result.ok) {
|
|
@@ -46,12 +49,17 @@ const testSlackApiServer = async(client: WebClient): Promise<any> => {
|
|
|
return result;
|
|
return result;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+// biome-ignore lint/suspicious/noExplicitAny: ignore
|
|
|
const checkSlackScopes = (resultTestSlackApiServer: any) => {
|
|
const checkSlackScopes = (resultTestSlackApiServer: any) => {
|
|
|
const slackScopes = resultTestSlackApiServer.response_metadata.scopes;
|
|
const slackScopes = resultTestSlackApiServer.response_metadata.scopes;
|
|
|
- const isPassedScopeCheck = requiredScopes.every(e => slackScopes.includes(e));
|
|
|
|
|
|
|
+ const isPassedScopeCheck = requiredScopes.every((e) =>
|
|
|
|
|
+ slackScopes.includes(e),
|
|
|
|
|
+ );
|
|
|
|
|
|
|
|
if (!isPassedScopeCheck) {
|
|
if (!isPassedScopeCheck) {
|
|
|
- throw new Error(`The scopes you registered are not appropriate. Required scopes are ${requiredScopes}`);
|
|
|
|
|
|
|
+ throw new Error(
|
|
|
|
|
+ `The scopes you registered are not appropriate. Required scopes are ${requiredScopes}`,
|
|
|
|
|
+ );
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
@@ -59,13 +67,14 @@ const checkSlackScopes = (resultTestSlackApiServer: any) => {
|
|
|
* Retrieve Slack workspace name
|
|
* Retrieve Slack workspace name
|
|
|
* @param client
|
|
* @param client
|
|
|
*/
|
|
*/
|
|
|
-const retrieveWorkspaceName = async(client: WebClient): Promise<string> => {
|
|
|
|
|
|
|
+const retrieveWorkspaceName = async (client: WebClient): Promise<string> => {
|
|
|
const result = await client.team.info();
|
|
const result = await client.team.info();
|
|
|
|
|
|
|
|
if (!result.ok) {
|
|
if (!result.ok) {
|
|
|
throw new Error(result.error);
|
|
throw new Error(result.error);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // biome-ignore lint/suspicious/noExplicitAny: ignore
|
|
|
return (result as any).team?.name;
|
|
return (result as any).team?.name;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
@@ -73,7 +82,9 @@ const retrieveWorkspaceName = async(client: WebClient): Promise<string> => {
|
|
|
* @param token bot OAuth token
|
|
* @param token bot OAuth token
|
|
|
* @returns
|
|
* @returns
|
|
|
*/
|
|
*/
|
|
|
-export const getConnectionStatus = async(token:string): Promise<ConnectionStatus> => {
|
|
|
|
|
|
|
+export const getConnectionStatus = async (
|
|
|
|
|
+ token: string,
|
|
|
|
|
+): Promise<ConnectionStatus> => {
|
|
|
const client = generateWebClient(token);
|
|
const client = generateWebClient(token);
|
|
|
const status: ConnectionStatus = {};
|
|
const status: ConnectionStatus = {};
|
|
|
|
|
|
|
@@ -84,8 +95,7 @@ export const getConnectionStatus = async(token:string): Promise<ConnectionStatus
|
|
|
await checkSlackScopes(resultTestSlackApiServer);
|
|
await checkSlackScopes(resultTestSlackApiServer);
|
|
|
// retrieve workspace name
|
|
// retrieve workspace name
|
|
|
status.workspaceName = await retrieveWorkspaceName(client);
|
|
status.workspaceName = await retrieveWorkspaceName(client);
|
|
|
- }
|
|
|
|
|
- catch (err) {
|
|
|
|
|
|
|
+ } catch (err) {
|
|
|
status.error = err as Error;
|
|
status.error = err as Error;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -98,35 +108,43 @@ export const getConnectionStatus = async(token:string): Promise<ConnectionStatus
|
|
|
* @param botTokenResolver function to convert from key to token
|
|
* @param botTokenResolver function to convert from key to token
|
|
|
* @returns
|
|
* @returns
|
|
|
*/
|
|
*/
|
|
|
-export const getConnectionStatuses = async(keys: string[], botTokenResolver?: (key: string) => string): Promise<{[key: string]: ConnectionStatus}> => {
|
|
|
|
|
- const map = keys
|
|
|
|
|
- .reduce<Promise<Map<string, ConnectionStatus>>>(
|
|
|
|
|
- async(acc, key) => {
|
|
|
|
|
- let token = key;
|
|
|
|
|
- if (botTokenResolver != null) {
|
|
|
|
|
- token = botTokenResolver(key);
|
|
|
|
|
- }
|
|
|
|
|
- const status: ConnectionStatus = await getConnectionStatus(token);
|
|
|
|
|
-
|
|
|
|
|
- (await acc).set(key, status);
|
|
|
|
|
- return acc;
|
|
|
|
|
- },
|
|
|
|
|
- // define initial accumulator
|
|
|
|
|
- Promise.resolve(new Map<string, ConnectionStatus>()),
|
|
|
|
|
- );
|
|
|
|
|
|
|
+export const getConnectionStatuses = async (
|
|
|
|
|
+ keys: string[],
|
|
|
|
|
+ botTokenResolver?: (key: string) => string,
|
|
|
|
|
+): Promise<{ [key: string]: ConnectionStatus }> => {
|
|
|
|
|
+ const map = keys.reduce<Promise<Map<string, ConnectionStatus>>>(
|
|
|
|
|
+ async (acc, key) => {
|
|
|
|
|
+ let token = key;
|
|
|
|
|
+ if (botTokenResolver != null) {
|
|
|
|
|
+ token = botTokenResolver(key);
|
|
|
|
|
+ }
|
|
|
|
|
+ const status: ConnectionStatus = await getConnectionStatus(token);
|
|
|
|
|
+
|
|
|
|
|
+ (await acc).set(key, status);
|
|
|
|
|
+ return acc;
|
|
|
|
|
+ },
|
|
|
|
|
+ // define initial accumulator
|
|
|
|
|
+ Promise.resolve(new Map<string, ConnectionStatus>()),
|
|
|
|
|
+ );
|
|
|
|
|
|
|
|
// convert to object
|
|
// convert to object
|
|
|
return Object.fromEntries(await map);
|
|
return Object.fromEntries(await map);
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-export const sendSuccessMessage = async(token:string, channel:string, appSiteUrl:string): Promise<void> => {
|
|
|
|
|
|
|
+export const sendSuccessMessage = async (
|
|
|
|
|
+ token: string,
|
|
|
|
|
+ channel: string,
|
|
|
|
|
+ appSiteUrl: string,
|
|
|
|
|
+): Promise<void> => {
|
|
|
const client = generateWebClient(token);
|
|
const client = generateWebClient(token);
|
|
|
await client.chat.postMessage({
|
|
await client.chat.postMessage({
|
|
|
channel,
|
|
channel,
|
|
|
text: 'Success',
|
|
text: 'Success',
|
|
|
blocks: [
|
|
blocks: [
|
|
|
markdownSectionBlock(`:tada: Successfully tested with ${appSiteUrl}.`),
|
|
markdownSectionBlock(`:tada: Successfully tested with ${appSiteUrl}.`),
|
|
|
- markdownSectionBlock('Now your GROWI and Slack integration is ready to use :+1:'),
|
|
|
|
|
|
|
+ markdownSectionBlock(
|
|
|
|
|
+ 'Now your GROWI and Slack integration is ready to use :+1:',
|
|
|
|
|
+ ),
|
|
|
],
|
|
],
|
|
|
});
|
|
});
|
|
|
};
|
|
};
|