Bot API платформы InterChat позволяет создавать мощные, автоматизированные интеграции для ваших пользователей без необходимости понимать базовую криптографию или управлять ей. Поскольку InterChat использует архитектуру сквозного шифрования (E2EE) с нулевым разглашением, основной узел InterChat выступает в качестве безопасного криптографического прокси для вашего бота.
Когда ваш сервер отправляет стандартный ответ обычным текстом в формате JSON, узел InterChat автоматически шифрует его с использованием выделенного мастер-ключа вашего бота перед отправкой клиенту.
1. Регистрация и настройка
Перед написанием кода вам необходимо зарегистрировать своего бота в клиентском приложении InterChat:
- Откройте InterChat и перейдите в Settings (Настройки) > My Bots (Мои боты).
- Нажмите Create Bot (Создать бота) и заполните Имя бота (Name), Имя пользователя (Username) и Описание (Description).
- В поле Webhook URL введите HTTPS-адрес вашего внешнего сервера (например, https://scripts.yourdomain.com/webhook).
- Нажмите Generate New Token (Сгенерировать новый токен). Скопируйте этот API-токен; вы будете использовать его как Bearer-токен для аутентификации ваших исходящих сообщений.
- Сохраните вашего бота.
2. Получение сообщений (Webhook)
Каждый раз, когда пользователь отправляет сообщение вашему боту, InterChat немедленно отправляет HTTP-запрос POST на настроенный вами URL вебхука.
Входящая полезная нагрузка (JSON Payload):
{
"userId": "019f3c79-763a-7e60-a6ed-535febd4d0bd",
"text": "Покажите информацию о моем заказе",
"command": "order",
"timestamp": 1732049182394
}
Примечание: Поле command заполняется только в том случае, если сообщение пользователя начинается с косой черты (например, /order). В противном случае оно отсутствует.
Ваш сервер должен обработать эту полезную нагрузку и немедленно вернуть статус HTTP 200 OK для подтверждения получения.
3. Отправка ответов (API)
Чтобы отправить сообщение обратно пользователю, выполните HTTP-запрос POST на конечную точку Bot API InterChat.
- Конечная точка (Endpoint): https://gobackend.interchat.co.za/bot/send-message
- Заголовки (Headers):
Content-Type: application/jsonAuthorization: Bearer ВАШ_API_ТОКЕН
Исходящая полезная нагрузка (JSON Payload):
{
"targetUserId": "019f3c79-763a-7e60-a6ed-535febd4d0bd",
"text": "Ваш заказ передан курьеру!",
"inlineKeyboard": ""
}
Примечание: inlineKeyboard принимает преобразованный в строку массив JSON, если вы хотите прикрепить к вашему сообщению интерактивные кнопки.
4. Пример сервера:
Представленный файл main.go — это автономный веб-сервер на Go без внешних зависимостей, который реализует полноценного тестового логистического бота. Он управляет состояниями бесед в оперативной памяти и демонстрирует, как анализировать вебхуки и отправлять аутентифицированные ответы.
Чтобы запустить сервер:
# Настройте переменные окружения
export INTERCHAT_API_URL="https://gobackend.interchat.co.za/bot/send-message"
export BOT_API_TOKEN="ваш_сгенерированный_токен"
export PORT="8080"
# Запустите бота
go run main.go
./main.go
package main
import (
"bytes"
"encoding/json"
"io"
"log"
"net/http"
"os"
"strings"
"sync"
"time"
)
// InterChatWebhookPayload представляет входящие данные HTTP POST от InterChat.
type InterChatWebhookPayload struct {
UserID string `json:"userId"`
Text string `json:"text"`
Command string `json:"command,omitempty"`
Timestamp int64 `json:"timestamp"`
}
// DevMessageRequest представляет необходимую структуру JSON для отправки сообщения обратно.
type DevMessageRequest struct {
TargetUserID string `json:"targetUserId"`
Text string `json:"text"`
InlineKeyboard string `json:"inlineKeyboard"`
}
var (
apiToken string
interchatURL string
// Потокобезопасное хранилище в оперативной памяти для отслеживания сценариев общения с пользователями
stateMutex sync.RWMutex
userStates = make(map[string]string)
)
func main() {
// 1. Загрузка конфигурации
apiToken = os.Getenv("BOT_API_TOKEN")
if apiToken == "" {
log.Fatal("КРИТИЧЕСКАЯ ОШИБКА: переменная окружения BOT_API_TOKEN не установлена.")
}
interchatURL = os.Getenv("INTERCHAT_API_URL")
if interchatURL == "" {
// Возврат к стандартному рабочему URL, если он не задан явно
interchatURL = "https://gobackend.interchat.co.za/bot/send-message"
}
port := os.Getenv("PORT")
if port == "" {
port = "8080"
}
// 2. Настройка маршрутов
mux := http.NewServeMux()
mux.HandleFunc("POST /webhook", handleWebhook)
// Базовая конечная точка проверки работоспособности (health check)
mux.HandleFunc("GET /health", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte("Песочница бота работает (Bot Sandbox is Online)"))
})
// 3. Запуск сервера
log.Printf("🚀 Запуск песочницы бота InterChat на порту %s", port)
log.Printf("Целевой API: %s", interchatURL)
server := &http.Server{
Addr: ":" + port,
Handler: mux,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
}
log.Fatal(server.ListenAndServe())
}
// handleWebhook перехватывает JSON-данные из маршрутизатора DispatchIfBot платформы InterChat.
func handleWebhook(w http.ResponseWriter, r *http.Request) {
bodyBytes, err := io.ReadAll(r.Body)
if err != nil {
log.Printf("Ошибка чтения тела вебхука: %v", err)
http.Error(w, "Не удалось прочитать тело запроса", http.StatusBadRequest)
return
}
defer r.Body.Close()
var payload InterChatWebhookPayload
if err := json.Unmarshal(bodyBytes, &payload); err != nil {
log.Printf("Ошибка распаковки (unmarshaling) JSON-данных: %v", err)
http.Error(w, "Неверный JSON", http.StatusBadRequest)
return
}
log.Printf("Получено сообщение от пользователя [%s]. Команда: [%s], Текст: [%s]", payload.UserID, payload.Command, payload.Text)
// Немедленно подтверждаем получение, чтобы InterChat не держал соединение открытым
w.WriteHeader(http.StatusOK)
// Обработка бизнес-логики в асинхронном режиме
go processConversationFlow(payload)
}
// processConversationFlow оценивает ввод пользователя и определяет подходящий ответ.
func processConversationFlow(payload InterChatWebhookPayload) {
userText := strings.ToLower(strings.TrimSpace(payload.Text))
var replyText string
stateMutex.RLock()
currentState := userStates[payload.UserID]
stateMutex.RUnlock()
// Бизнес-логика: Сценарий отслеживания заказа
if currentState == "waiting_for_order_id" {
// Имитация поиска в базе данных
replyText = "📦 Заказ ID " + userText + " найден.\nСтатус: В пути и будет доставлен сегодня!"
log.Printf("Сценарий завершен для пользователя %s, очистка состояния.", payload.UserID)
stateMutex.Lock()
delete(userStates, payload.UserID)
stateMutex.Unlock()
} else {
// Оценка начальных команд
if payload.Command == "order" {
replyText = "Конечно! Пожалуйста, введите ваш 5-значный номер (ID) заказа:"
log.Printf("Запуск сценария заказа для пользователя %s.", payload.UserID)
stateMutex.Lock()
userStates[payload.UserID] = "waiting_for_order_id"
stateMutex.Unlock()
} else if payload.Command == "start" {
replyText = "Добро пожаловать в Logistics Corp! 🚚\n\nОтправьте /order, чтобы проверить статус отслеживания."
} else {
replyText = "Я не совсем понял. Отправьте /order для отслеживания посылки."
}
}
// Отправка ответа через InterChat API
sendReply(payload.UserID, replyText)
}
// sendReply формирует HTTP POST к InterChat, используя API-токен бота.
func sendReply(targetUserID, text string) {
reqBody := DevMessageRequest{
TargetUserID: targetUserID,
Text: text,
InlineKeyboard: "", // Строка в формате JSON-массива, если требуются интерактивные кнопки
}
jsonPayload, err := json.Marshal(reqBody)
if err != nil {
log.Printf("Ошибка упаковки (marshaling) исходящего сообщения: %v", err)
return
}
req, err := http.NewRequest("POST", interchatURL, bytes.NewBuffer(jsonPayload))
if err != nil {
log.Printf("Ошибка создания исходящего HTTP-запроса: %v", err)
return
}
// Безопасное добавление заголовков, требуемых функцией SendMessageAsBot
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer "+apiToken)
client := &http.Client{Timeout: 10 * time.Second}
resp, err := client.Do(req)
if err != nil {
log.Printf("Сетевая ошибка при отправке ответа в InterChat: %v", err)
return
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
respBytes, _ := io.ReadAll(resp.Body)
log.Printf("Ошибка API: InterChat отклонил сообщение (Статус %d): %s", resp.StatusCode, string(respBytes))
} else {
log.Printf("Ответ успешно отправлен пользователю %s", targetUserID)
}
}