К основному содержанию
скилл CX Codex

extension-invite-links — скилл для Claude Code: установка и обзор

Скилл добавляет в проект систему приглашений и сбор ответов RSVP. Гости отправляют подтверждения по кодам без авторизации, а администратор видит сводку через вход в систему.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add caffeinelabs/skills --skill extension-invite-links -a claude-code
Открыть на GitHub

Что делает extension-invite-links

Скилл настраивает закрытый доступ по инвайтам на базе Motoko и React. Администраторы выпускают уникальные коды через бэкенд, а гости подтверждают своё присутствие без создания учётной записи. Код приглашения считывается напрямую из параметров адресной строки.

Для бэкенда используется готовый модуль invite-links-module.mo и миксин MixinInviteLinks. Инструкция требует подключать include MixinInviteLinks(accessControlState, inviteState) строго внутри src/backend/main.mo. Переопределять публичные методы generateInviteCode, submitRSVP, getAllRSVPs и getInviteCodes нельзя, иначе возникнет конфликт сигнатур.

Перед интеграцией необходимо настроить расширение extension-authorization, потому что модуль инвайтов напрямую зависит от контроля доступа caffeineai-authorization. Если этой базы в проекте ещё нет, компилятор Motoko выдаст ошибку отсутствующих типов.

Какие задачи решает

  • организовать сбор RSVP без обязательной регистрации гостей
  • генерировать одноразовые коды приглашений в панели администратора
  • автоматически подставлять код инвайта из параметров адресной строки
  • разграничить просмотр ответов гостей через авторизацию администратора

Примеры запросов агенту

  • Подключи миксин MixinInviteLinks в бэкенд main.mo для обработки кодов приглашений.
  • Создай компонент GuestRSVP для отправки ответа гостя по коду из URL без входа.
  • Собери панель администратора с генерацией инвайт-кодов и статистикой посещаемости.

Как установить extension-invite-links

1Через Skills CLI (Vercel)

npx skills add caffeinelabs/skills --skill extension-invite-links -a claude-code

2Вручную: положить файлы

~/.claude/skills/extension-invite-links/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/extension-invite-links/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Вопросы о extension-invite-links

Как установить extension-invite-links в Claude Code?

Выполните команду npx skills add caffeinelabs/skills --skill extension-invite-links -a claude-code в терминале проекта.

Что делает скилл extension-invite-links?

Он настраивает модуль генерации кодов приглашений на Motoko и React-форму RSVP, позволяя гостям отвечать без учётной записи.

Какие зависимости нужны для работы этого скилла?

Проекту требуется предварительно настроенный модуль extension-authorization, а также пакеты caffeineai-invite-links и caffeineai-authorization версии ~1.0.0.

Исходный текст

SKILL.md · Apache-2.0
---
name: extension-invite-links
description: Requests invite-link / RSVP based access where guests can submit responses without login while admin can view responses with login.
version: 1.0.3
compatibility:
  mops:
    caffeineai-invite-links: "~1.0.0"
    caffeineai-authorization: "~1.0.0"
caffeineai-subscription: [none]
---

