Skip to main content

Method Signature

await sdk.messages.sendReaction(options: {
  chatGuid: string;
  messageGuid: string;
  reaction: string;
  partIndex?: number;
}): Promise<MessageResponse>
Sends a tapback reaction (like, love, laugh, etc.) to a specific message. Tapbacks are iMessage’s quick reaction feature.
Tapbacks only work with iMessage chats. SMS recipients will receive a text message like “Liked “message text"".

Parameters

chatGuid
string
required
The unique identifier for the chat where the message exists
messageGuid
string
required
The unique identifier of the message to react to
reaction
string
required
The reaction type. Must be one of:
  • "love" - Heart
  • "like" - Thumbs up
  • "dislike" - Thumbs down
  • "laugh" - “Haha”
  • "emphasize" - Double exclamation marks ”!!”
  • "question" - Question mark
To remove a reaction, prefix with a minus sign:
  • "-love", "-like", "-dislike", "-laugh", "-emphasize", "-question"
partIndex
number
default:"0"
The part index for multi-part messages. Use 0 for single-part messages (most common).

Response

Returns a MessageResponse object representing the reaction:
guid
string
Unique identifier for the reaction message
associatedMessageGuid
string | null
The GUID of the message this reaction is associated with
associatedMessageType
string | null
The type of association (typically the reaction type)
dateCreated
number
Timestamp when the reaction was sent

Examples

Send a Heart Reaction

const reaction = await sdk.messages.sendReaction({
  chatGuid: "iMessage;-;user@example.com",
  messageGuid: "iMessage;-;user@example.com;12345",
  reaction: "love"
});

console.log("Sent heart reaction!");

Send a Thumbs Up

await sdk.messages.sendReaction({
  chatGuid: "iMessage;-;user@example.com",
  messageGuid: "iMessage;-;user@example.com;12345",
  reaction: "like"
});

Send “Haha” Reaction

await sdk.messages.sendReaction({
  chatGuid: "iMessage;-;user@example.com",
  messageGuid: "iMessage;-;user@example.com;12345",
  reaction: "laugh"
});

Remove a Reaction

// First, send a reaction
await sdk.messages.sendReaction({
  chatGuid: "iMessage;-;user@example.com",
  messageGuid: "iMessage;-;user@example.com;12345",
  reaction: "love"
});

// Later, remove it by prefixing with "-"
await sdk.messages.sendReaction({
  chatGuid: "iMessage;-;user@example.com",
  messageGuid: "iMessage;-;user@example.com;12345",
  reaction: "-love"
});

console.log("Reaction removed");

React to Incoming Messages

sdk.on("message", async (message) => {
  // Auto-react with thumbs up to messages from a specific person
  if (message.handle?.address === "friend@example.com" && !message.isFromMe) {
    await sdk.messages.sendReaction({
      chatGuid: message.chats![0].guid,
      messageGuid: message.guid,
      reaction: "like"
    });
    console.log(`Liked message: ${message.text}`);
  }
});

React Based on Message Content

sdk.on("message", async (message) => {
  if (!message.isFromMe && message.text) {
    const text = message.text.toLowerCase();
    
    // Auto-react based on keywords
    if (text.includes("funny") || text.includes("😂")) {
      await sdk.messages.sendReaction({
        chatGuid: message.chats![0].guid,
        messageGuid: message.guid,
        reaction: "laugh"
      });
    } else if (text.includes("love") || text.includes("❤️")) {
      await sdk.messages.sendReaction({
        chatGuid: message.chats![0].guid,
        messageGuid: message.guid,
        reaction: "love"
      });
    } else if (text.includes("?") || text.includes("confused")) {
      await sdk.messages.sendReaction({
        chatGuid: message.chats![0].guid,
        messageGuid: message.guid,
        reaction: "question"
      });
    }
  }
});

Toggle Reaction

async function toggleReaction(
  chatGuid: string,
  messageGuid: string,
  reactionType: string
) {
  // Get the message to check if we already reacted
  const message = await sdk.messages.getMessage(messageGuid);
  
  // Check if we already have this reaction (implementation depends on your needs)
  const hasReaction = false; // You'd check message.associatedMessages or similar
  
  if (hasReaction) {
    // Remove reaction
    await sdk.messages.sendReaction({
      chatGuid,
      messageGuid,
      reaction: `-${reactionType}`
    });
    console.log(`Removed ${reactionType} reaction`);
  } else {
    // Add reaction
    await sdk.messages.sendReaction({
      chatGuid,
      messageGuid,
      reaction: reactionType
    });
    console.log(`Added ${reactionType} reaction`);
  }
}

await toggleReaction(
  "iMessage;-;user@example.com",
  "iMessage;-;user@example.com;12345",
  "love"
);

React to Your Own Messages

// Send a message
const message = await sdk.messages.sendMessage({
  chatGuid: "iMessage;-;user@example.com",
  message: "Did you see the game last night?"
});

// React to your own message
await sdk.messages.sendReaction({
  chatGuid: "iMessage;-;user@example.com",
  messageGuid: message.guid,
  reaction: "emphasize"
});

Reaction Types Reference

ReactionCodeVisualRemove Code
Heart"love"❤️"-love"
Thumbs Up"like"👍"-like"
Thumbs Down"dislike"👎"-dislike"
Haha"laugh"😂"-laugh"
Emphasize"emphasize"!!"-emphasize"
Question"question"?"-question"

Error Handling

try {
  await sdk.messages.sendReaction({
    chatGuid: "iMessage;-;user@example.com",
    messageGuid: "iMessage;-;user@example.com;12345",
    reaction: "love"
  });
  console.log("Reaction sent");
} catch (error) {
  if (error.response?.status === 400) {
    console.error("Invalid reaction type or message GUID");
  } else if (error.response?.status === 404) {
    console.error("Message not found");
  } else if (error.message.includes("not supported")) {
    console.error("Reactions not supported for this chat type (likely SMS)");
  } else {
    console.error("Failed to send reaction:", error.message);
  }
}

SMS Behavior

When sending a tapback to an SMS chat, the recipient receives a text message:
Liked "This is the original message"
The format varies by reaction type:
  • love: “Loved “message""
  • like: “Liked “message""
  • dislike: “Disliked “message""
  • laugh: “Laughed at “message""
  • emphasize: “Emphasized “message""
  • question: “Questioned “message""

Limitations

Tapback limitations:
  • Only one reaction type per person per message (adding a new reaction replaces the old one)
  • SMS recipients receive text descriptions instead of visual reactions
  • No support for custom reactions or emojis (limited to the 6 built-in types)
  • Some older iMessage versions may not display reactions correctly

Build docs developers (and LLMs) love