X Enterprises
fastify-x-twilio

rcs.*

Send RCS rich messages — plain text, media, content templates, rich cards, carousels, and quick replies via Twilio.

rcs.*

Rich Communication Services messaging via Twilio. The fastify.rcs decorator is only registered when twilio.messagingServiceSid is provided — it silently skips if not.

RCS messages fall back to SMS for recipients whose devices do not support RCS.

Signatures

fastify.rcs.send(to: string, body: string, extraOptions?: object): Promise<Object>
fastify.rcs.sendMedia(to: string, body: string, mediaUrl: string | string[]): Promise<Object>
fastify.rcs.sendTemplate(to: string, contentSid: string, contentVariables?: Record<string, string>): Promise<Object>
fastify.rcs.sendRichCard(to: string, card: { title: string; description?: string; mediaUrl?: string; actions?: object[]; contentSid?: string }): Promise<Object>
fastify.rcs.sendCarousel(to: string, cards: Array<{ id?: string; title: string; description?: string; mediaUrl?: string }>): Promise<Object>
fastify.rcs.sendQuickReplies(to: string, body: string, replies: Array<{ text: string; payload?: string }>): Promise<Object>
fastify.rcs.getStatus(messageSid: string): Promise<{ sid: string; status: string; errorCode?: string; errorMessage?: string; channel: string }>
fastify.rcs.listTemplates(options?: { limit?: number }): Promise<Object[]>
fastify.rcs.getTemplate(contentSid: string): Promise<Object>
fastify.rcs.deleteTemplate(contentSid: string): Promise<true>

Params

send / sendMedia

NameTypeRequiredDescription
tostringYesRecipient phone number in E.164 format.
bodystringYesMessage text.
mediaUrlstring | string[]Yes (sendMedia)URL(s) of media attachments.

sendTemplate

NameTypeRequiredDescription
tostringYesRecipient phone number.
contentSidstringYesTwilio Content SID for the template.
contentVariablesobjectNoVariables to interpolate into the template.

sendRichCard

NameTypeRequiredDescription
tostringYesRecipient phone number.
card.titlestringYesCard title.
card.descriptionstringNoCard subtitle/description.
card.mediaUrlstringNoCard image URL.
card.actionsarrayNoAction buttons for the card.
card.contentSidstringNoExisting Content SID — skips Twilio Content API creation.

sendCarousel

NameTypeRequiredDescription
tostringYesRecipient phone number.
cardsarrayYesNon-empty array of { id?, title, description?, mediaUrl? }.

sendQuickReplies

NameTypeRequiredDescription
tostringYesRecipient phone number.
bodystringYesMessage text above the quick reply buttons.
repliesarrayYesNon-empty array of { text, payload? }.

getStatus / getTemplate / deleteTemplate

NameTypeRequiredDescription
messageSid / contentSidstringYesMessage SID or Content SID.

Examples

send — basic RCS text

await fastify.rcs.send("+15551234567", "Hello via RCS!");

sendRichCard — product card with action button

await fastify.rcs.sendRichCard("+15551234567", {
  title: "New Arrivals",
  description: "Check out our latest collection",
  mediaUrl: "https://cdn.example.com/product.jpg",
  actions: [
    { type: "url", title: "Shop Now", url: "https://shop.example.com" },
  ],
});

sendCarousel — product showcase

await fastify.rcs.sendCarousel("+15551234567", [
  {
    title: "Blue Sneakers",
    description: "$89.99",
    mediaUrl: "https://cdn.example.com/shoe-blue.jpg",
  },
  {
    title: "Red Sneakers",
    description: "$79.99",
    mediaUrl: "https://cdn.example.com/shoe-red.jpg",
  },
]);

sendQuickReplies — confirmation flow

await fastify.rcs.sendQuickReplies(
  "+15551234567",
  "Confirm your appointment for Tuesday at 2pm?",
  [
    { text: "Yes, confirm", payload: "confirm" },
    { text: "No, cancel", payload: "cancel" },
    { text: "Reschedule", payload: "reschedule" },
  ]
);

Realistic — order notification with tracking button

fastify.post("/orders/:orderId/notify", async (request, reply) => {
  const order = await db.orders.find(request.params.orderId);

  await fastify.rcs.sendRichCard(order.customerPhone, {
    title: `Order #${order.id} Shipped!`,
    description: `Expected delivery: ${order.estimatedDelivery}`,
    mediaUrl: order.productImageUrl,
    actions: [
      {
        type: "url",
        title: "Track Package",
        url: `https://tracking.example.com/${order.trackingNumber}`,
      },
    ],
  });

  return reply.send({ notified: true });
});

Throws

  • [xTwilio] rcs.send: to (string) is required
  • [xTwilio] rcs.send: body (string) is required
  • [xTwilio] rcs.sendMedia: mediaUrl is required
  • [xTwilio] rcs.sendTemplate: contentSid (string) is required
  • [xTwilio] rcs.sendRichCard: card (object) is required
  • [xTwilio] rcs.sendCarousel: cards must be a non-empty array
  • [xTwilio] rcs.sendQuickReplies: replies must be a non-empty array
  • [xTwilio] rcs.getStatus: messageSid (string) is required
  • [xTwilio] rcs.getTemplate: contentSid (string) is required
  • [xTwilio] rcs.deleteTemplate: contentSid (string) is required
  • [xTwilio] Failed to send RCS message: <message> — Twilio API error

See also

AI Context

package: "@xenterprises/fastify-xtwilio"
decorator: fastify.rcs
methods: send, sendMedia, sendTemplate, sendRichCard, sendCarousel, sendQuickReplies, getStatus, listTemplates, getTemplate, deleteTemplate
use-when: Rich Communication Services messaging via Twilio — requires messagingServiceSid
Copyright © 2026