Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 16 additions & 18 deletions src/Slapp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,11 @@ export interface SlappOptions {
signingSecret?: ReceiverArguments['signingSecret'];
endpoints?: ReceiverArguments['endpoints'];
convoStore?: ConversationStore | false;
token?: string; // either token or teamContext
teamContext?: Authorize; // either token or teamContext
token?: string; // either token or authorize
authorize?: Authorize; // either token or authorize
receiver?: Receiver;
logger?: Logger;
logLevel?: LogLevel;
colors?: boolean;
ignoreSelf?: boolean;
ignoreBots?: boolean;
}
Expand All @@ -65,8 +64,9 @@ export interface AuthorizeSourceData {

/** Authorization function outputs - data that will be available as part of event processing */
export interface AuthorizeResult {
botToken?: string; // used by `say` (preferred over appToken, one is required)
appToken?: string; // used by `say` (overridden by botToken, one is required)
// one of either botToken or userToken are required
botToken?: string; // used by `say` (preferred over userToken)
userToken?: string; // used by `say` (overridden by botToken)
botId?: string; // required for `ignoreSelf` global middleware
botUserId?: string; // optional
[ key: string ]: any;
Expand Down Expand Up @@ -101,27 +101,25 @@ export default class Slapp {
receiver = undefined,
convoStore = undefined,
token = undefined,
teamContext = undefined,
authorize = undefined,
logger = new ConsoleLogger(),
logLevel = LogLevel.INFO,
colors = false,
ignoreSelf = false,
ignoreBots = false,
}: SlappOptions = {}) {

this.logger = logger;
this.logger.setLevel(logLevel);
// TODO: set colors

if (token !== undefined) {
if (teamContext !== undefined) {
throw new Error(`Both token and teamContext options provided. ${tokenUsage}`);
if (authorize !== undefined) {
throw new Error(`Both token and authorize options provided. ${tokenUsage}`);
}
this.authorize = async () => ({ botToken: token });
} else if (teamContext === undefined) {
throw new Error(`No token and no teamContext options provided. ${tokenUsage}`);
} else if (authorize === undefined) {
throw new Error(`No token and no authorize options provided. ${tokenUsage}`);
} else {
this.authorize = teamContext;
this.authorize = authorize;
}

this.middleware = [];
Expand Down Expand Up @@ -194,7 +192,7 @@ export default class Slapp {

// Factory for say() argument
const createSay = (channelId: string): SayFn => {
const token = context.botToken !== undefined ? context.botToken : context.appToken;
const token = context.botToken !== undefined ? context.botToken : context.userToken;
return (message: Parameters<SayFn>[0]) => {
const postMessageArguments: ChatPostMessageArguments = (typeof message === 'string') ?
{ token, text: message, channel: channelId } : { ...message, token, channel: channelId };
Expand Down Expand Up @@ -359,12 +357,12 @@ export default class Slapp {
Source extends 'interactive_message' | 'dialog_suggestion' | 'external_select' =
'interactive_message' | 'dialog_suggestion' | 'external_select'
>(
actionIdOrContraints: string | RegExp | ActionConstraints,
actionIdOrConstraints: string | RegExp | ActionConstraints,
...listeners: Middleware<SlackOptionsMiddlewareArgs<Source>>[]
): void {
const constraints: ActionConstraints =
(typeof actionIdOrContraints === 'string' || util.types.isRegExp(actionIdOrContraints)) ?
{ action_id: actionIdOrContraints } : actionIdOrContraints;
(typeof actionIdOrConstraints === 'string' || util.types.isRegExp(actionIdOrConstraints)) ?
{ action_id: actionIdOrConstraints } : actionIdOrConstraints;

this.listeners.push(
[onlyOptions, matchActionConstraints(constraints), ...listeners] as Middleware<AnyMiddlewareArgs>[],
Expand All @@ -373,7 +371,7 @@ export default class Slapp {
}

const tokenUsage = 'Apps used in one workspace should be initialized with a token. Apps used in many workspaces ' +
'should be initialized with a teamContext.';
'should be initialized with a authorize.';

/**
* Helper which builds the data structure the authorize hook uses to provide tokens for the context.
Expand Down
12 changes: 9 additions & 3 deletions src/middleware/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -466,9 +466,8 @@ export interface PostProcessFn {

// The say() utility function binds the message to the same channel as the incoming message that triggered the
// listener. Therefore, specifying the `channel` argument is not required.
type SayArguments = {
[Arg in keyof ChatPostMessageArguments]: Arg extends 'channel' ?
(ChatPostMessageArguments[Arg] | undefined) : ChatPostMessageArguments[Arg];
type SayArguments = Pick<ChatPostMessageArguments, Exclude<KnownKeys<ChatPostMessageArguments>, 'channel'>> & {
channel?: string;
};

export interface SayFn {
Expand All @@ -495,3 +494,10 @@ export interface ActionConstraints {
action_id?: string | RegExp;
callback_id?: string | RegExp;
}

/**
* Type helpers
*/
type KnownKeys<T> = {
[K in keyof T]: string extends K ? never : number extends K ? never : K
} extends { [_ in keyof T]: infer U } ? U : never;