Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds Block types #688

Merged
merged 9 commits into from
Feb 13, 2019
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
107 changes: 78 additions & 29 deletions docs/_pages/web_client.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ redirect_from: /basic_usage
order: 2
headings:
- title: Posting a message
- title: Adding attachments to a message
- title: Customizing a message layout
- title: Uploading a file
- title: Getting a list of channels
- title: Using refresh tokens
Expand All @@ -20,6 +20,7 @@ headings:
- title: Customizing the logger
- title: Custom agent for proxy support
- title: OAuth token exchange
- title: Using legacy message attachments
---

This package includes a web client that makes it simple to use the
Expand Down Expand Up @@ -68,37 +69,46 @@ web.chat.postMessage({ channel: conversationId, text: 'Hello there' })

---

### Adding attachments to a message
### Customizing a message layout

The `chat.postMessage` method takes an optional `attachments` argument. Arguments for Web API methods are all specified
in a single object literal, so just add additional keys for any optional argument.
The `chat.postMessage` method takes an optional `blocks` argument that allows you to customize the layout of a message.
Blocks for Web API methods are all specified in a single object literal, so just add additional keys for any
optional argument.

[Learn more about customize message layouts on the API site](https://api.slack.com/messaging/composing/layouts).

```javascript
web.chat.postMessage({
channel: conversationId,
text: 'Hello there',
attachments: [
blocks: [
{
"fallback": "Required plain-text summary of the attachment.",
"color": "#36a64f",
"author_name": "Bobby Tables",
"author_link": "http://flickr.com/bobby/",
"author_icon": "http://flickr.com/icons/bobby.jpg",
"title": "Slack API Documentation",
"title_link": "https://api.slack.com/",
"text": "Optional text that appears within the attachment",
"fields": [
{
"title": "Priority",
"value": "High",
"short": false
"type": "section",
"text": {
"type": "mrkdwn",
"text": "Danny Torrence left the following review for your property:"
}
],
"image_url": "http://my-website.com/path/to/image.jpg",
"thumb_url": "http://example.com/path/to/thumb.png",
"footer": "Slack API",
"footer_icon": "https://platform.slack-edge.com/img/default_application_icon.png",
"ts": 123456789
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "<https://example.com|Overlook Hotel> \n :star: \n Doors had too many axe holes, guest in room " +
"237 was far too rowdy, whole place felt stuck in the 1920s."
},
"accessory": {
"type": "image",
"image_url": "https://images.pexels.com/photos/750319/pexels-photo-750319.jpeg",
"alt_text": "Haunted hotel image"
}
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Average Rating*\n1.0"
}
]
}
]
})
Expand All @@ -109,10 +119,8 @@ web.chat.postMessage({
.catch(console.error);
```

**NOTE**: See the [Message Builder](https://api.slack.com/docs/messages/builder) for a playground
where you can prototype your message's look.

---
**NOTE**: Use the [Block Kit Builder](https://api.slack.com/tools/block-kit-builder) for a playground
where you can prototype your message's look and feel.

### Uploading a file

Expand Down Expand Up @@ -660,4 +668,45 @@ client.oauth.access({
.catch(console.error);
```

---

### Using legacy message attachments

While we recommend using the more flexible top-level blocks to display message content, attachments are still supported anywhere you construct a message (like `chat.postMessage`). Just use the `attachments` key like you're
accustomed to:

```javascript
web.chat.postMessage({
channel: conversationId,
text: 'Hello there',
attachments: [
{
"fallback": "Required plain-text summary of the attachment.",
"color": "#36a64f",
"author_name": "Bobby Tables",
"author_link": "http://flickr.com/bobby/",
"author_icon": "http://flickr.com/icons/bobby.jpg",
"title": "Slack API Documentation",
"title_link": "https://api.slack.com/",
"text": "Optional text that appears within the attachment",
"fields": [
{
"title": "Priority",
"value": "High",
"short": false
}
],
"image_url": "http://my-website.com/path/to/image.jpg",
"thumb_url": "http://example.com/path/to/thumb.png",
"footer": "Slack API",
"footer_icon": "https://platform.slack-edge.com/img/default_application_icon.png",
"ts": 123456789
}
]
})
.then((res) => {
// `res` contains information about the posted message
console.log('Message sent: ', res.ts);
})
.catch(console.error);
```
3 changes: 2 additions & 1 deletion src/IncomingWebhook.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import axios, { AxiosInstance, AxiosResponse, AxiosError } from 'axios';
import { CodedError, errorWithCode, ErrorCode } from './errors';
import { MessageAttachment } from './methods';
import { MessageAttachment, Block } from './methods';
import { callbackify, AgentOption, agentForScheme } from './util';

/**
Expand Down Expand Up @@ -105,6 +105,7 @@ export interface IncomingWebhookDefaultArguments {

export interface IncomingWebhookSendArguments extends IncomingWebhookDefaultArguments {
attachments?: MessageAttachment[];
blocks?: Block[];
unfurl_links?: boolean;
unful_media?: boolean;
}
Expand Down
151 changes: 151 additions & 0 deletions src/methods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,155 @@ export interface Dialog {
state?: string;
}

/*
* Block Elements
*/

export interface ImageElement {
type: 'image';
image_url: string;
alt_text: string;
}

export interface UserElement {
type: 'user';
user_id: string;
}

export interface PlainTextElement {
type: 'plain_text';
text: string;
emoji?: boolean;
}

export interface MrkdwnElement {
type: 'mrkdwn';
text: string;
verbatim?: boolean;
}

export interface Option {
text: PlainTextElement;
value?: string;
url?: string;
description?: PlainTextElement;
}

export interface Confirm {
title?: PlainTextElement;
text: PlainTextElement | MrkdwnElement;
confirm?: PlainTextElement;
deny?: PlainTextElement;
}

/*
* Action Types
*/

type KnownAction = UsersSelect | StaticSelect | ConversationsSelect | ChannelsSelect | ExternalSelect |
Button | Overflow | Datepicker;

interface Action {
type: string;
action_id?: string;
confirm?: Confirm;
}

export interface UsersSelect extends Action {
type: 'users_select';
initial_user?: string;
placeholder?: PlainTextElement;
}

export interface StaticSelect extends Action {
type: 'static_select';
placeholder?: PlainTextElement;
initial_option?: Option;
options?: Option[];
option_groups?: {
label: PlainTextElement;
options: Option[];
}[];
}

export interface ConversationsSelect extends Action {
type: 'conversations_select';
initial_conversation?: string;
placeholder?: PlainTextElement;
}

export interface ChannelsSelect extends Action {
type: 'channels_select';
initial_channel?: string;
placeholder?: PlainTextElement;
}

export interface ExternalSelect extends Action {
type: 'external_select';
initial_option?: Option;
placeholder?: PlainTextElement;
min_query_length?: number;
}

export interface Button extends Action {
type: 'button';
text: PlainTextElement;
value?: string;
url?: string;
}

export interface Overflow extends Action {
type: 'overflow';
options: Option[];
}

export interface Datepicker extends Action {
type: 'datepicker';
initial_date?: string;
placeholder?: PlainTextElement;
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add a type for KnownAction (or pick a better name) that is the union of all the types that extend Action.

/*
* Block Types
*/

export type KnownBlock = ImageBlock | ContextBlock | ActionsBlock | DividerBlock | SectionBlock;

export interface Block {
type: string;
block_id?: string;
}

export interface ImageBlock extends Block {
type: 'image';
image_url: string;
alt_text: string;
title?: PlainTextElement;
}

export interface ContextBlock extends Block {
type: 'context';
elements: (ImageElement | UserElement | PlainTextElement | MrkdwnElement)[];
}

export interface ActionsBlock extends Block {
type: 'actions';
elements: (KnownAction | Action)[];
}

export interface DividerBlock extends Block {
type: 'divider';
}

export interface SectionBlock extends Block {
type: 'section';
text?: PlainTextElement | MrkdwnElement; // either this or fields must be defined
fields?: (PlainTextElement | MrkdwnElement)[]; // either this or text must be defined
accessory?: KnownAction | Action | ImageElement;
}

export interface MessageAttachment {
blocks?: (KnownBlock | Block)[];
fallback?: string; // either this or text must be defined
color?: 'good' | 'warning' | 'danger' | string;
pretext?: string;
Expand Down Expand Up @@ -294,6 +442,7 @@ export type ChatPostEphemeralArguments = TokenOverridable & {
user: string;
as_user?: boolean;
attachments?: MessageAttachment[];
blocks?: (KnownBlock | Block)[];
link_names?: boolean;
parse?: 'full' | 'none';
};
Expand All @@ -302,6 +451,7 @@ export type ChatPostMessageArguments = TokenOverridable & {
text: string;
as_user?: boolean;
attachments?: MessageAttachment[];
blocks?: (KnownBlock | Block)[];
icon_emoji?: string; // if specified, as_user must be false
icon_url?: string;
link_names?: boolean;
Expand All @@ -327,6 +477,7 @@ export type ChatUpdateArguments = TokenOverridable & {
ts: string;
as_user?: boolean;
attachments?: MessageAttachment[];
blocks?: (KnownBlock | Block)[];
link_names?: boolean;
parse?: 'full' | 'none';
};
Expand Down
4 changes: 2 additions & 2 deletions support/jsdoc/@slack-client-dist-logger.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,13 @@ export class Logger {
}

/**
* INTERNAL interface for getting or creating a named Logger
* INTERNAL interface for getting or creating a named Logger.
* @param {string} name
* @returns {module:@slack/client/dist/logger.Logger}
*/
export function getLogger() {}
/**
* INTERNAL function for transforming an external LoggerFunc type into the internal Logger interface
* INTERNAL function for transforming an external LoggingFunc type into the internal Logger interface.
* @param {string} name
* @param {module:@slack/client.LoggingFunc} loggingFunc
* @returns {module:@slack/client/dist/logger.Logger}
Expand Down
Loading