Skip to main content

Community Service

The Community Service manages cross-platform community registrations, configurations, and security key storage. It provides a unified way to connect Discord servers, Telegram groups, and other platform communities to Loyalteez brands.

Overview

The Community Service handles:

  • Community Registration - Two-step secure registration flow
  • Security Key Management - Encrypted storage (AES-256-GCM)
  • Configuration Management - Event settings, metadata, options
  • Default Event Creation - Platform-specific default monitoring rules

Base URL

https://services.loyalteez.app/community

Endpoints

Register Community

Start the registration process. This creates a pending community record and returns an activation token.

POST /community/register

Request Body

{
"platform": "telegram",
"brandId": "0x1234567890abcdef1234567890abcdef12345678",
"securityKey": "your-64-char-hex-security-key",
"adminId": "5150836861",
"metadata": {
"setupInitiatedBy": "5150836861"
}
}
FieldTypeRequiredDescription
platformstringYesPlatform identifier: discord, telegram, twitter, etc.
brandIdstringYesBrand wallet address (42 chars, starts with 0x)
securityKeystringYesBrand security key (64 char hex string)
adminIdstringYesPlatform user ID of the registering admin
metadataobjectNoAdditional metadata to store

Response

{
"success": true,
"activationToken": "abc123xyz",
"expiresAt": "2026-01-22T15:30:00.000Z",
"message": "Registration successful. Use this token to activate in your community."
}

Errors

StatusErrorDescription
400Missing required fieldsPlatform, brandId, securityKey, or adminId not provided
400Invalid Brand ID formatBrand ID must be 42 chars starting with 0x
400Invalid security keySecurity key validation failed against the brand

Activate Community

Complete the registration by providing the activation token and community ID.

POST /community/activate

Request Body

{
"activationToken": "abc123xyz",
"communityId": "-5009994438",
"communityName": "My Awesome Community",
"metadata": {
"chatType": "supergroup"
}
}
FieldTypeRequiredDescription
activationTokenstringYesToken from registration step
communityIdstringYesPlatform-specific community identifier
communityNamestringNoHuman-readable community name
metadataobjectNoAdditional metadata to store

Response

{
"success": true,
"communityId": "-5009994438",
"brandId": "0x1234567890abcdef1234567890abcdef12345678",
"message": "Community activated successfully!",
"eventsCreated": [
"telegram_daily_checkin",
"gm_checkin",
"gn_checkin",
"telegram_join",
"telegram_admin_reward"
]
}

Errors

StatusErrorDescription
400Missing activation token or community IDRequired fields not provided
400Invalid or expired activation tokenToken not found or expired
409Community already existsA community with this ID already exists

Get Community Configuration

Retrieve the full configuration for a community.

GET /community/:platform/:communityId

Parameters

ParameterDescription
platformPlatform identifier (e.g., telegram, discord)
communityIdPlatform-specific community identifier

Response

{
"success": true,
"data": {
"communityId": "-5009994438",
"platform": "telegram",
"brandId": "0x1234567890abcdef1234567890abcdef12345678",
"communityName": "My Awesome Community",
"status": "active",
"config": {
"welcomeMessage": "Welcome to {community}!",
"dailyEvent": "telegram_daily_checkin"
},
"events": [
{
"eventName": "telegram_daily_checkin",
"eventType": "telegram_daily_checkin",
"ltzReward": 10,
"cooldownHours": 24,
"isActive": true
}
],
"createdAt": "2026-01-22T14:00:00.000Z",
"updatedAt": "2026-01-22T14:30:00.000Z"
}
}

Errors

StatusErrorDescription
404Community not foundNo community with this platform/ID combination

Update Community Configuration

Update configuration, metadata, or settings for a community.

PATCH /community/:platform/:communityId

Request Body

{
"config": {
"welcomeMessage": "Welcome aboard!",
"dailyEvent": "custom_daily_event"
},
"communityName": "Updated Community Name"
}
FieldTypeRequiredDescription
configobjectNoConfiguration object to merge
communityNamestringNoUpdate community name
statusstringNoUpdate status (active, inactive)

Response

