mirror of
https://github.com/prosolis/gogobee.git
synced 2026-07-15 08:32:41 +00:00
Add space groups, fix HLTB scraper, fix quote wall E2EE, improve tarot prompts
Space groups: automatic room grouping via membership overlap percentage. Rooms with sufficient shared members are grouped together so leaderboards, trivia scores, and stats aggregate across the community. Uses strict clique-based algorithm (every room must meet threshold with every other room in group). Configurable via SPACE_GROUP_THRESHOLD env var. Persisted to SQLite, recomputed hourly and on startup. HLTB scraper: rewrote for new howlongtobeat.com API (two-step token auth via /api/finder/init + /api/finder endpoint). Quote wall: fix E2EE decrypt flow for reply-to-save (ParseRaw before Decrypt, skip ParseRaw after Decrypt returns pre-parsed event). Fix subcommand matching for delete/search. Remove broken star-reaction handler and old quote handler from user.go. Other fixes: - Strip Matrix reply fallback before command detection (main.go) - Increase Ollama context window to 8192 - Improve tarot spread prompts (~4x longer, narrative arc) - Add "cards are props" instruction to tarot LLM prompt - Fix movies.go CommandDef name mismatch - Add Community category to !help - Remove daily horoscope broadcast cron - Update README with all changes Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
@@ -33,7 +32,6 @@ func (p *UserPlugin) Commands() []CommandDef {
|
||||
{Name: "settz", Description: "Set your timezone (IANA format)", Usage: "!settz America/New_York", Category: "Personal"},
|
||||
{Name: "mytz", Description: "Show your timezone and current time", Usage: "!mytz", Category: "Personal"},
|
||||
{Name: "timezone", Description: "List common timezones", Usage: "!timezone list", Category: "Personal"},
|
||||
{Name: "quote", Description: "Show a random saved quote from this room", Usage: "!quote", Category: "Personal"},
|
||||
{Name: "np", Description: "Set or show now playing", Usage: "!np [track]", Category: "Personal"},
|
||||
{Name: "backlog", Description: "Manage your personal backlog", Usage: "!backlog add/list/random/done", Category: "Personal"},
|
||||
{Name: "watch", Description: "Watch a keyword for DM alerts", Usage: "!watch <keyword>", Category: "Personal"},
|
||||
@@ -44,40 +42,7 @@ func (p *UserPlugin) Commands() []CommandDef {
|
||||
|
||||
func (p *UserPlugin) Init() error { return nil }
|
||||
|
||||
func (p *UserPlugin) OnReaction(ctx ReactionContext) error {
|
||||
if ctx.Emoji != "\u2B50" { // ⭐
|
||||
return nil
|
||||
}
|
||||
|
||||
// Fetch the target event to get the quoted message
|
||||
evt, err := p.Client.GetEvent(context.Background(), ctx.RoomID, ctx.TargetEvent)
|
||||
if err != nil {
|
||||
slog.Error("user: fetch event for quote", "err", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := evt.Content.ParseRaw(evt.Type); err != nil {
|
||||
slog.Error("user: parse event content for quote", "err", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
content := evt.Content.AsMessage()
|
||||
if content == nil || content.Body == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
d := db.Get()
|
||||
_, err = d.Exec(
|
||||
`INSERT INTO quotes (room_id, user_id, quote_text, saved_by) VALUES (?, ?, ?, ?)`,
|
||||
string(ctx.RoomID), string(evt.Sender), content.Body, string(ctx.Sender),
|
||||
)
|
||||
if err != nil {
|
||||
slog.Error("user: save quote", "err", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
return p.SendReact(ctx.RoomID, ctx.EventID, "\u2705") // ✅
|
||||
}
|
||||
func (p *UserPlugin) OnReaction(_ ReactionContext) error { return nil }
|
||||
|
||||
func (p *UserPlugin) OnMessage(ctx MessageContext) error {
|
||||
switch {
|
||||
@@ -87,8 +52,6 @@ func (p *UserPlugin) OnMessage(ctx MessageContext) error {
|
||||
return p.handleMyTZ(ctx)
|
||||
case p.IsCommand(ctx.Body, "timezone"):
|
||||
return p.handleTimezoneList(ctx)
|
||||
case p.IsCommand(ctx.Body, "quote"):
|
||||
return p.handleQuote(ctx)
|
||||
case p.IsCommand(ctx.Body, "np"):
|
||||
return p.handleNP(ctx)
|
||||
case p.IsCommand(ctx.Body, "backlog"):
|
||||
@@ -182,25 +145,6 @@ func (p *UserPlugin) handleTimezoneList(ctx MessageContext) error {
|
||||
return p.SendReply(ctx.RoomID, ctx.EventID, sb.String())
|
||||
}
|
||||
|
||||
func (p *UserPlugin) handleQuote(ctx MessageContext) error {
|
||||
d := db.Get()
|
||||
var quoteText, userID string
|
||||
err := d.QueryRow(
|
||||
`SELECT quote_text, user_id FROM quotes WHERE room_id = ? ORDER BY RANDOM() LIMIT 1`,
|
||||
string(ctx.RoomID),
|
||||
).Scan("eText, &userID)
|
||||
if err == sql.ErrNoRows {
|
||||
return p.SendReply(ctx.RoomID, ctx.EventID, "No quotes saved in this room yet. React with a star to save one!")
|
||||
}
|
||||
if err != nil {
|
||||
slog.Error("user: random quote", "err", err)
|
||||
return p.SendReply(ctx.RoomID, ctx.EventID, "Failed to fetch a quote.")
|
||||
}
|
||||
|
||||
msg := fmt.Sprintf("\"%s\"\n — %s", quoteText, userID)
|
||||
return p.SendReply(ctx.RoomID, ctx.EventID, msg)
|
||||
}
|
||||
|
||||
func (p *UserPlugin) handleNP(ctx MessageContext) error {
|
||||
args := strings.TrimSpace(p.GetArgs(ctx.Body, "np"))
|
||||
d := db.Get()
|
||||
|
||||
Reference in New Issue
Block a user