Platform Integration
How to integrate Slootly with each messaging platform.
Info
The Slootly SDK is platform-agnostic. The same methods work across all platforms. This guide covers platform-specific details like user ID extraction and checkout link delivery.
Telegram
User ID
Telegram provides the user ID via from.id in the Bot API update object. Always convert to string.
| Source | Access Path | Example |
|---|---|---|
Bot API | message.from.id | 123456789 |
Inline query | inline_query.from.id | 123456789 |
Callback query | callback_query.from.id | 123456789 |
Sending Checkout Links
// node-telegram-bot-api
bot.on('message', async (msg) => {
const userId = msg.from.id.toString();
const sub = await gate.check(userId, 'telegram');
if (!sub.active) {
const url = gate.checkoutUrl(userId, 'pro', 'telegram');
bot.sendMessage(msg.chat.id, 'Upgrade to Pro:', {
reply_markup: {
inline_keyboard: [[
{ text: 'Subscribe to Pro - $9.99/mo', url }
]]
}
});
}
});Checkout links open in the device browser. After payment, the success page includes a deep link back to the bot.
Grammy.js Example
import { Bot } from 'grammy';
import { Slootly } from '@slootly/sdk';
const bot = new Bot(process.env.BOT_TOKEN);
const gate = new Slootly('sk_live_...');
bot.command('premium', async (ctx) => {
const userId = ctx.from.id.toString();
const sub = await gate.check(userId, 'telegram');
if (sub.active && sub.plan === 'pro') {
await ctx.reply('You already have Pro access!');
} else {
const url = gate.checkoutUrl(userId, 'pro', 'telegram');
await ctx.reply('Get unlimited access with Pro:', {
reply_markup: {
inline_keyboard: [[
{ text: 'Subscribe - $9.99/mo', url }
]]
}
});
}
});Discord
User ID
Discord provides the user ID via the interaction object.
| Source | Access Path | Example |
|---|---|---|
Slash command | interaction.user.id | 987654321012345678 |
Message | message.author.id | 987654321012345678 |
Button click | interaction.user.id | 987654321012345678 |
Sending Checkout Links
// discord.js v14
import { Client, SlashCommandBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } from 'discord.js';
import { Slootly } from '@slootly/sdk';
const gate = new Slootly('sk_live_...');
client.on('interactionCreate', async (interaction) => {
if (!interaction.isChatInputCommand()) return;
if (interaction.commandName !== 'premium') return;
const userId = interaction.user.id;
const sub = await gate.check(userId, 'discord');
if (sub.active && sub.plan === 'pro') {
await interaction.reply({
content: 'You already have Pro access!',
ephemeral: true,
});
} else {
const url = gate.checkoutUrl(userId, 'pro', 'discord');
const row = new ActionRowBuilder().addComponents(
new ButtonBuilder()
.setLabel('Subscribe to Pro - $9.99/mo')
.setStyle(ButtonStyle.Link)
.setURL(url)
);
await interaction.reply({
content: 'Unlock unlimited features with Pro:',
components: [row],
ephemeral: true,
});
}
});User ID
WhatsApp Cloud API provides the user ID as wa_id.
| Source | Access Path | Example |
|---|---|---|
Cloud API | messages[0].from | 15551234567 |
Webhook | contacts[0].wa_id | 15551234567 |
Sending Checkout Links
// WhatsApp Cloud API
import { Slootly } from '@slootly/sdk';
const gate = new Slootly('sk_live_...');
async function handleMessage(from: string, phoneNumberId: string) {
const sub = await gate.check(from, 'whatsapp');
if (!sub.active) {
const url = gate.checkoutUrl(from, 'pro', 'whatsapp');
await fetch(
`https://graph.facebook.com/v18.0/${phoneNumberId}/messages`,
{
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.WHATSAPP_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
messaging_product: 'whatsapp',
to: from,
type: 'interactive',
interactive: {
type: 'button',
body: { text: 'Upgrade to Pro for unlimited access' },
action: {
buttons: [
{ type: 'url', title: 'Subscribe', url }
]
}
}
}),
}
);
}
}Slack
User ID
| Source | Access Path | Example |
|---|---|---|
Events API | event.user | U0123456789 |
Slash command | user_id | U0123456789 |
Block action | user.id | U0123456789 |
Sending Checkout Links
// Slack Bolt
import { App } from '@slack/bolt';
import { Slootly } from '@slootly/sdk';
const gate = new Slootly('sk_live_...');
const app = new App({
token: process.env.SLACK_BOT_TOKEN,
signingSecret: process.env.SLACK_SIGNING_SECRET,
});
app.command('/premium', async ({ command, ack, respond }) => {
await ack();
const userId = command.user_id;
const sub = await gate.check(userId, 'slack');
if (sub.active && sub.plan === 'pro') {
await respond('You already have Pro access!');
} else {
const url = gate.checkoutUrl(userId, 'pro', 'slack');
await respond({
blocks: [
{
type: 'section',
text: {
type: 'mrkdwn',
text: 'Unlock premium features with Pro:',
},
accessory: {
type: 'button',
text: { type: 'plain_text', text: 'Subscribe - $9.99/mo' },
url,
},
},
],
});
}
});Custom Platform
Use the custom platform for web apps, CLI tools, or any platform not listed above. You define the user ID format.
// Web app example
const sub = await gate.check(user.email, 'custom');
const url = gate.checkoutUrl(user.email, 'pro', 'custom');Cross-Platform Identity Linking
Slootly can link multiple platform identities to a single subscriber. If a user pays on Telegram, they can link their Discord account and get Pro features there too without re-subscribing.
Linking is handled through the Slootly hosted checkout page. When a subscriber visits the checkout page from a new platform, Slootly detects the existing subscription and offers to link the accounts.
Tip
Identity linking is available on the Pro plan and above. On the Free plan, each platform identity is treated as a separate subscriber.