Skip to main content

Method Signature

async sendSticker(options: SendStickerOptions): Promise<MessageResponse>
Send a sticker to an iMessage conversation. Stickers can be sent as standalone messages or placed on existing messages as tapbacks.
Stickers require the Private API to be enabled on your BlueBubbles server.

Parameters

options
SendStickerOptions
required
Configuration object for sending the sticker

Returns

MessageResponse
object
The sent message object containing the sticker metadata

Examples

Send Standalone Sticker

Send a sticker as a regular message in the conversation.
const message = await client.attachment.sendSticker({
  chatGuid: "iMessage;+;chat123456",
  filePath: "/path/to/sticker.png"
});

console.log(`Sticker sent: ${message.guid}`);

Send Sticker on Message (Tapback)

Place a sticker on an existing message with default positioning.
const message = await client.attachment.sendSticker({
  chatGuid: "iMessage;+;chat123456",
  filePath: "/path/to/sticker.png",
  selectedMessageGuid: "message-to-react-to"
});

Custom Sticker Positioning

Place a sticker with precise control over position, size, and rotation.
const message = await client.attachment.sendSticker({
  chatGuid: "iMessage;+;chat123456",
  filePath: "/path/to/sticker.png",
  selectedMessageGuid: "message-guid",
  stickerX: 0.75,        // 75% from left (right side)
  stickerY: 0.25,        // 25% from top (upper area)
  stickerScale: 0.5,     // 50% of default size
  stickerRotation: Math.PI / 4,  // 45 degrees (π/4 radians)
  stickerWidth: 200      // 200 points wide
});

Sticker Pack Implementation

const stickerPack = [
  "/stickers/heart.png",
  "/stickers/thumbs-up.png",
  "/stickers/fire.png"
];

// Send a random sticker from the pack
const randomSticker = stickerPack[Math.floor(Math.random() * stickerPack.length)];

await client.attachment.sendSticker({
  chatGuid: "iMessage;+;chat123456",
  filePath: randomSticker
});

Animated Sticker Placement

Place stickers with varying rotations for visual effect.
const rotations = [0, Math.PI / 6, -Math.PI / 6]; // 0°, 30°, -30°

for (const rotation of rotations) {
  await client.attachment.sendSticker({
    chatGuid: "iMessage;+;chat123456",
    filePath: "/path/to/star.png",
    selectedMessageGuid: "message-guid",
    stickerRotation: rotation,
    stickerScale: 0.6
  });
  
  await new Promise(resolve => setTimeout(resolve, 500)); // Delay between stickers
}

Positioning Guide

X and Y Coordinates

  • Values range from 0.0 to 1.0
  • (0, 0) = top-left corner of the message bubble
  • (1, 1) = bottom-right corner of the message bubble
  • (0.5, 0.5) = center (default)
(0,0)  ───────────  (1,0)
  │                    │
  │    (0.5, 0.5)      │
  │        ●           │
  │                    │
(0,1)  ───────────  (1,1)

Scale

  • Range: 0.0 to 1.0
  • 0.75 = 75% of original size (default)
  • 1.0 = 100% (full size)
  • 0.5 = 50% (half size)

Rotation

  • Value in radians
  • 0 = no rotation (default)
  • Math.PI / 2 = 90° clockwise
  • Math.PI = 180°
  • -Math.PI / 2 = 90° counter-clockwise

Behavior

  • If the specified chat doesn’t exist, it will be created automatically
  • Stickers require Private API to be enabled on BlueBubbles server
  • The method is queued to ensure messages are sent in order
  • When selectedMessageGuid is omitted, the sticker is sent as a standalone message
  • When selectedMessageGuid is provided, the sticker appears as a tapback on that message

Error Handling

try {
  const message = await client.attachment.sendSticker({
    chatGuid: "iMessage;+;chat123456",
    filePath: "/path/to/sticker.png"
  });
} catch (error) {
  if (error.response?.status === 400) {
    console.error('Private API may not be enabled');
  } else if (error.code === 'ENOENT') {
    console.error('Sticker file not found');
  } else {
    console.error('Failed to send sticker:', error);
  }
}

See Also

Build docs developers (and LLMs) love