# Invite Links & RSVP
Invite links & RSVP extension for [Caffeine AI](https://caffeine.ai?utm_source=caffeine-skill&utm_medium=referral).

## Overview

This skill adds invite-link generation and RSVP collection. Admins generate unique invite codes; guests use them to submit responses without authentication.

Prerequisite: You must follow [extension-authorization](../extension-authorization/SKILL.md) first, as this integration depends on it.

# Backend

## Module API

The prefabricated module `mo:caffeineai-invite-links/invite-links-module.mo` provides low-level invite-link and RSVP state management. Do not modify it.

```mo:caffeineai-invite-links/invite-links-module
module {
    public type RSVP = {
        name : Text;
        attending : Bool;
        timestamp : Time.Time;
        inviteCode : Text;
    };

    public type InviteCode = {
        code : Text;
        created : Time.Time;
        used : Bool;
    };

    public type InviteLinksSystemState = {
        var rsvps : Map.Map<Text, RSVP>;
        var inviteCodes : Map.Map<Text, InviteCode>;
    };

    public func initState() : InviteLinksSystemState;
    public func generateUUID(blob: Blob) : Text;
    public func generateInviteCode(state: InviteLinksSystemState, code: Text);
    public func getInviteCodes(state: InviteLinksSystemState) : [InviteCode];
    public func submitRSVP(state: InviteLinksSystemState, name: Text, attending: Bool, inviteCode: Text);
    public func getAllRSVPs(state: InviteLinksSystemState) : [RSVP];
}
```

## Setup in main.mo

`include MixinInviteLinks(accessControlState, inviteState)` MUST be placed in `main.mo`, not in a custom mixin file. The mixin provides these public endpoints automatically:

- `generateInviteCode()`
- `submitRSVP(name, attending, inviteCode)`
- `getAllRSVPs()`
- `getInviteCodes()`

Do NOT redeclare any of these functions. They are provided exclusively by `MixinInviteLinks`.

```motoko filepath=src/backend/main.mo
import AccessControl "mo:caffeineai-authorization/access-control";
import MixinAuthorization "mo:caffeineai-authorization/MixinAuthorization";
import MixinInviteLinks "mo:caffeineai-invite-links/MixinInviteLinks";
import InviteLinksModule "mo:caffeineai-invite-links/invite-links-module";

actor {
  let accessControlState : AccessControl.AccessControlState;
  include MixinAuthorization(accessControlState, null);
  let inviteState : InviteLinksModule.InviteLinksSystemState;
  include MixinInviteLinks(accessControlState, inviteState);

  // Write additional application-specific code here.
};
```

The migration chain head:

```motoko filepath=src/backend/migrations/00000000_000000.mo
import AccessControl "mo:caffeineai-authorization/access-control";
import InviteLinksModule "mo:caffeineai-invite-links/invite-links-module";

module {
  type NewActor = {
    accessControlState : AccessControl.AccessControlState;
    inviteState : InviteLinksModule.InviteLinksSystemState;
  };

  public func migration(_old : {}) : NewActor {
    {
      accessControlState = AccessControl.initState();
      inviteState = InviteLinksModule.initState();
    };
  };
};
```

# Frontend

Invite links and RSVP system functionality:

Here is an example how to implement Internet Identity authentication with admin-only invite links / RSVPs in the frontend: 

```typescript filepath=src/App.tsx
import AdminDashboard from './components/AdminDashboard';
import GuestRSVP from './components/GuestRSVP';
import LoginButton from './components/LoginButton';
import { useIsCurrentUserAdmin } from './hooks/useQueries';

export default function App() {
  const { data: isAdmin } = useIsCurrentUserAdmin();

  return (
    <div className="min-h-screen bg-gradient-to-br from-purple-100 to-pink-100">
      <header className="p-4 bg-white/80 backdrop-blur-sm shadow-sm">
        <div className="max-w-7xl mx-auto flex justify-between items-center">
          <h1 className="text-3xl font-bold text-purple-800">RSVP</h1>
          <LoginButton />
        </div>
      </header>
      <main className="max-w-7xl mx-auto p-4 mt-8">
        {isAdmin ? <AdminDashboard /> : <GuestRSVP />}
      </main>
    </div>
  );
}
```


```typescript filepath=src/components/GuestRSVP.tsx
import { useState, useEffect } from 'react';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group';
import { useSubmitRSVP } from '../hooks/useQueries';

export default function GuestRSVP() {
  const [name, setName] = useState('');
  const [inviteCode, setInviteCode] = useState('');
  const [attending, setAttending] = useState(true);
  const [submitted, setSubmitted] = useState(false);
  const submitRSVP = useSubmitRSVP();

  // Auto-populate invite code from URL
  useEffect(() => {
    const codeFromUrl = new URLSearchParams(window.location.search).get('code');
    if (codeFromUrl) setInviteCode(codeFromUrl);
  }, []);

  const handleSubmit = (e) => {
    e.preventDefault();
    submitRSVP.mutate({ name, attending, inviteCode }, {
      onSuccess: () => setSubmitted(true)
    });
  };

  if (submitted) return <div>Thank you! Your RSVP has been submitted.</div>;

  return (
    <form onSubmit={handleSubmit}>
      <input value={name} onChange={(e) => setName(e.target.value)} placeholder="Your Name" required />
      <input value={inviteCode} onChange={(e) => setInviteCode(e.target.value)} placeholder="Invite Code" required />
      <label>
        <input type="radio" checked={attending} onChange={() => setAttending(true)} />
        Yes, I'll attend
      </label>
      <label>
        <input type="radio" checked={!attending} onChange={() => setAttending(false)} />
        No, I can't attend
      </label>
      <button type="submit" disabled={submitRSVP.isPending}>Submit RSVP</button>
      {submitRSVP.error && <p>Error: {submitRSVP.error.message}</p>}
    </form>
  );
}
```

### Admin Dashboard
```typescript filepath=src/components/AdminDashboard.tsx
import { useGetAllRSVPs, useGetInviteCodes, useGenerateInviteCode } from '../hooks/useQueries';

export default function AdminDashboard() {
  const { data: rsvps } = useGetAllRSVPs();
  const { data: inviteCodes } = useGetInviteCodes();
  const generateInviteCode = useGenerateInviteCode();

  const unusedCodes = inviteCodes?.filter(code => !code.used) || [];
  const attendingCount = rsvps?.filter(rsvp => rsvp.attending).length || 0;

  return (
    <div>
      <div>
        <h2>Statistics</h2>
        <p>Total RSVPs: {rsvps?.length || 0}</p>
        <p>Attending: {attendingCount}</p>
        <p>Not Attending: {(rsvps?.length || 0) - attendingCount}</p>
      </div>

      <div>
        <h2>Invite Codes</h2>
        <button onClick={() => generateInviteCode.mutate()}>Generate New Code</button>
        {unusedCodes.map(code => (
          <div key={code.code}>
            <code>{code.code}</code>
            <button onClick={() => navigator.clipboard.writeText(`${window.location.origin}?code=${code.code}`)}>
              Copy Link
            </button>
          </div>
        ))}
      </div>

      <div>
        <h2>RSVPs</h2>
        <table>
          <thead><tr><th>Name</th><th>Status</th><th>Date</th></tr></thead>
          <tbody>
            {rsvps?.map(rsvp => (
              <tr key={rsvp.inviteCode}>
                <td>{rsvp.name}</td>
                <td>{rsvp.attending ? 'Attending' : 'Not Attending'}</td>
                <td>{new Date(Number(rsvp.timestamp / BigInt(1000000))).toLocaleDateString()}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}
```

## Required Hooks
- `useIsCurrentUserAdmin()` - Check if current user is admin
- `useSubmitRSVP()` - Submit RSVP mutation
- `useGetAllRSVPs()` - Fetch all RSVPs (admin only)
- `useGetInviteCodes()` - Fetch invite codes (admin only)  
- `useGenerateInviteCode()` - Generate new invite code (admin only)
- `useInternetIdentity()` - Internet Identity authentication

## Key Features
- URL parameter parsing for invite codes (`?code=xyz`)
- Copy invite links to clipboard functionality
- Admin/guest view switching based on authentication
- Basic form validation and error handling
- Timestamp conversion for display

© caffeinelabs · Apache-2.0 · caffeinelabs/skills

Похожие скиллы

Всё по теме «Бэкенд и API» →
clerk-tanstack-patterns clerk Подсказывает агенту, как подключить Clerk к TanStack React Start: защита маршрутов, createServerFn, лоадеры и middleware. CX Codex +1 15 500установок cloud assistant-ui Подключает AssistantCloud к приложению на assistant-ui: история тредов между сессиями, обратная связь по сообщениям и загрузка файлов. CX Codex +1 5 000установок webflow-cli:designer-extension webflow Скилл ведёт агента по всему циклу работы с Designer Extensions в Webflow: выбор шаблона, инициализация проекта, локальный сервер и сборка бандла. CX Codex +1 1 000установок clerk-nextjs-patterns clerk Скилл обучает ИИ-агента паттернам аутентификации Clerk в Next.js: от серверных функций до кэширования. Пригодится при настройке middleware, Server Actions и защите роутов. CX Codex +1 53 400установок workos-widgets workos Помогает встроить виджеты WorkOS — управление пользователями, профиль, SSO и проверку домена — и связать фронтенд с выдачей токенов на бэкенде. CX Codex +1 857установок netlify-identity netlify Скилл для добавления входа, регистрации и OAuth на сайт Netlify через @netlify/identity. Пригодится, когда нужно закрыть контент по ролям. CX Codex +1 3 000установок

Из того же набора25

extension-stripe Добавляет в проект на Caffeine AI оплату картами через Stripe: создание checkout-сессии и проверку её статуса. Пригодится, когда нужен приём платежей внутри канистры. CX Codex +1 28 200установок extension-posting-to-x Скилл для сборок Caffeine, которые публикуют твиты в X. Задаёт единственный поддерживаемый путь через пакет x-client и OAuth 2.0 PKCE. CX Codex +1 28 100установок extension-openai Задаёт правила интеграции OpenAI в канистры Motoko через пакет openai-client. Защищает API-ключ от утечки при реплицированных вызовах. CX Codex +1 28 100установок extension-email-raw Скилл добавляет в проект отправку одного письма сразу нескольким получателям через to, cc и bcc. Пригодится, когда нужно разослать уведомление участникам встречи. CX Codex +1 28 100установок extension-http-outcalls Скилл для HTTP-запросов из бэкенд-канистры к внешним API. Следит, чтобы каждый запрос был ограничен на стороне провайдера. CX Codex +1 28 100установок extension-email Скилл учит агента отправлять сервисные и транзакционные письма из канистр Motoko. Пригодится для разовых системных оповещений и чеков. CX Codex +1 28 100установок extension-object-storage Скилл добавляет в проект хранилище файлов: содержимое лежит вне сети, а бэкенд держит только ссылки на него. Пригодится для галерей изображений, видео и документов. CX Codex +1 28 100установок extension-email-verification Добавляет в приложение на Caffeine AI подтверждение email по ссылке: получатель кликает кнопку и адрес помечается проверенным. CX Codex +1 28 100установок

Спонсоры проекта

Компании, которые помогают держать аналитику открытой