{
"success": true,
"message": "Configuration updated",
"data": {
"communityId": "-5009994438",
"config": {
"welcomeMessage": "Welcome aboard!",
"dailyEvent": "custom_daily_event"
}
}
}

Get Security Key

Retrieve the decrypted security key for a community. Used internally by platform integrations for HMAC signing.

GET /community/:platform/:communityId/security-key

Response

{
"success": true,
"securityKey": "your-64-char-hex-security-key"
}

Errors

StatusErrorDescription
404Community not foundNo community with this platform/ID combination
500Decryption failedInternal error decrypting security key
Internal Use Only

This endpoint is intended for internal use by platform bot workers. Security keys should never be exposed to end users.


Disconnect Community

Deactivate a community. This doesn't delete the record but sets status to inactive.

DELETE /community/:platform/:communityId

Query Parameters

ParameterRequiredDescription
confirmYesMust be true to confirm deletion

Response

{
"success": true,
"message": "Community disconnected successfully"
}

Database Schema

The Community Service uses the brand_communities table:

CREATE TABLE brand_communities (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
platform TEXT NOT NULL, -- 'discord', 'telegram', etc.
community_id TEXT, -- Platform-specific ID (null while pending)
brand_id TEXT NOT NULL, -- Brand wallet address
community_name TEXT, -- Human-readable name
encrypted_security_key TEXT, -- AES-256-GCM encrypted
security_key_iv TEXT, -- Encryption IV
config_metadata JSONB DEFAULT '{}', -- Configuration settings
status TEXT DEFAULT 'pending', -- pending, active, inactive
activation_token TEXT, -- For two-step activation
activation_expires_at TIMESTAMPTZ, -- Token expiration
admin_user_id TEXT, -- Who set up the community
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),

CONSTRAINT unique_platform_community
UNIQUE (platform, community_id)
);

CREATE INDEX idx_brand_communities_brand
ON brand_communities(brand_id);
CREATE INDEX idx_brand_communities_status
ON brand_communities(status);
CREATE INDEX idx_brand_communities_token
ON brand_communities(activation_token);

Default Events by Platform

When a community is activated, platform-specific default events are created:

Telegram

EventTypeLTZCooldownDescription
telegram_daily_checkindaily1024hDaily check-in reward
gm_checkinnatural2524h"Good morning" detection
gn_checkinnatural1524h"Good night" detection
telegram_joinwelcome50One-timeNew member bonus
message_qualityquality101hQuality message (disabled by default)
telegram_admin_rewardmanualVariableNoneAdmin-granted rewards

Discord

EventTypeLTZCooldownDescription
discord_daily_checkindaily1024hDaily check-in reward
gm_checkinnatural2524h"Good morning" detection
gn_checkinnatural1524h"Good night" detection
discord_joinwelcome50One-timeNew member bonus
message_qualityquality101hQuality message
discord_admin_rewardmanualVariableNoneAdmin-granted rewards

Security

Security Key Encryption

Security keys are encrypted at rest using AES-256-GCM:

  1. A random 12-byte IV is generated for each key
  2. The key is encrypted using the service's ENCRYPTION_KEY
  3. Both the encrypted key and IV are stored in the database
  4. Decryption happens in-memory only when needed

Two-Step Activation

The two-step activation flow protects against:

  • Key Exposure: Security keys are never sent in public channels
  • Unauthorized Setup: Only users who complete the DM flow can activate
  • Token Expiration: Activation tokens expire after 1 hour

Integration Example

Telegram Bot Setup Flow

// Step 1: User DMs bot with /setup
// Bot collects brandId and securityKey through conversation

// Step 2: Register community
const response = await fetch('https://services.loyalteez.app/community/register', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
platform: 'telegram',
brandId: '0x...',
securityKey: 'abc123...',
adminId: userId
})
});

const { activationToken } = await response.json();
// Send token to user in DM

// Step 3: User uses /activate <token> in group
const activateResponse = await fetch('https://services.loyalteez.app/community/activate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
activationToken,
communityId: chatId,
communityName: chatTitle
})
});

// Community is now active!

Next Steps