!7 concept Msg { long msgID, channelID, userID; long date, edited; // epochSeconds S text; S text() { ret text; } } concept HasMsg { new Ref msg; S text() { ret msg->text; } } concept Question > HasMsg { Answer acceptedAnswer; } concept Answer > HasMsg { Question question; } standardBot1 Asker { init { dbIndexing(Msg, 'msgID, Msg, 'channelID); thread { temp enter(); for (Question q) print(q.msg->text + " => " + mapMethod text(linesAfterQuestion(q))); } } allServers { !include #1025906 // DiscordScanner L linesAfterQuestion(Question q) { long channelID = q.msg->channelID; if (channelID == 0) null; L l = conceptsWhere(Msg, +channelID); l = takeFirst(10, sortByField date(filter(l, m -> m.date > q.msg->date))); ret l; } L openQuestionsInChannel(long channelID) { ret sortedByField date(filter(conceptsWhere(Question, acceptedAnswer := null), q -> q.msg->channelID == channelID)); } } processSimplified { optPar Message msg; optPar long channelID; optPar long userID; Msg storedMsg = pairA(storeMsg(msg)); if null (s = dropMyPrefixOrNull(s)) null; if "ask me something" { S q = "Is " + random(100) + " bigger than " + random(100) + "?"; postInChannel(channelID, discordAt(userID) + " " + q, mm -> { Msg stored = pairA(storeMsg(mm)); printStruct("New question: " + cnew Question(msg := stored)); }); null; } L qs = openQuestionsInChannel(channelID); Question q = last(qs); if (q != null) { Answer a = cnew Answer(msg := storedMsg); cset(q, acceptedAnswer := a); ret "Assuming " + quote(s) + " is the answer to " + quote(q.text()); } } }