Skip to content

Commit

Permalink
Delay sending anon links when new anon links are posted
Browse files Browse the repository at this point in the history
  • Loading branch information
rcy committed Dec 27, 2024
1 parent ebe6bb0 commit c3df4d9
Show file tree
Hide file tree
Showing 9 changed files with 157 additions and 39 deletions.
11 changes: 11 additions & 0 deletions db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,17 @@ create table bedtimes(
nick text not null,
message text
);
`)
return err
},
func(tx migration.LimitedTx) error {
log.Println("MIGRATE: add future messages")
_, err := tx.Exec(`
create table future_messages(
id integer not null primary key,
created_at datetime not null default current_timestamp,
kind text not null
);
`)
return err
},
Expand Down
13 changes: 13 additions & 0 deletions db/model/models.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

56 changes: 31 additions & 25 deletions db/model/query.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions db/query.sql
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,12 @@ select * from notes where kind='note' order by created_at desc;

-- name: NotesAndQuotes :many
select * from notes where kind='note' or kind='quote' order by created_at desc;

-- name: ScheduleFutureMessage :one
insert into future_messages(kind) values(?) returning *;

-- name: ReadyFutureMessage :one
select * from future_messages where datetime('now') > datetime(created_at, ?) limit 1;

-- name: DeleteFutureMessage :exec
delete from future_messages where id = ?;
15 changes: 13 additions & 2 deletions db/schema.sql
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
CREATE TABLE links(created_at text, nick text, text text);
CREATE TABLE migration_version (
version INTEGER
);
CREATE TABLE links(created_at text, nick text, text text);
CREATE TABLE laters(created_at text, nick text, target text, message text, sent boolean default false);
CREATE TABLE notes(
id INTEGER not null primary key,
Expand Down Expand Up @@ -41,17 +41,28 @@ CREATE TABLE IF NOT EXISTS channel_nicks(
present bool not null default false,
updated_at datetime not null
);
CREATE UNIQUE INDEX channel_nick_unique_index on "channel_nicks"(channel, nick);
CREATE TABLE generated_images(
id integer not null primary key,
created_at datetime not null default current_timestamp,
filename text not null,
prompt text not null,
revised_prompt text not null
);
CREATE UNIQUE INDEX channel_nick_unique_index on "channel_nicks"(channel, nick);
CREATE TABLE nick_sessions(
id integer not null primary key,
created_at datetime not null default current_timestamp,
nick text not null,
session text not null
);
CREATE TABLE bedtimes(
id integer not null primary key,
created_at datetime not null default current_timestamp,
nick text not null,
message text
);
CREATE TABLE future_messages(
id integer not null primary key,
created_at datetime not null default current_timestamp,
kind text not null
);
64 changes: 61 additions & 3 deletions handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"context"
"database/sql"
"errors"
"goirc/bot"
"goirc/db/model"
Expand Down Expand Up @@ -79,9 +80,10 @@ func addHandlers(b *bot.Bot) {
panic(err)
}

q := model.New(db.DB.DB)

c := cron.NewWithLocation(location)
err = c.AddFunc("16 14 15 * * 1,2,3,4,5,6", func() {
q := model.New(db.DB.DB)
note, err := q.RandomHistoricalTodayNote(context.TODO())
if err != nil {
// TODO test no rows
Expand Down Expand Up @@ -114,6 +116,58 @@ func addHandlers(b *bot.Bot) {
panic(err)
}

err = c.AddFunc("57 * * * * *", func() {
ctx := context.TODO()
msg, err := q.ReadyFutureMessage(ctx, handlers.FutureMessageInterval)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return
}
b.Conn.Privmsg(b.Channel, err.Error())
return
}
err = q.DeleteFutureMessage(ctx, msg.ID)
if err != nil {
b.Conn.Privmsg(b.Channel, err.Error())
return
}

// send anonymous note
switch msg.Kind {
case "link":
err = handlers.AnonLink(bot.HandlerParams{
Target: b.Channel,
Privmsgf: b.MakePrivmsgf(),
})
case "quote":
err = handlers.AnonQuote(bot.HandlerParams{
Target: b.Channel,
Privmsgf: b.MakePrivmsgf(),
})
default:
b.Conn.Privmsgf(b.Channel, "unhandled msg.Kind: %s", msg.Kind)
}
if err != nil {
if errors.Is(err, ai.ErrBilling) {
// the quote was sent, but no generated image, this is fine
return
}
if errors.Is(err, linkpool.NoNoteFoundError) {
// didn't find a note, reschedule
_, scheduleErr := q.ScheduleFutureMessage(ctx, msg.Kind)
if scheduleErr != nil {
b.Conn.Privmsg(b.Channel, "error rescheduling: "+scheduleErr.Error())
}
return
}
// something else happened, spam the channel
b.Conn.Privmsg(b.Channel, "error: "+err.Error())
}
})
if err != nil {
panic(err)
}

c.Start()

events.Subscribe("anonnoteposted", func(note any) {
Expand All @@ -123,9 +177,13 @@ func addHandlers(b *bot.Bot) {
Privmsgf: b.MakePrivmsgf(),
})
if err != nil {
if !errors.Is(err, linkpool.NoNoteFoundError) {
b.Conn.Privmsg(b.Channel, "error: "+err.Error())
if errors.Is(err, ai.ErrBilling) {
return
}
if errors.Is(err, linkpool.NoNoteFoundError) {
return
}
b.Conn.Privmsg(b.Channel, "error: "+err.Error())
}
}()
})
Expand Down
7 changes: 5 additions & 2 deletions handlers/anonlink.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@ import (
"goirc/handlers/linkpool"
"goirc/image"
db "goirc/model"
"time"
)

const (
minAge = 7 * time.Hour * 24
// how old a message must be before it is delivered
minAge = 0 //7 * time.Hour * 24

// how long to wait after an anon message is posted to send one from the queue
FutureMessageInterval = "+1 hour"
)

func AnonLink(params bot.HandlerParams) error {
Expand Down
9 changes: 5 additions & 4 deletions handlers/link.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func Link(params bot.HandlerParams) error {
// posted in a private message?
isAnonymous := params.Target == params.Nick

note, err := q.InsertNote(context.TODO(), model.InsertNoteParams{
_, err := q.InsertNote(context.TODO(), model.InsertNoteParams{
Target: params.Target,
Nick: sql.NullString{String: params.Nick, Valid: true},
Kind: "link",
Expand All @@ -28,12 +28,13 @@ func Link(params bot.HandlerParams) error {
}

if isAnonymous {
link, err := note.Link()
_, err = q.ScheduleFutureMessage(context.TODO(), "link")
if err != nil {
return err
}
params.Privmsgf(params.Target, "%s will be shared later, maybe", link)
params.Publish("anonnoteposted", note)

params.Privmsgf(params.Target, "thanks for the link")

return nil
}

Expand Down
12 changes: 9 additions & 3 deletions handlers/quote.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func Quote(params bot.HandlerParams) error {
// posted to private channel
isAnonymous := params.Target == params.Nick

note, err := q.InsertNote(context.TODO(), model.InsertNoteParams{
_, err := q.InsertNote(context.TODO(), model.InsertNoteParams{
Target: params.Target,
Nick: sql.NullString{String: params.Nick, Valid: true},
Kind: "quote",
Expand All @@ -27,8 +27,14 @@ func Quote(params bot.HandlerParams) error {
}

if isAnonymous {
params.Privmsgf(params.Target, "stored quote to share later, maybe")
params.Publish("anonquoteposted", note)
_, err = q.ScheduleFutureMessage(context.TODO(), "quote")
if err != nil {
return err
}

params.Privmsgf(params.Target, "thanks for the quote")

return nil
}

return nil
Expand Down

0 comments on commit c3df4d9

Please sign in to comment.