From 7240a871e78dc6215fbc8f59a34c3527aae1cbd5 Mon Sep 17 00:00:00 2001 From: GoldOrange261 <63157008+GoldOrange261@users.noreply.github.com> Date: Sun, 12 Nov 2023 19:04:51 +0800 Subject: [PATCH 01/11] feat: new permission checking method, each server can be overridden by itself, default is administrator --- cogs/list_users.py | 5 ++--- cogs/notification.py | 8 +++----- src/permission.py | 5 +++++ src/permission_check.py | 15 --------------- 4 files changed, 10 insertions(+), 23 deletions(-) create mode 100644 src/permission.py delete mode 100644 src/permission_check.py diff --git a/cogs/list_users.py b/cogs/list_users.py index 1a34c4d..fc7acf6 100644 --- a/cogs/list_users.py +++ b/cogs/list_users.py @@ -4,13 +4,12 @@ import sqlite3 import os -from src.permission_check import is_administrator +from src.permission import ADMINISTRATOR class ListUsers(Cog_Extension): - list_group = app_commands.Group(name='list', description="List something") + list_group = app_commands.Group(name='list', description='List something', default_permissions=ADMINISTRATOR) - @is_administrator() @list_group.command(name='users') async def list_users(self, itn: discord.Interaction): """Lists all exists notifier on your server.""" diff --git a/cogs/notification.py b/cogs/notification.py index a3e9ffb..736582c 100644 --- a/cogs/notification.py +++ b/cogs/notification.py @@ -9,7 +9,7 @@ from src.log import setup_logger from src.notification.account_tracker import AccountTracker -from src.permission_check import is_administrator +from src.permission import ADMINISTRATOR log = setup_logger(__name__) @@ -20,11 +20,10 @@ def __init__(self, bot): super().__init__(bot) self.account_tracker = AccountTracker(bot) - add_group = app_commands.Group(name='add', description="Add something") - remove_group = app_commands.Group(name='remove', description='Remove something') + add_group = app_commands.Group(name='add', description='Add something', default_permissions=ADMINISTRATOR) + remove_group = app_commands.Group(name='remove', description='Remove something', default_permissions=ADMINISTRATOR) - @is_administrator() @add_group.command(name='notifier') async def notifier(self, itn : discord.Interaction, username: str, channel: discord.TextChannel, mention: discord.Role = None): """Add a twitter user to specific channel on your server. @@ -79,7 +78,6 @@ async def notifier(self, itn : discord.Interaction, username: str, channel: disc await itn.followup.send(f'successfully add notifier of {username}!', ephemeral=True) - @is_administrator() @remove_group.command(name='notifier') async def notifier(self, itn : discord.Interaction, username: str, channel: discord.TextChannel): """Remove a notifier on your server. diff --git a/src/permission.py b/src/permission.py new file mode 100644 index 0000000..2f2fa26 --- /dev/null +++ b/src/permission.py @@ -0,0 +1,5 @@ +import discord +from typing import Final + + +ADMINISTRATOR: Final[discord.Permissions] = discord.Permissions(8) \ No newline at end of file diff --git a/src/permission_check.py b/src/permission_check.py deleted file mode 100644 index 02d917b..0000000 --- a/src/permission_check.py +++ /dev/null @@ -1,15 +0,0 @@ -import discord -from discord import app_commands - - -def is_owner(): - async def predicate(itn : discord.Interaction): - info = await itn.client.application_info() - return itn.user == info.owner - return app_commands.check(predicate) - - -def is_administrator(): - def predicate(itn : discord.Interaction): - return itn.user.guild_permissions.administrator - return app_commands.check(predicate) \ No newline at end of file From 72fd5bd5b537aa9e30f93c9748269349938a2527 Mon Sep 17 00:00:00 2001 From: GoldOrange261 <63157008+GoldOrange261@users.noreply.github.com> Date: Sat, 18 Nov 2023 13:02:57 +0800 Subject: [PATCH 02/11] feat: remove unnecessary judgments within on_tree_error --- bot.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/bot.py b/bot.py index 8a32269..1e44503 100644 --- a/bot.py +++ b/bot.py @@ -73,10 +73,7 @@ async def upload_data(ctx : commands.context.Context): @bot.event async def on_tree_error(itn : discord.Interaction, error : app_commands.AppCommandError): - if isinstance(error, app_commands.errors.CheckFailure): - await itn.response.send_message('Permission denied.', ephemeral=True) - else: - await itn.response.send_message(error, ephemeral=True) + await itn.response.send_message(error, ephemeral=True) log.warning(f'an error occurred but was handled by the tree error handler, error message : {error}') From e54d6ef53de4120fdbc8eac688600e49c54a072e Mon Sep 17 00:00:00 2001 From: GoldOrange261 <63157008+GoldOrange261@users.noreply.github.com> Date: Sun, 21 Jan 2024 22:31:53 +0800 Subject: [PATCH 03/11] feat: after changing your twitter account, you can use the sync command to enable notifications in the new account --- cogs/sync.py | 40 ++++++++++++++++++++++++++++++++++++++++ src/sync_db/sync_db.py | 22 ++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 cogs/sync.py create mode 100644 src/sync_db/sync_db.py diff --git a/cogs/sync.py b/cogs/sync.py new file mode 100644 index 0000000..81fae82 --- /dev/null +++ b/cogs/sync.py @@ -0,0 +1,40 @@ +import discord +from discord import app_commands +from core.classes import Cog_Extension +from dotenv import load_dotenv +import os +import sqlite3 + +from src.log import setup_logger +from src.sync_db.sync_db import sync_db + +log = setup_logger(__name__) + +load_dotenv() + +class Sync(Cog_Extension): + + @app_commands.command(name='sync') + async def sync(self, itn : discord.Interaction): + """To sync the notification of new Twitter account with database, use this command. + """ + + await itn.response.defer(ephemeral=True) + + conn = sqlite3.connect(f"{os.getenv('DATA_PATH')}tracked_accounts.db") + conn.row_factory = sqlite3.Row + cursor = conn.cursor() + + cursor.execute('SELECT * FROM user') + follow_list = cursor.fetchall() + + conn.commit() + conn.close() + + self.bot.loop.create_task(sync_db(follow_list)) + + await itn.followup.send(f'synchronizing in the background', ephemeral=True) + + +async def setup(bot): + await bot.add_cog(Sync(bot)) \ No newline at end of file diff --git a/src/sync_db/sync_db.py b/src/sync_db/sync_db.py new file mode 100644 index 0000000..3e3ac35 --- /dev/null +++ b/src/sync_db/sync_db.py @@ -0,0 +1,22 @@ +from tweety import Twitter +from dotenv import load_dotenv +import os +import asyncio + +from src.log import setup_logger + +log = setup_logger(__name__) + +load_dotenv() + +async def sync_db(follow_list): + app = Twitter("session") + app.load_auth_token(os.getenv('TWITTER_TOKEN')) + + for user in follow_list: + user_id = user[0] + app.follow_user(user_id) + app.enable_user_notification(user_id) + await asyncio.sleep(1) + + log.info('synchronization with database completed') \ No newline at end of file From dcc52754e075729d7f216ddec0f06fbf78d6e054 Mon Sep 17 00:00:00 2001 From: GoldOrange261 <63157008+GoldOrange261@users.noreply.github.com> Date: Mon, 22 Jan 2024 23:17:27 +0800 Subject: [PATCH 04/11] feat: when all notifications for an account are turned off, the task will also be turned off. --- bot.py | 4 ++-- cogs/notification.py | 24 ++++++++++++++++++------ src/db_function/init_db.py | 2 +- src/notification/account_tracker.py | 24 ++++++++++++++++++++++-- 4 files changed, 43 insertions(+), 11 deletions(-) diff --git a/bot.py b/bot.py index 1e44503..0489de2 100644 --- a/bot.py +++ b/bot.py @@ -21,8 +21,8 @@ async def on_ready(): if not(os.path.isfile(f"{os.getenv('DATA_PATH')}tracked_accounts.db")): init_db() bot.tree.on_error = on_tree_error for filename in os.listdir('./cogs'): - if filename.endswith('.py'): - await bot.load_extension(f'cogs.{filename[:-3]}') + if filename.endswith('.py'): + await bot.load_extension(f'cogs.{filename[:-3]}') log.info(f'{bot.user} is online') slash = await bot.tree.sync() log.info(f'synced {len(slash)} slash commands') diff --git a/cogs/notification.py b/cogs/notification.py index 736582c..29952ee 100644 --- a/cogs/notification.py +++ b/cogs/notification.py @@ -49,7 +49,7 @@ async def notifier(self, itn : discord.Interaction, username: str, channel: disc server_id = str(channel.guild.id) roleID = str(mention.id) if mention != None else '' - if match_user == None: + if match_user == None or match_user['enabled'] == 0: app = Twitter("session") app.load_auth_token(os.getenv('TWITTER_TOKEN')) try: @@ -58,9 +58,15 @@ async def notifier(self, itn : discord.Interaction, username: str, channel: disc await itn.followup.send(f'user {username} not found', ephemeral=True) return - cursor.execute('INSERT INTO user VALUES (?, ?, ?)', (str(new_user.id), username, datetime.utcnow().replace(tzinfo=timezone.utc).strftime('%Y-%m-%d %H:%M:%S%z'))) - cursor.execute('INSERT OR IGNORE INTO channel VALUES (?, ?)', (str(channel.id), server_id)) - cursor.execute('INSERT INTO notification (user_id, channel_id, role_id) VALUES (?, ?, ?)', (str(new_user.id), str(channel.id), roleID)) + if match_user == None: + cursor.execute('INSERT INTO user VALUES (?, ?, ?)', (str(new_user.id), username, datetime.utcnow().replace(tzinfo=timezone.utc).strftime('%Y-%m-%d %H:%M:%S%z'))) + cursor.execute('INSERT OR IGNORE INTO channel VALUES (?, ?)', (str(channel.id), server_id)) + cursor.execute('INSERT INTO notification (user_id, channel_id, role_id) VALUES (?, ?, ?)', (str(new_user.id), str(channel.id), roleID)) + else: + cursor.execute('INSERT OR IGNORE INTO channel VALUES (?, ?)', (str(channel.id), server_id)) + cursor.execute('REPLACE INTO notification (user_id, channel_id, role_id) VALUES (?, ?, ?)', (match_user['id'], str(channel.id), roleID)) + cursor.execute('UPDATE user SET enabled = 1 WHERE id = ?', (match_user['id'],)) + app.follow_user(new_user) @@ -73,7 +79,7 @@ async def notifier(self, itn : discord.Interaction, username: str, channel: disc conn.commit() conn.close() - if match_user == None: await self.account_tracker.addTask(username) + if match_user == None or match_user['enabled'] == 0: await self.account_tracker.addTask(username) await itn.followup.send(f'successfully add notifier of {username}!', ephemeral=True) @@ -96,12 +102,18 @@ async def notifier(self, itn : discord.Interaction, username: str, channel: disc conn.row_factory = sqlite3.Row cursor = conn.cursor() - cursor.execute('SELECT user_id FROM notification, user WHERE username = ? AND channel_id = ? AND user_id = id', (username, str(channel.id))) + cursor.execute('SELECT user_id FROM notification, user WHERE username = ? AND channel_id = ? AND user_id = id AND notification.enabled = 1', (username, str(channel.id))) match_notifier = cursor.fetchone() if match_notifier != None: cursor.execute('UPDATE notification SET enabled = 0 WHERE user_id = ? AND channel_id = ?', (match_notifier['user_id'], str(channel.id))) conn.commit() await itn.followup.send(f'successfully remove notifier of {username}!', ephemeral=True) + cursor.execute('SELECT user_id FROM notification WHERE user_id = ? AND enabled = 1', (match_notifier['user_id'],)) + if len(cursor.fetchall()) == 0: + cursor.execute('UPDATE user SET enabled = 0 WHERE id = ?', (match_notifier['user_id'],)) + conn.commit() + await self.account_tracker.removeTask(username) + else: await itn.followup.send(f'can\'t find notifier {username} in {channel.mention}!', ephemeral=True) diff --git a/src/db_function/init_db.py b/src/db_function/init_db.py index 33e3fb8..c70dc6b 100644 --- a/src/db_function/init_db.py +++ b/src/db_function/init_db.py @@ -6,7 +6,7 @@ def init_db(): conn = sqlite3.connect(f"{os.getenv('DATA_PATH')}tracked_accounts.db") cursor = conn.cursor() cursor.executescript(""" - CREATE TABLE IF NOT EXISTS user (id TEXT PRIMARY KEY, username TEXT, lastest_tweet TEXT); + CREATE TABLE IF NOT EXISTS user (id TEXT PRIMARY KEY, username TEXT, lastest_tweet TEXT, enabled INTEGER DEFAULT 1); CREATE TABLE IF NOT EXISTS channel (id TEXT PRIMARY KEY, server_id TEXT); CREATE TABLE IF NOT EXISTS notification (user_id TEXT, channel_id TEXT, role_id TEXT, enabled INTEGER DEFAULT 1, FOREIGN KEY (user_id) REFERENCES user (id), FOREIGN KEY (channel_id) REFERENCES channel (id), PRIMARY KEY(user_id, channel_id)); """) diff --git a/src/notification/account_tracker.py b/src/notification/account_tracker.py index 634e83f..a99ae6c 100644 --- a/src/notification/account_tracker.py +++ b/src/notification/account_tracker.py @@ -30,7 +30,7 @@ async def setup_tasks(self): cursor = conn.cursor() self.bot.loop.create_task(self.tweetsUpdater(app)).set_name('TweetsUpdater') - cursor.execute('SELECT username FROM user') + cursor.execute('SELECT username FROM user WHERE enabled = 1') usernames = [] for user in cursor: username = user[0] @@ -114,7 +114,27 @@ async def addTask(self, username : str): if task.get_name() == 'TasksMonitor': try: log.info(f'existing TasksMonitor has been closed') if task.cancel() else log.info('existing TasksMonitor failed to close') except Exception as e: log.warning(f'addTask : {e}') - self.bot.loop.create_task(self.tasksMonitor({user[0] for user in cursor.execute('SELECT username FROM user').fetchall()})).set_name('TasksMonitor') + self.bot.loop.create_task(self.tasksMonitor({user[0] for user in cursor.execute('SELECT username FROM user WHERE enabled = 1').fetchall()})).set_name('TasksMonitor') + log.info(f'new TasksMonitor has been started') + + conn.close() + + + async def removeTask(self, username : str): + conn = sqlite3.connect(f"{os.getenv('DATA_PATH')}tracked_accounts.db") + cursor = conn.cursor() + + for task in asyncio.all_tasks(): + if task.get_name() == 'TasksMonitor': + try: log.info(f'existing TasksMonitor has been closed') if task.cancel() else log.info('existing TasksMonitor failed to close') + except Exception as e: log.warning(f'removeTask : {e}') + + for task in asyncio.all_tasks(): + if task.get_name() == username: + try: log.info(f'existing task {username} has been closed') if task.cancel() else log.info(f'existing task {username} failed to close') + except Exception as e: log.warning(f'removeTask : {e}') + + self.bot.loop.create_task(self.tasksMonitor({user[0] for user in cursor.execute('SELECT username FROM user WHERE enabled = 1').fetchall()})).set_name('TasksMonitor') log.info(f'new TasksMonitor has been started') conn.close() \ No newline at end of file From c638e5d69aaa236d94a1d1f2514ee9143e5da1c2 Mon Sep 17 00:00:00 2001 From: GoldOrange261 <63157008+GoldOrange261@users.noreply.github.com> Date: Tue, 23 Jan 2024 07:39:11 +0800 Subject: [PATCH 05/11] feat: now can decide to disable notifications or unfollow a Twitter account after disable all notifications for a user --- cogs/notification.py | 13 ++++++++++++- configs.yml | 4 +++- requirements.txt | 2 +- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/cogs/notification.py b/cogs/notification.py index 29952ee..e310d5d 100644 --- a/cogs/notification.py +++ b/cogs/notification.py @@ -10,6 +10,7 @@ from src.log import setup_logger from src.notification.account_tracker import AccountTracker from src.permission import ADMINISTRATOR +from configs.load_configs import configs log = setup_logger(__name__) @@ -70,7 +71,7 @@ async def notifier(self, itn : discord.Interaction, username: str, channel: disc app.follow_user(new_user) - if app.enable_user_notification(new_user): log.info(f'successfully opened notification for {username}') + if app.enable_user_notification(new_user): log.info(f'successfully turned on notification for {username}') else: log.warning(f'unable to turn on notifications for {username}') else: cursor.execute('INSERT OR IGNORE INTO channel VALUES (?, ?)', (str(channel.id), server_id)) @@ -109,10 +110,20 @@ async def notifier(self, itn : discord.Interaction, username: str, channel: disc conn.commit() await itn.followup.send(f'successfully remove notifier of {username}!', ephemeral=True) cursor.execute('SELECT user_id FROM notification WHERE user_id = ? AND enabled = 1', (match_notifier['user_id'],)) + if len(cursor.fetchall()) == 0: cursor.execute('UPDATE user SET enabled = 0 WHERE id = ?', (match_notifier['user_id'],)) conn.commit() await self.account_tracker.removeTask(username) + if configs['auto_unfollow'] or configs['auto_turn_off_notification']: + app = Twitter("session") + app.load_auth_token(os.getenv('TWITTER_TOKEN')) + target_user = app.get_user_info(username) + + if configs['auto_unfollow']: + log.info(f'successfully unfollowed {username}') if app.unfollow_user(target_user) else log.warning(f'unable to unfollow {username}') + else: + log.info(f'successfully turned off notification for {username}') if app.disable_user_notification(target_user) else log.warning(f'unable to turn off notifications for {username}') else: await itn.followup.send(f'can\'t find notifier {username} in {channel.mention}!', ephemeral=True) diff --git a/configs.yml b/configs.yml index 488e90a..abeeba5 100644 --- a/configs.yml +++ b/configs.yml @@ -3,4 +3,6 @@ activity_name: 'Hennyano' tweets_check_period: 10 tweets_updater_retry_delay: 300 tasks_monitor_check_period: 60 -tasks_monitor_log_period: 14400 \ No newline at end of file +tasks_monitor_log_period: 14400 +auto_turn_off_notification: true +auto_unfollow: true \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index a283a7f..c454f2b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ discord.py==2.3.2 -tweety-ns==0.9.9.5 +tweety-ns==1.0.9.2 python-dotenv==1.0.0 pyyaml==6.0.1 \ No newline at end of file From f4143b94a7f04ed99277513e517a596e20cde262 Mon Sep 17 00:00:00 2001 From: GoldOrange261 <63157008+GoldOrange261@users.noreply.github.com> Date: Tue, 23 Jan 2024 08:28:28 +0800 Subject: [PATCH 06/11] docs: update README --- README.md | 9 +++++++++ README_zh.md | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/README.md b/README.md index 2c75801..6747c6a 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,10 @@ Tweetcord is a discord bot that uses the tweety-ns module to let you receive twe - List all twitter users whose notifications are enabled on the current server +👉 `/sync` + +- Sync the notification of new Twitter account with database. If you change the twitter account used by bot, please use this command + ## 📥Installation @@ -167,6 +171,8 @@ tweets_check_period: 10 # The check frequency for the posts (it is n tweets_updater_retry_delay: 300 # Retry Interval when Tweets Updater encounters exceptions (e.g., rate limitations). tasks_monitor_check_period: 60 # Interval at which to check if each tasks is functioning properly, and if a task has stopped, attempt a restart. tasks_monitor_log_period: 14400 # Interval at which to output the list of currently running tasks to the execution log. +auto_turn_off_notification: true # (v0.4.0 or later) If all notifications for a user are disabled, decide whether to unfollow the user. +auto_unfollow: true # (v0.4.0 or later) If all notifications for a user is disabled, decide whether to disable notification for the user (twitter side). ``` ### 3. Run and invite the bot to your server @@ -186,6 +192,9 @@ In certain operating systems, you may need to use `python3` instead of `python`. - [x] Mention Everyone - [x] Use Slash Commands +> [!NOTE] +> If you want to host the bot on a server, here is a recommended service that is basically free: [fly.io](https://fly.io). + ### 4. Have fun Now you can go back to Discord and use the `/add notifier` command to set up notifications for the Twitter users you wish to receive updates from! diff --git a/README_zh.md b/README_zh.md index 9b8e87d..99c86df 100644 --- a/README_zh.md +++ b/README_zh.md @@ -54,6 +54,10 @@ Tweetcord是一個discord機器人,它使用tweety-ns模組讓你在discord上 - 列出所有當前伺服器開啟通知的Twitter用戶 +👉 `/sync` + +- 將新Twitter帳戶的通知與資料庫同步。如果你更改了bot使用的Twitter帳戶,請使用此指令 + ## 📥安裝 @@ -167,6 +171,8 @@ tweets_check_period: 10 # 檢查推文的頻率(不建議將此值 tweets_updater_retry_delay: 300 # 當Tweets Updater遇到異常(例如速率限制)時的重試間隔。 tasks_monitor_check_period: 60 # 檢查每個任務是否正常運行的間隔,如果某個任務停止了,嘗試重新啟動。 tasks_monitor_log_period: 14400 # 將當前運行中的任務列表輸出到執行日誌的間隔。 +auto_turn_off_notification: true # (v0.4.0或更新版本) 如果某個使用者的所有通知都已停用,決定是否取消追蹤該使用者。 +auto_unfollow: true # (v0.4.0或更新版本) 如果某個使用者的所有通知都已停用,決定是否停用該使用者的通知(Twitter端)。 ``` ### 3. 運行機器人並邀請至你的伺服器 @@ -186,6 +192,9 @@ python bot.py - [x] 提及 @everyone、@here 和所有身分組(Mention Everyone) - [x] 使用應用程式命令(Use Slash Commands) +> [!NOTE] +> 如果想將機器人架到伺服器上,這裡推薦一個基本免費的服務:[fly.io](https://fly.io). + ### 4. 玩得開心 現在你可以回到Discord,並使用 `/add notifier` 指令來設置你想要接收更新的Twitter用戶! From 3ee392d4743919fd27a46faca037e9992e2845d0 Mon Sep 17 00:00:00 2001 From: GoldOrange261 <63157008+GoldOrange261@users.noreply.github.com> Date: Tue, 23 Jan 2024 13:43:50 +0800 Subject: [PATCH 07/11] feat: initial completion of custom message function --- cogs/notification.py | 62 ++++++++++++++++++++++++++++- src/notification/account_tracker.py | 5 ++- 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/cogs/notification.py b/cogs/notification.py index e310d5d..26ccb88 100644 --- a/cogs/notification.py +++ b/cogs/notification.py @@ -16,6 +16,29 @@ load_dotenv() +class CustomMsgModal(discord.ui.Modal, title='custom message'): + def __init__(self, user_id: str, username: str, channel: discord.TextChannel): + super().__init__(timeout=None) + # self.headers = headers + self.user_id = user_id + # self.username = username + self.channel = channel + self.custom_msg = discord.ui.TextInput(label=f'custom message for @{username} in #{channel.name}', placeholder='enter custom message', max_length=200, style=discord.TextStyle.long, required=True) + self.add_item(self.custom_msg) + + async def on_submit(self, itn: discord.Interaction): + await itn.response.defer(ephemeral=True) + + conn = sqlite3.connect(f"{os.getenv('DATA_PATH')}tracked_accounts.db") + conn.row_factory = sqlite3.Row + cursor = conn.cursor() + + cursor.execute('UPDATE notification SET custom_msg = ? WHERE user_id = ? AND channel_id = ?', (self.custom_msg.value, self.user_id, str(self.channel.id))) + conn.commit() + conn.close() + + await itn.followup.send('setting successful', ephemeral=True) + class Notification(Cog_Extension): def __init__(self, bot): super().__init__(bot) @@ -23,7 +46,7 @@ def __init__(self, bot): add_group = app_commands.Group(name='add', description='Add something', default_permissions=ADMINISTRATOR) remove_group = app_commands.Group(name='remove', description='Remove something', default_permissions=ADMINISTRATOR) - + custom_group = app_commands.Group(name='custom', description='Custom something', default_permissions=ADMINISTRATOR) @add_group.command(name='notifier') async def notifier(self, itn : discord.Interaction, username: str, channel: discord.TextChannel, mention: discord.Role = None): @@ -129,6 +152,43 @@ async def notifier(self, itn : discord.Interaction, username: str, channel: disc await itn.followup.send(f'can\'t find notifier {username} in {channel.mention}!', ephemeral=True) conn.close() + + + @custom_group.command(name='message') + async def custom_message(self, itn : discord.Interaction, username: str, channel: discord.TextChannel, default: bool = False): + """Set custom messages for notification. + + Parameters + ----------- + username: str + The username of the twitter user you want to set custom message. + channel: discord.TextChannel + The channel which set to delivers notifications. + default: bool + Whether to use default setting. + """ + + # await itn.response.defer(ephemeral=True) + + conn = sqlite3.connect(f"{os.getenv('DATA_PATH')}tracked_accounts.db") + conn.row_factory = sqlite3.Row + cursor = conn.cursor() + + cursor.execute('SELECT user_id FROM notification, user WHERE username = ? AND channel_id = ? AND user_id = id AND notification.enabled = 1', (username, str(channel.id))) + match_notifier = cursor.fetchone() + if match_notifier != None: + if default: + await itn.response.defer(ephemeral=True) + cursor.execute('UPDATE notification SET custom_msg = ? WHERE user_id = ? AND channel_id = ?', (None, match_notifier['user_id'], str(channel.id))) + conn.commit() + await itn.followup.send('successfully restored to default settings', ephemeral=True) + else: + modal = CustomMsgModal(match_notifier['user_id'], username, channel) + await itn.response.send_modal(modal) + else: + await itn.response.send_message(f'can\'t find notifier {username} in {channel.mention}!', ephemeral=True) + + conn.close() async def setup(bot): diff --git a/src/notification/account_tracker.py b/src/notification/account_tracker.py index a99ae6c..fdeaaa1 100644 --- a/src/notification/account_tracker.py +++ b/src/notification/account_tracker.py @@ -63,7 +63,10 @@ async def notification(self, username): if channel != None: try: mention = f"{channel.guild.get_role(int(data['role_id'])).mention} " if data['role_id'] != '' else '' - await channel.send(f"{mention}**{tweet.author.name}** just {get_action(tweet)} here: \n{tweet.url}", file = discord.File('images/twitter.png', filename='twitter.png'), embeds = gen_embed(tweet)) + author, action, url = tweet.author.name, get_action(tweet), tweet.url + msg = data['custom_msg'] if data['custom_msg'] else "{mention}**{author}** just {action} here: \n{url}" + msg = msg.format(mention=mention, author=author, action=action, url=url) + await channel.send(msg, file = discord.File('images/twitter.png', filename='twitter.png'), embeds = gen_embed(tweet)) except Exception as e: if not isinstance(e, discord.errors.Forbidden): log.error(f'an unexpected error occurred at {channel.mention} while sending notification') From 5d120f79480576af4347102ea3cd2d7353f8e2d5 Mon Sep 17 00:00:00 2001 From: GoldOrange261 <63157008+GoldOrange261@users.noreply.github.com> Date: Wed, 24 Jan 2024 18:19:06 +0800 Subject: [PATCH 08/11] fix: error when label of modal is too long --- cogs/notification.py | 29 ++++++++++++++--------------- src/db_function/init_db.py | 2 +- src/notification/account_tracker.py | 2 +- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/cogs/notification.py b/cogs/notification.py index 26ccb88..675b6c9 100644 --- a/cogs/notification.py +++ b/cogs/notification.py @@ -16,15 +16,16 @@ load_dotenv() -class CustomMsgModal(discord.ui.Modal, title='custom message'): +class CustomizeMsgModal(discord.ui.Modal, title='customize message'): def __init__(self, user_id: str, username: str, channel: discord.TextChannel): super().__init__(timeout=None) - # self.headers = headers self.user_id = user_id - # self.username = username self.channel = channel - self.custom_msg = discord.ui.TextInput(label=f'custom message for @{username} in #{channel.name}', placeholder='enter custom message', max_length=200, style=discord.TextStyle.long, required=True) - self.add_item(self.custom_msg) + label = f'customizing message for @{username} in #{channel.name}' + if len(label) > 45: label = f'customizing message for @{username}' + if len(label) > 45: label = f'customizing message' + self.customized_msg = discord.ui.TextInput(label=label, placeholder='enter customized message', max_length=200, style=discord.TextStyle.long, required=True) + self.add_item(self.customized_msg) async def on_submit(self, itn: discord.Interaction): await itn.response.defer(ephemeral=True) @@ -33,7 +34,7 @@ async def on_submit(self, itn: discord.Interaction): conn.row_factory = sqlite3.Row cursor = conn.cursor() - cursor.execute('UPDATE notification SET custom_msg = ? WHERE user_id = ? AND channel_id = ?', (self.custom_msg.value, self.user_id, str(self.channel.id))) + cursor.execute('UPDATE notification SET customized_msg = ? WHERE user_id = ? AND channel_id = ?', (self.customized_msg.value, self.user_id, str(self.channel.id))) conn.commit() conn.close() @@ -46,7 +47,7 @@ def __init__(self, bot): add_group = app_commands.Group(name='add', description='Add something', default_permissions=ADMINISTRATOR) remove_group = app_commands.Group(name='remove', description='Remove something', default_permissions=ADMINISTRATOR) - custom_group = app_commands.Group(name='custom', description='Custom something', default_permissions=ADMINISTRATOR) + customize_group = app_commands.Group(name='customize', description='Customize something', default_permissions=ADMINISTRATOR) @add_group.command(name='notifier') async def notifier(self, itn : discord.Interaction, username: str, channel: discord.TextChannel, mention: discord.Role = None): @@ -154,22 +155,20 @@ async def notifier(self, itn : discord.Interaction, username: str, channel: disc conn.close() - @custom_group.command(name='message') - async def custom_message(self, itn : discord.Interaction, username: str, channel: discord.TextChannel, default: bool = False): - """Set custom messages for notification. + @customize_group.command(name='message') + async def customize_message(self, itn : discord.Interaction, username: str, channel: discord.TextChannel, default: bool = False): + """Set customized messages for notification. Parameters ----------- username: str - The username of the twitter user you want to set custom message. + The username of the twitter user you want to set customized message. channel: discord.TextChannel The channel which set to delivers notifications. default: bool Whether to use default setting. """ - # await itn.response.defer(ephemeral=True) - conn = sqlite3.connect(f"{os.getenv('DATA_PATH')}tracked_accounts.db") conn.row_factory = sqlite3.Row cursor = conn.cursor() @@ -179,11 +178,11 @@ async def custom_message(self, itn : discord.Interaction, username: str, channel if match_notifier != None: if default: await itn.response.defer(ephemeral=True) - cursor.execute('UPDATE notification SET custom_msg = ? WHERE user_id = ? AND channel_id = ?', (None, match_notifier['user_id'], str(channel.id))) + cursor.execute('UPDATE notification SET customized_msg = ? WHERE user_id = ? AND channel_id = ?', (None, match_notifier['user_id'], str(channel.id))) conn.commit() await itn.followup.send('successfully restored to default settings', ephemeral=True) else: - modal = CustomMsgModal(match_notifier['user_id'], username, channel) + modal = CustomizeMsgModal(match_notifier['user_id'], username, channel) await itn.response.send_modal(modal) else: await itn.response.send_message(f'can\'t find notifier {username} in {channel.mention}!', ephemeral=True) diff --git a/src/db_function/init_db.py b/src/db_function/init_db.py index c70dc6b..c36d2db 100644 --- a/src/db_function/init_db.py +++ b/src/db_function/init_db.py @@ -8,7 +8,7 @@ def init_db(): cursor.executescript(""" CREATE TABLE IF NOT EXISTS user (id TEXT PRIMARY KEY, username TEXT, lastest_tweet TEXT, enabled INTEGER DEFAULT 1); CREATE TABLE IF NOT EXISTS channel (id TEXT PRIMARY KEY, server_id TEXT); - CREATE TABLE IF NOT EXISTS notification (user_id TEXT, channel_id TEXT, role_id TEXT, enabled INTEGER DEFAULT 1, FOREIGN KEY (user_id) REFERENCES user (id), FOREIGN KEY (channel_id) REFERENCES channel (id), PRIMARY KEY(user_id, channel_id)); + CREATE TABLE IF NOT EXISTS notification (user_id TEXT, channel_id TEXT, role_id TEXT, enabled INTEGER DEFAULT 1, customized_msg TEXT DEFAULT NULL, FOREIGN KEY (user_id) REFERENCES user (id), FOREIGN KEY (channel_id) REFERENCES channel (id), PRIMARY KEY(user_id, channel_id)); """) conn.commit() conn.close() \ No newline at end of file diff --git a/src/notification/account_tracker.py b/src/notification/account_tracker.py index fdeaaa1..4d858c8 100644 --- a/src/notification/account_tracker.py +++ b/src/notification/account_tracker.py @@ -64,7 +64,7 @@ async def notification(self, username): try: mention = f"{channel.guild.get_role(int(data['role_id'])).mention} " if data['role_id'] != '' else '' author, action, url = tweet.author.name, get_action(tweet), tweet.url - msg = data['custom_msg'] if data['custom_msg'] else "{mention}**{author}** just {action} here: \n{url}" + msg = data['customized_msg'] if data['customized_msg'] else "{mention}**{author}** just {action} here: \n{url}" msg = msg.format(mention=mention, author=author, action=action, url=url) await channel.send(msg, file = discord.File('images/twitter.png', filename='twitter.png'), embeds = gen_embed(tweet)) except Exception as e: From 43e6db32e67d61fb030fef7033977c0d430494ee Mon Sep 17 00:00:00 2001 From: GoldOrange261 <63157008+GoldOrange261@users.noreply.github.com> Date: Wed, 24 Jan 2024 20:05:40 +0800 Subject: [PATCH 09/11] docs: update README --- README.md | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++- README_zh.md | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 182 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6747c6a..44a3bf1 100644 --- a/README.md +++ b/README.md @@ -54,10 +54,25 @@ Tweetcord is a discord bot that uses the tweety-ns module to let you receive twe - List all twitter users whose notifications are enabled on the current server -👉 `/sync` +👉 `/sync` _(new in 0.4)_ - Sync the notification of new Twitter account with database. If you change the twitter account used by bot, please use this command +👉 `/customize message` `username` `channel` | `default` _(new in 0.4)_ + +| parameters | types | descriptions | +| --------- | ----- | ----------- | +| `username` | str | The username of the twitter user you want to set customized message | +| `channel` | discord.TextChannel | The channel which set to delivers notifications | +| `default` | bool | Whether to use default setting _(default is false)_ | + +> [!TIP] +> There are currently 4 special variables that can be used in customized messages, which will be explained below. +> `{action}` : poster's action, include `tweeted`, `retweeted` and `quoted` +> `{author}` : poster's display name +> `{mention}` : the role to mention when sending to discord +> `{url}` : the link of the tweet + ## 📥Installation @@ -74,6 +89,51 @@ In certain operating systems, you may need to use the command `pip3` instead of **📢This tutorial is suitable for version 0.3.2 or later. (Recommended: 0.3.5 or later)** +
+ 📌click here to upgrade from 0.3.5 to 0.4.0 + +> [!IMPORTANT] +> Before everything starts you must upgrade the version of `tweety-ns` to `1.0.9.2` first and download or pull the new code from this repo. + +Create a python file in the `cogs` folder and name it `upgrade.py`. Paste the following code and run the bot. Use the slash command `/upgrade version` to upgrade. This cog can be removed after the upgrade is completed. + +```py +import discord +from discord import app_commands +from core.classes import Cog_Extension +import sqlite3 +import os + +from src.permission import ADMINISTRATOR + +class Upgrade(Cog_Extension): + + upgrade_group = app_commands.Group(name='upgrade', description='Upgrade something', default_permissions=ADMINISTRATOR) + + @upgrade_group.command(name='version', description='upgrade to Tweetcord 0.4.0') + async def upgrade(self, itn: discord.Interaction): + + await itn.response.defer(ephemeral=True) + + conn = sqlite3.connect(f"{os.getenv('DATA_PATH')}tracked_accounts.db") + cursor = conn.cursor() + + try: + cursor.executescript(""" + ALTER TABLE user ADD enabled INTEGER DEFAULT 1; + ALTER TABLE notification ADD cusomized_msg TEXT DEFAULT NULL; + """) + await itn.followup.send('successfully upgrade to 0.4.0, you can remove this cog and reboot the bot.') + except: + await itn.followup.send('upgrading to 0.4.0 failed, please try again or contact the author.') + + +async def setup(bot): + await bot.add_cog(Upgrade(bot)) +``` + +
+
📌click here to upgrade from 0.3.4 to 0.3.5 @@ -195,6 +255,36 @@ In certain operating systems, you may need to use `python3` instead of `python`. > [!NOTE] > If you want to host the bot on a server, here is a recommended service that is basically free: [fly.io](https://fly.io). +
+ ⚙️some configuration files you may need if you use fly.io + +- dockerfile + +```dockerfile +FROM python:3.10.9 +WORKDIR /bot +COPY requirements.txt /bot/ +RUN pip install -r requirements.txt +COPY . /bot/ +CMD python bot.py +``` + +- fly.toml + +```toml +app = "YOUR_APP_NAME" +primary_region = "YOUR_APP_REGION" + +[env] + DATA_PATH = "/data/" + +[mounts] + source = "YOUR_APP_VOLUME_NAME" + destination = "/data" +``` + +
+ ### 4. Have fun Now you can go back to Discord and use the `/add notifier` command to set up notifications for the Twitter users you wish to receive updates from! diff --git a/README_zh.md b/README_zh.md index 99c86df..807269b 100644 --- a/README_zh.md +++ b/README_zh.md @@ -54,10 +54,25 @@ Tweetcord是一個discord機器人,它使用tweety-ns模組讓你在discord上 - 列出所有當前伺服器開啟通知的Twitter用戶 -👉 `/sync` +👉 `/sync` _(0.4版本的新功能)_ - 將新Twitter帳戶的通知與資料庫同步。如果你更改了bot使用的Twitter帳戶,請使用此指令 +👉 `/customize message` `username` `channel` | `default` _(0.4版本的新功能)_ + +| 參數 | 類型 | 描述 | +| --------- | ----- | ----------- | +| `username` | str | 你想要設定自定義通知訊息的Twitter用戶的用戶名 | +| `channel` | discord.TextChannel | 機器人發送通知的頻道 | +| `default` | bool | 是否要還原至預設的設定 _(預設是false)_ | + +> [!TIP] +> 目前自定義通知訊息有4種特別的變數可以使用,將在下面說明 +> `{action}` : 發文者的動作, 包括 `tweeted`, `retweeted` 和 `quoted` _(暫不支持中文)_ +> `{author}` : 發文者的顯示名稱 +> `{mention}` : 發送到discord時提及的身份組 +> `{url}` : 推文的連結 +
## 📥安裝 @@ -74,6 +89,51 @@ pip install -r requirements.txt **📢本教學適用於0.3.2或更高版本。(建議:0.3.5或更高版本)** +
+ 📌0.3.5升級到0.4.0請點這裡 + +> [!IMPORTANT] +> 在一切開始之前請先更新 `tweety-ns` 至 `1.0.9.2` 版本並且從這個repo下載或拉取新的程式碼。 + +在 `cogs` 資料夾創建一個python檔案並命名為 `upgrade.py`,貼上下面的程式碼並運行機器人,使用斜線指令 `/upgrade version` 進行升級。升級結束後可以移除這個cog。 + +```py +import discord +from discord import app_commands +from core.classes import Cog_Extension +import sqlite3 +import os + +from src.permission import ADMINISTRATOR + +class Upgrade(Cog_Extension): + + upgrade_group = app_commands.Group(name='upgrade', description='Upgrade something', default_permissions=ADMINISTRATOR) + + @upgrade_group.command(name='version', description='upgrade to Tweetcord 0.4.0') + async def upgrade(self, itn: discord.Interaction): + + await itn.response.defer(ephemeral=True) + + conn = sqlite3.connect(f"{os.getenv('DATA_PATH')}tracked_accounts.db") + cursor = conn.cursor() + + try: + cursor.executescript(""" + ALTER TABLE user ADD enabled INTEGER DEFAULT 1; + ALTER TABLE notification ADD cusomized_msg TEXT DEFAULT NULL; + """) + await itn.followup.send('successfully upgrade to 0.4.0, you can remove this cog and reboot the bot.') + except: + await itn.followup.send('upgrading to 0.4.0 failed, please try again or contact the author.') + + +async def setup(bot): + await bot.add_cog(Upgrade(bot)) +``` + +
+
📌0.3.4升級到0.3.5請點這裡 @@ -195,6 +255,36 @@ python bot.py > [!NOTE] > 如果想將機器人架到伺服器上,這裡推薦一個基本免費的服務:[fly.io](https://fly.io). +
+ ⚙️如果你使用fly.io的話你可能會需要的一些配置檔案 + +- dockerfile + +```dockerfile +FROM python:3.10.9 +WORKDIR /bot +COPY requirements.txt /bot/ +RUN pip install -r requirements.txt +COPY . /bot/ +CMD python bot.py +``` + +- fly.toml + +```toml +app = "你的APP名稱" +primary_region = "你的APP地區" + +[env] + DATA_PATH = "/data/" + +[mounts] + source = "你的APP的VOLUME名稱" + destination = "/data" +``` + +
+ ### 4. 玩得開心 現在你可以回到Discord,並使用 `/add notifier` 指令來設置你想要接收更新的Twitter用戶! From 938af23e4f5a1686364cf58e29a880805a5bd5f6 Mon Sep 17 00:00:00 2001 From: GoldOrange261 <63157008+GoldOrange261@users.noreply.github.com> Date: Wed, 24 Jan 2024 20:19:00 +0800 Subject: [PATCH 10/11] docs: fix markdown syntax that cannot be displayed correctly --- README.md | 15 +++++++-------- README_zh.md | 15 +++++++-------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 44a3bf1..f041272 100644 --- a/README.md +++ b/README.md @@ -66,12 +66,12 @@ Tweetcord is a discord bot that uses the tweety-ns module to let you receive twe | `channel` | discord.TextChannel | The channel which set to delivers notifications | | `default` | bool | Whether to use default setting _(default is false)_ | -> [!TIP] -> There are currently 4 special variables that can be used in customized messages, which will be explained below. -> `{action}` : poster's action, include `tweeted`, `retweeted` and `quoted` -> `{author}` : poster's display name -> `{mention}` : the role to mention when sending to discord -> `{url}` : the link of the tweet +There are currently 4 special variables that can be used in customized messages, which will be explained below. + +- `{action}` : poster's action, include `tweeted`, `retweeted` and `quoted` +- `{author}` : poster's display name +- `{mention}` : the role to mention when sending to discord +- `{url}` : the link of the tweet
@@ -92,8 +92,7 @@ In certain operating systems, you may need to use the command `pip3` instead of
📌click here to upgrade from 0.3.5 to 0.4.0 -> [!IMPORTANT] -> Before everything starts you must upgrade the version of `tweety-ns` to `1.0.9.2` first and download or pull the new code from this repo. +⚠️Before everything starts you must upgrade the version of `tweety-ns` to `1.0.9.2` first and download or pull the new code from this repo. Create a python file in the `cogs` folder and name it `upgrade.py`. Paste the following code and run the bot. Use the slash command `/upgrade version` to upgrade. This cog can be removed after the upgrade is completed. diff --git a/README_zh.md b/README_zh.md index 807269b..0f2edca 100644 --- a/README_zh.md +++ b/README_zh.md @@ -66,12 +66,12 @@ Tweetcord是一個discord機器人,它使用tweety-ns模組讓你在discord上 | `channel` | discord.TextChannel | 機器人發送通知的頻道 | | `default` | bool | 是否要還原至預設的設定 _(預設是false)_ | -> [!TIP] -> 目前自定義通知訊息有4種特別的變數可以使用,將在下面說明 -> `{action}` : 發文者的動作, 包括 `tweeted`, `retweeted` 和 `quoted` _(暫不支持中文)_ -> `{author}` : 發文者的顯示名稱 -> `{mention}` : 發送到discord時提及的身份組 -> `{url}` : 推文的連結 +目前自定義通知訊息有4種特別的變數可以使用,將在下面說明: + +- `{action}` : 發文者的動作, 包括 `tweeted`, `retweeted` 和 `quoted` _(暫不支持中文)_ +- `{author}` : 發文者的顯示名稱 +- `{mention}` : 發送到discord時提及的身份組 +- `{url}` : 推文的連結
@@ -92,8 +92,7 @@ pip install -r requirements.txt
📌0.3.5升級到0.4.0請點這裡 -> [!IMPORTANT] -> 在一切開始之前請先更新 `tweety-ns` 至 `1.0.9.2` 版本並且從這個repo下載或拉取新的程式碼。 +⚠️在一切開始之前請先更新 `tweety-ns` 至 `1.0.9.2` 版本並且從這個repo下載或拉取新的程式碼。 在 `cogs` 資料夾創建一個python檔案並命名為 `upgrade.py`,貼上下面的程式碼並運行機器人,使用斜線指令 `/upgrade version` 進行升級。升級結束後可以移除這個cog。 From 7e8ac5241f2ef087ac657e21b6676cbe820a8b3b Mon Sep 17 00:00:00 2001 From: GoldOrange261 <63157008+GoldOrange261@users.noreply.github.com> Date: Wed, 24 Jan 2024 20:48:14 +0800 Subject: [PATCH 11/11] fix: fixed some bugs and moved CustomizeMsgModal to a separate file --- README.md | 2 +- README_zh.md | 2 +- cogs/notification.py | 27 ++------------------------- src/discord_ui/modal.py | 27 +++++++++++++++++++++++++++ 4 files changed, 31 insertions(+), 27 deletions(-) create mode 100644 src/discord_ui/modal.py diff --git a/README.md b/README.md index f041272..77087d2 100644 --- a/README.md +++ b/README.md @@ -120,7 +120,7 @@ class Upgrade(Cog_Extension): try: cursor.executescript(""" ALTER TABLE user ADD enabled INTEGER DEFAULT 1; - ALTER TABLE notification ADD cusomized_msg TEXT DEFAULT NULL; + ALTER TABLE notification ADD customized_msg TEXT DEFAULT NULL; """) await itn.followup.send('successfully upgrade to 0.4.0, you can remove this cog and reboot the bot.') except: diff --git a/README_zh.md b/README_zh.md index 0f2edca..fe9a390 100644 --- a/README_zh.md +++ b/README_zh.md @@ -120,7 +120,7 @@ class Upgrade(Cog_Extension): try: cursor.executescript(""" ALTER TABLE user ADD enabled INTEGER DEFAULT 1; - ALTER TABLE notification ADD cusomized_msg TEXT DEFAULT NULL; + ALTER TABLE notification ADD customized_msg TEXT DEFAULT NULL; """) await itn.followup.send('successfully upgrade to 0.4.0, you can remove this cog and reboot the bot.') except: diff --git a/cogs/notification.py b/cogs/notification.py index 675b6c9..1de10d4 100644 --- a/cogs/notification.py +++ b/cogs/notification.py @@ -9,6 +9,7 @@ from src.log import setup_logger from src.notification.account_tracker import AccountTracker +from src.discord_ui.modal import CustomizeMsgModal from src.permission import ADMINISTRATOR from configs.load_configs import configs @@ -16,30 +17,6 @@ load_dotenv() -class CustomizeMsgModal(discord.ui.Modal, title='customize message'): - def __init__(self, user_id: str, username: str, channel: discord.TextChannel): - super().__init__(timeout=None) - self.user_id = user_id - self.channel = channel - label = f'customizing message for @{username} in #{channel.name}' - if len(label) > 45: label = f'customizing message for @{username}' - if len(label) > 45: label = f'customizing message' - self.customized_msg = discord.ui.TextInput(label=label, placeholder='enter customized message', max_length=200, style=discord.TextStyle.long, required=True) - self.add_item(self.customized_msg) - - async def on_submit(self, itn: discord.Interaction): - await itn.response.defer(ephemeral=True) - - conn = sqlite3.connect(f"{os.getenv('DATA_PATH')}tracked_accounts.db") - conn.row_factory = sqlite3.Row - cursor = conn.cursor() - - cursor.execute('UPDATE notification SET customized_msg = ? WHERE user_id = ? AND channel_id = ?', (self.customized_msg.value, self.user_id, str(self.channel.id))) - conn.commit() - conn.close() - - await itn.followup.send('setting successful', ephemeral=True) - class Notification(Cog_Extension): def __init__(self, bot): super().__init__(bot) @@ -84,7 +61,7 @@ async def notifier(self, itn : discord.Interaction, username: str, channel: disc return if match_user == None: - cursor.execute('INSERT INTO user VALUES (?, ?, ?)', (str(new_user.id), username, datetime.utcnow().replace(tzinfo=timezone.utc).strftime('%Y-%m-%d %H:%M:%S%z'))) + cursor.execute('INSERT INTO user (id, username, lastest_tweet) VALUES (?, ?, ?)', (str(new_user.id), username, datetime.utcnow().replace(tzinfo=timezone.utc).strftime('%Y-%m-%d %H:%M:%S%z'))) cursor.execute('INSERT OR IGNORE INTO channel VALUES (?, ?)', (str(channel.id), server_id)) cursor.execute('INSERT INTO notification (user_id, channel_id, role_id) VALUES (?, ?, ?)', (str(new_user.id), str(channel.id), roleID)) else: diff --git a/src/discord_ui/modal.py b/src/discord_ui/modal.py new file mode 100644 index 0000000..e7bc299 --- /dev/null +++ b/src/discord_ui/modal.py @@ -0,0 +1,27 @@ +import discord +import os +import sqlite3 + +class CustomizeMsgModal(discord.ui.Modal, title='customize message'): + def __init__(self, user_id: str, username: str, channel: discord.TextChannel): + super().__init__(timeout=None) + self.user_id = user_id + self.channel = channel + label = f'customizing message for @{username} in #{channel.name}' + if len(label) > 45: label = f'customizing message for @{username}' + if len(label) > 45: label = f'customizing message' + self.customized_msg = discord.ui.TextInput(label=label, placeholder='enter customized message', max_length=200, style=discord.TextStyle.long, required=True) + self.add_item(self.customized_msg) + + async def on_submit(self, itn: discord.Interaction): + await itn.response.defer(ephemeral=True) + + conn = sqlite3.connect(f"{os.getenv('DATA_PATH')}tracked_accounts.db") + conn.row_factory = sqlite3.Row + cursor = conn.cursor() + + cursor.execute('UPDATE notification SET customized_msg = ? WHERE user_id = ? AND channel_id = ?', (self.customized_msg.value, self.user_id, str(self.channel.id))) + conn.commit() + conn.close() + + await itn.followup.send('setting successful', ephemeral=True) \ No newline at end of file