Implement the R-1 adapter (FT-WP-0001 T05/T09); mark workplans blocked
Builds internal/adapter and cmd/adapter: the three contracts/r1.openapi.yaml
operations, idempotency on post_id, the reviewed_by/consent-basis refusals,
per-form (R-2/R-3) length limits, and Markdown-to-Telegram rendering, all
against a Sender interface so it's testable without a live bot token.
Every other open task in FT-WP-0001 and FT-WP-0002 needs something this repo
can't supply on its own: the human session bootstrap in FT-WP-0002 T01, the
fluid CLI from fluid-core, or a person's judgment (consent basis, editorial
review, publishing pace). Set both workplans to status: blocked and flagged
FT-WP-0002-T01 needs_human on the hub, since it's the single blocker gating
everything else.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Assistant: claude-code
Assistant-Model: sonnet
Assistant-Process: 278411@bnt-lap001
Assistant-Session: 19568045-15bc-4b88-ba3d-8e95b4f9c6f1
2026-09-27 23:15:29 +02:00
|
|
|
// Command adapter runs the R-1 Telegram publishing adapter for one channel.
|
|
|
|
|
//
|
|
|
|
|
// It owns rendering and delivery only: it has no MTProto session and no
|
|
|
|
|
// provisioning code path, so a compromised adapter cannot create, rename,
|
|
|
|
|
// delete or re-permission anything (docs/adapter-contract.md). Configuration
|
|
|
|
|
// comes from `provision adapter-config`, per that same doc's Configuration
|
|
|
|
|
// section.
|
|
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"log"
|
|
|
|
|
"net/http"
|
|
|
|
|
"os"
|
|
|
|
|
"strconv"
|
2026-10-08 20:55:32 +02:00
|
|
|
"strings"
|
Implement the R-1 adapter (FT-WP-0001 T05/T09); mark workplans blocked
Builds internal/adapter and cmd/adapter: the three contracts/r1.openapi.yaml
operations, idempotency on post_id, the reviewed_by/consent-basis refusals,
per-form (R-2/R-3) length limits, and Markdown-to-Telegram rendering, all
against a Sender interface so it's testable without a live bot token.
Every other open task in FT-WP-0001 and FT-WP-0002 needs something this repo
can't supply on its own: the human session bootstrap in FT-WP-0002 T01, the
fluid CLI from fluid-core, or a person's judgment (consent basis, editorial
review, publishing pace). Set both workplans to status: blocked and flagged
FT-WP-0002-T01 needs_human on the hub, since it's the single blocker gating
everything else.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Assistant: claude-code
Assistant-Model: sonnet
Assistant-Process: 278411@bnt-lap001
Assistant-Session: 19568045-15bc-4b88-ba3d-8e95b4f9c6f1
2026-09-27 23:15:29 +02:00
|
|
|
|
|
|
|
|
"github.com/tegwick/fluid-telegram/internal/adapter"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
|
if err := run(); err != nil {
|
|
|
|
|
log.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func run() error {
|
|
|
|
|
token := os.Getenv("TELEGRAM_BOT_TOKEN")
|
|
|
|
|
if token == "" {
|
|
|
|
|
return fmt.Errorf("TELEGRAM_BOT_TOKEN is not set; injected from OpenBao at start, see docs/adapter-contract.md")
|
|
|
|
|
}
|
|
|
|
|
chatIDStr := os.Getenv("TELEGRAM_CHANNEL_ID")
|
|
|
|
|
if chatIDStr == "" {
|
|
|
|
|
return fmt.Errorf("TELEGRAM_CHANNEL_ID is not set; run `provision adapter-config`")
|
|
|
|
|
}
|
|
|
|
|
chatID, err := strconv.ParseInt(chatIDStr, 10, 64)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("TELEGRAM_CHANNEL_ID %q is not an integer: %w", chatIDStr, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
attachVisual := os.Getenv("ATTACH_VISUAL") == "true"
|
|
|
|
|
controlURL := os.Getenv("FLUID_CONTROL_URL")
|
|
|
|
|
hallBaseURL := os.Getenv("HALL_BASE_URL")
|
|
|
|
|
|
|
|
|
|
addr := os.Getenv("ADAPTER_LISTEN_ADDR")
|
|
|
|
|
if addr == "" {
|
|
|
|
|
addr = ":8080"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cfg := adapter.Config{
|
|
|
|
|
ChatID: chatID,
|
|
|
|
|
AttachVisual: attachVisual,
|
|
|
|
|
HallBaseURL: hallBaseURL,
|
|
|
|
|
}
|
2026-10-08 20:55:32 +02:00
|
|
|
// UPLOAD_VISUALS=true: fetch images from VISUAL_HOSTS (default the forge)
|
|
|
|
|
// and upload them, optionally with FORGE_READ_TOKEN, so Telegram never needs
|
|
|
|
|
// a public image URL (FT-WP-0001-T14).
|
|
|
|
|
if os.Getenv("UPLOAD_VISUALS") == "true" {
|
|
|
|
|
hosts := strings.Split(os.Getenv("VISUAL_HOSTS"), ",")
|
|
|
|
|
if strings.TrimSpace(os.Getenv("VISUAL_HOSTS")) == "" {
|
|
|
|
|
hosts = []string{"forgejo.coulomb.social"}
|
|
|
|
|
}
|
|
|
|
|
cfg.Visuals = adapter.NewVisualFetcher(hosts, os.Getenv("FORGE_READ_TOKEN"))
|
|
|
|
|
}
|
Implement the R-1 adapter (FT-WP-0001 T05/T09); mark workplans blocked
Builds internal/adapter and cmd/adapter: the three contracts/r1.openapi.yaml
operations, idempotency on post_id, the reviewed_by/consent-basis refusals,
per-form (R-2/R-3) length limits, and Markdown-to-Telegram rendering, all
against a Sender interface so it's testable without a live bot token.
Every other open task in FT-WP-0001 and FT-WP-0002 needs something this repo
can't supply on its own: the human session bootstrap in FT-WP-0002 T01, the
fluid CLI from fluid-core, or a person's judgment (consent basis, editorial
review, publishing pace). Set both workplans to status: blocked and flagged
FT-WP-0002-T01 needs_human on the hub, since it's the single blocker gating
everything else.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Assistant: claude-code
Assistant-Model: sonnet
Assistant-Process: 278411@bnt-lap001
Assistant-Session: 19568045-15bc-4b88-ba3d-8e95b4f9c6f1
2026-09-27 23:15:29 +02:00
|
|
|
a := adapter.New(cfg, adapter.NewBotAPISender(token), adapter.NewMemStore(), adapter.NewHTTPTelemetry(controlURL))
|
|
|
|
|
|
2026-10-08 20:55:32 +02:00
|
|
|
log.Printf("adapter listening on %s (chat_id=%d, attach_visual=%v, upload_visuals=%v)", addr, chatID, attachVisual, cfg.Visuals != nil)
|
Implement the R-1 adapter (FT-WP-0001 T05/T09); mark workplans blocked
Builds internal/adapter and cmd/adapter: the three contracts/r1.openapi.yaml
operations, idempotency on post_id, the reviewed_by/consent-basis refusals,
per-form (R-2/R-3) length limits, and Markdown-to-Telegram rendering, all
against a Sender interface so it's testable without a live bot token.
Every other open task in FT-WP-0001 and FT-WP-0002 needs something this repo
can't supply on its own: the human session bootstrap in FT-WP-0002 T01, the
fluid CLI from fluid-core, or a person's judgment (consent basis, editorial
review, publishing pace). Set both workplans to status: blocked and flagged
FT-WP-0002-T01 needs_human on the hub, since it's the single blocker gating
everything else.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Assistant: claude-code
Assistant-Model: sonnet
Assistant-Process: 278411@bnt-lap001
Assistant-Session: 19568045-15bc-4b88-ba3d-8e95b4f9c6f1
2026-09-27 23:15:29 +02:00
|
|
|
return http.ListenAndServe(addr, a.Handler())
|
|
|
|
|
}
|