Official library for using the Slack Platform's Web API
—
Pin and unpin messages in channels, and retrieve lists of pinned items. Pinned messages are highlighted items that stay easily accessible at the top of a channel for important information or reference.
Pin a message to a channel to highlight it as important.
/**
* Pin an item to a channel
* @param options - Message parameters to pin
* @returns Promise resolving to success confirmation
*/
pins.add(options: PinsAddArguments): Promise<PinsAddResponse>;
interface PinsAddArguments extends MessageArgument, TokenOverridable {}
interface MessageArgument {
/** Channel containing the message */
channel: string;
/** Timestamp of the message to pin */
timestamp: string;
}
interface PinsAddResponse extends WebAPICallResult {
/** Whether the pin was successfully added */
ok: boolean;
}Usage Examples:
import { WebClient } from "@slack/web-api";
const web = new WebClient(process.env.SLACK_BOT_TOKEN);
// Pin a message to a channel
await web.pins.add({
channel: "C1234567890",
timestamp: "1234567890.123456"
});Retrieve all pinned items in a specific channel.
/**
* List items pinned to a channel
* @param options - Channel parameters
* @returns Promise resolving to list of pinned items
*/
pins.list(options: PinsListArguments): Promise<PinsListResponse>;
interface PinsListArguments extends TokenOverridable {
/** Channel to get pinned items for */
channel: string;
}
interface PinsListResponse extends WebAPICallResult {
/** Array of pinned items */
items?: PinnedItem[];
/** Total count of pinned items */
count?: number;
}
interface PinnedItem {
/** Type of pinned item ('message', 'file', etc.) */
type?: string;
/** Channel ID where item is pinned */
channel?: string;
/** User who pinned the item */
created_by?: string;
/** Timestamp when item was pinned */
created?: number;
/** Message object (if type is 'message') */
message?: Message;
/** File object (if type is 'file') */
file?: File;
/** File comment object (if type is 'file_comment') */
comment?: FileComment;
}Usage Examples:
// Get all pinned items in a channel
const pinnedItems = await web.pins.list({
channel: "C1234567890"
});
console.log(`Found ${pinnedItems.count} pinned items`);
// Process different types of pinned items
pinnedItems.items?.forEach(item => {
switch (item.type) {
case 'message':
console.log(`Pinned message: ${item.message?.text}`);
break;
case 'file':
console.log(`Pinned file: ${item.file?.name}`);
break;
case 'file_comment':
console.log(`Pinned file comment: ${item.comment?.comment}`);
break;
}
});Remove a pin from a message in a channel.
/**
* Remove a pin from an item in a channel
* @param options - Message parameters to unpin
* @returns Promise resolving to success confirmation
*/
pins.remove(options: PinsRemoveArguments): Promise<PinsRemoveResponse>;
interface PinsRemoveArguments extends MessageArgument, TokenOverridable {}
interface PinsRemoveResponse extends WebAPICallResult {
/** Whether the pin was successfully removed */
ok: boolean;
}Usage Examples:
// Remove a pin from a message
await web.pins.remove({
channel: "C1234567890",
timestamp: "1234567890.123456"
});
// Remove all pins from a channel (requires iteration)
const pinnedItems = await web.pins.list({
channel: "C1234567890"
});
for (const item of pinnedItems.items || []) {
if (item.type === 'message' && item.message?.ts) {
await web.pins.remove({
channel: "C1234567890",
timestamp: item.message.ts
});
}
}Check if a message is already pinned before adding:
const checkAndPin = async (channel: string, timestamp: string) => {
const pinnedItems = await web.pins.list({ channel });
const isAlreadyPinned = pinnedItems.items?.some(
item => item.type === 'message' && item.message?.ts === timestamp
);
if (!isAlreadyPinned) {
await web.pins.add({ channel, timestamp });
console.log('Message pinned successfully');
} else {
console.log('Message is already pinned');
}
};Maintain a maximum number of pins by removing oldest when adding new:
const pinWithRotation = async (channel: string, timestamp: string, maxPins = 5) => {
const pinnedItems = await web.pins.list({ channel });
// If at max capacity, remove oldest pin
if (pinnedItems.items && pinnedItems.items.length >= maxPins) {
const oldestPin = pinnedItems.items
.filter(item => item.type === 'message')
.sort((a, b) => (a.created || 0) - (b.created || 0))[0];
if (oldestPin?.message?.ts) {
await web.pins.remove({
channel,
timestamp: oldestPin.message.ts
});
}
}
// Add new pin
await web.pins.add({ channel, timestamp });
};interface TokenOverridable {
/** Override the default token for this request */
token?: string;
}
interface Message {
/** Message text content */
text?: string;
/** Message timestamp */
ts?: string;
/** User who sent the message */
user?: string;
/** Message type */
type?: string;
/** Message subtype */
subtype?: string;
/** Message attachments */
attachments?: MessageAttachment[];
/** Message blocks */
blocks?: Block[];
/** Thread timestamp if message is in a thread */
thread_ts?: string;
}
interface File {
/** File ID */
id?: string;
/** File name */
name?: string;
/** File title */
title?: string;
/** File size in bytes */
size?: number;
/** File MIME type */
mimetype?: string;
/** File URL */
url_private?: string;
/** User who uploaded the file */
user?: string;
}
interface FileComment {
/** Comment ID */
id?: string;
/** Comment text */
comment?: string;
/** User who created the comment */
user?: string;
/** Comment timestamp */
timestamp?: number;
}Install with Tessl CLI
npx tessl i tessl/npm-slack--web-api