refactor notification handling
This commit is contained in:
parent
8487f60cff
commit
0fb455ef53
1 changed files with 41 additions and 19 deletions
|
@ -4,7 +4,7 @@ from asyncio import TaskGroup
|
||||||
from disnake import Embed
|
from disnake import Embed
|
||||||
from disnake.ext.commands import Cog, group, guild_only
|
from disnake.ext.commands import Cog, group, guild_only
|
||||||
|
|
||||||
from .utils import can_view, confirm, test_keyword, unpack
|
from .utils import can_view, confirm, fetch_unpacked, test_keyword
|
||||||
|
|
||||||
log = logging.getLogger("nomen.notifications")
|
log = logging.getLogger("nomen.notifications")
|
||||||
log.setLevel(logging.INFO)
|
log.setLevel(logging.INFO)
|
||||||
|
@ -40,31 +40,53 @@ async def handle_notification(db_updates, ctx, message, keyword, user_id):
|
||||||
|
|
||||||
|
|
||||||
async def handle_triggers(ctx, message):
|
async def handle_triggers(ctx, message):
|
||||||
cur = await ctx.bot.db.execute("SELECT disabled FROM users WHERE user_id=?", (ctx.author.id,))
|
"""
|
||||||
res = await cur.fetchone()
|
Main function that handles message triggers
|
||||||
|
"""
|
||||||
|
|
||||||
if res and res[0]:
|
params = {
|
||||||
|
"author": ctx.author.id,
|
||||||
|
"channel": ctx.channel.id,
|
||||||
|
"guild": ctx.guild.id,
|
||||||
|
"content": message.content,
|
||||||
|
"is_bot": ctx.author.bot,
|
||||||
|
}
|
||||||
|
|
||||||
|
disabled = await ctx.bot.db.execute_fetchall(
|
||||||
|
"SELECT EXISTS(SELECT * FROM users WHERE user_id=:author AND disabled IS 1)", params
|
||||||
|
)[0]
|
||||||
|
|
||||||
|
if disabled:
|
||||||
log.debug(f"User {ctx.author} ({ctx.author.id}) opted out")
|
log.debug(f"User {ctx.author} ({ctx.author.id}) opted out")
|
||||||
return
|
return
|
||||||
|
|
||||||
handled_users = [ctx.author.id]
|
|
||||||
db_updates = []
|
db_updates = []
|
||||||
|
|
||||||
|
search_query = """
|
||||||
|
SELECT keyword, user_id, use_embed
|
||||||
|
FROM ( -- Deduplicate notification recipients by user_id
|
||||||
|
SELECT keyword, user_id, use_embed, row_number() over (partition by user_id) n
|
||||||
|
FROM keywords
|
||||||
|
LEFT JOIN users USING (user_id)
|
||||||
|
WHERE disabled IS NOT 1 -- Don't notify users who opted out
|
||||||
|
AND (notify_self IS 1 OR user_id IS NOT :author) -- Don't notify author unless wanted
|
||||||
|
AND (bots_notify IS 1 OR :is_bot IS NOT 1) -- Don't notify from bots unless wanted
|
||||||
|
AND :author NOT IN ( -- Don't notify if...
|
||||||
|
SELECT target FROM user_ignores -- Author is ignored in this guilde
|
||||||
|
WHERE user_id=user_id AND guild_id=guild_id
|
||||||
|
UNION
|
||||||
|
SELECT target FROM user_blocks -- Author is blocked
|
||||||
|
WHERE user_id=user_id
|
||||||
|
)
|
||||||
|
AND guild_id=:guild AND contains(:content, keyword, regex)
|
||||||
|
)
|
||||||
|
WHERE n=1
|
||||||
|
"""
|
||||||
|
|
||||||
async with TaskGroup() as tg:
|
async with TaskGroup() as tg:
|
||||||
async with ctx.bot.db.execute(
|
async with ctx.bot.db.execute(search_query, params) as cur:
|
||||||
"""SELECT keyword, user_id
|
async for keyword, user_id, use_embed in cur:
|
||||||
FROM keywords LEFT JOIN users USING (user_id)
|
log.debug(f"- Creating notification task: '{keyword}' for {user_id}")
|
||||||
WHERE disabled IS NOT 1 AND guild_id=? AND contains(?, keyword, regex)""",
|
|
||||||
(ctx.guild.id, message.content),
|
|
||||||
) as cur:
|
|
||||||
async for keyword, user_id in cur:
|
|
||||||
log.debug(f"- Handling '{keyword}' for {user_id}")
|
|
||||||
|
|
||||||
if user_id in handled_users:
|
|
||||||
log.debug(f"- - Ignoring {user_id}")
|
|
||||||
continue
|
|
||||||
|
|
||||||
handled_users.append(user_id)
|
|
||||||
|
|
||||||
tg.create_task(handle_notification(db_updates, ctx, message, keyword, user_id))
|
tg.create_task(handle_notification(db_updates, ctx, message, keyword, user_id))
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue