diff --git a/.gitignore b/.gitignore
index 87a784c..914943d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -131,3 +131,4 @@ dmypy.json
.idea/
bot.session*
config.ini
+data/
diff --git a/defs/announcement.py b/defs/announcement.py
new file mode 100644
index 0000000..1ebb794
--- /dev/null
+++ b/defs/announcement.py
@@ -0,0 +1,75 @@
+from datetime import datetime
+from typing import Optional
+
+from mipac import Route
+
+from glover import topic_group_id, admin, notice_topic_id
+from init import bot
+from misskey_init import misskey_bot
+
+announcement_template = """Misskey Announcement
+
+{0}
+
+{1}"""
+
+
+class Announcement:
+ def __init__(self, data):
+ self.id = data["id"]
+ self.title = data["title"]
+ self.text = data["text"]
+ self.is_read = data["is_read"]
+ self.image_url = data["image_url"]
+ self._created_at = data["created_at"]
+ self._updated_at = data["updated_at"]
+
+ @property
+ def created_at(self) -> datetime:
+ return datetime.strptime(self._created_at, "%Y-%m-%dT%H:%M:%S.%fZ")
+
+ @property
+ def updated_at(self) -> Optional[datetime]:
+ return datetime.strptime(self._updated_at, "%Y-%m-%dT%H:%M:%S.%fZ") if self._updated_at else None
+
+ async def send_notice(self):
+ if not self.image_url:
+ await bot.send_message(
+ topic_group_id or admin,
+ announcement_template.format(
+ self.title,
+ self.text[:1000],
+ ),
+ reply_to_message_id=notice_topic_id,
+ )
+ else:
+ await bot.send_photo(
+ topic_group_id or admin,
+ self.image_url,
+ caption=announcement_template.format(
+ self.title,
+ self.text[:1000],
+ ),
+ reply_to_message_id=notice_topic_id,
+ )
+
+ async def mark_as_read(self):
+ data = {
+ "announcementId": self.id,
+ }
+ await misskey_bot.core.http.request(
+ Route("POST", "/api/i/read-announcement"),
+ json=data, auth=True, lower=True,
+ )
+
+
+async def get_unread_announcements():
+ data = {
+ "limit": 10,
+ "withUnreads": True,
+ }
+ req = await misskey_bot.core.http.request(
+ Route("POST", "/api/announcements"),
+ json=data, auth=True, lower=True,
+ )
+ return [Announcement(i) for i in req]
diff --git a/defs/notice.py b/defs/notice.py
index 87cdff9..3e4e802 100644
--- a/defs/notice.py
+++ b/defs/notice.py
@@ -1,4 +1,4 @@
-from mipac.models.notification import NotificationFollow, NotificationFollowRequest
+from mipac.models.notification import NotificationFollow, NotificationFollowRequest, NotificationAchievement
from mipac.models.lite.user import LiteUser
from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton
@@ -8,6 +8,49 @@ from init import bot
user_followed_template = """有人关注了你! {1}"""
follow_request_template = """有人申请关注你! {1}"""
follow_request_accept_template = """有人同意了你的关注申请! {1}"""
+achievement_template = """你获得了新成就! {0}:{1} {2}"""
+achievement_map = {
+ 'notes1': ('初来乍到', '第一次发帖', '祝您在Misskey玩的愉快~'),
+ 'notes10': ('一些帖子', '发布了10篇帖子', ''),
+ 'notes100': ('很多帖子', '发布了100篇帖子', ''),
+ 'notes500': ('满是帖子', '发布了500篇帖子', ''),
+ 'notes1000': ('积帖成山', '发布了1,000篇帖子', ''),
+ 'notes5000': ('帖如泉涌', '发布了5,000篇帖子', ''),
+ 'notes10000': ('超级帖', '发布了10,000篇帖子', ''),
+ 'notes20000': ('还想要更多帖子', '发布了20,000篇帖子', ''),
+ 'notes30000': ('帖子帖子帖子', '发布了30,000篇帖子', ''),
+ 'notes40000': ('帖子工厂', '发布了40,000篇帖子', ''),
+ 'notes50000': ('帖子星球', '发布了50,000篇帖子', ''),
+ 'notes60000': ('帖子类星体', '发布了60,000篇帖子', ''),
+ 'notes70000': ('帖子黑洞', '发布了70,000篇帖子', ''),
+ 'notes80000': ('帖子星系', '发布了80,000篇帖子', ''),
+ 'notes90000': ('帖子起源', '发布了90,000篇帖子', ''),
+ 'notes100000': ('ALL YOUR NOTE ARE BELONG TO US', '发布了100,000篇帖子', '真的有那么多可以写的东西吗?'),
+ 'login3': ('初学者 I', '连续登录3天', ''),
+ 'login7': ('初学者 II', '连续登录7天', ''),
+ 'login15': ('初学者 III', '连续登录15天', ''),
+ 'login30': ('', '连续登录30天', ''),
+ 'login60': ('', '连续登录60天', ''),
+ 'login1000': ('', '', '感谢您使用Misskey!'),
+ 'noteFavorited1': ('观星者', '', ''),
+ 'profileFilled': ('整装待发', '设置了个人资料', ''),
+ 'markedAsCat': ('我是猫', '将账户设定为一只猫', ''),
+ 'following10': ('关注,跟随', '关注数超过10', ''),
+ 'following50': ('我的朋友很多', '关注数超过50', ''),
+ 'following300': ('', '关注数超过300', ''),
+ 'followers100': ('胜友如云', '被关注数超过100', ''),
+ 'collectAchievements30': ('', '获得超过30个成就', ''),
+ 'viewAchievements3min': ('', '盯着成就看三分钟', ''),
+ 'iLoveMisskey': ('I Love Misskey', '发布"I ❤ #Misskey"帖子', '感谢您使用 Misskey ! by 开发团队'),
+ 'noteDeletedWithin1min': ('', '发帖后一分钟内就将其删除', ''),
+ 'postedAtLateNight': ('夜行者', '深夜发布帖子', ''),
+ 'outputHelloWorldOnScratchpad': ('Hello, world!', '', ''),
+ 'passedSinceAccountCreated1': ('', '账户创建时间超过1年', ''),
+ 'passedSinceAccountCreated2': ('', '账户创建时间超过2年', ''),
+ 'passedSinceAccountCreated3': ('', '账户创建时间超过3年', ''),
+ 'loggedInOnBirthday': ('生日快乐', '在生日当天登录', ''),
+ 'loggedInOnNewYearsDay': ('恭贺新禧', '在元旦登入', '')
+}
def gen_user_link_button(user: LiteUser):
@@ -67,3 +110,16 @@ async def send_follow_request_accept(notice: NotificationFollowRequest):
reply_to_message_id=notice_topic_id,
reply_markup=InlineKeyboardMarkup([gen_user_link_button(notice.user)]),
)
+
+
+async def send_achievement_earned(notice: NotificationAchievement):
+ name, desc, note = achievement_map.get(notice.achievement, ("", "", ""))
+ await bot.send_message(
+ topic_group_id or admin,
+ achievement_template.format(
+ name,
+ desc,
+ f"- {note}" if note else "",
+ ),
+ reply_to_message_id=notice_topic_id,
+ )
diff --git a/misskey_init.py b/misskey_init.py
index f9b6c64..0a157cb 100644
--- a/misskey_init.py
+++ b/misskey_init.py
@@ -1,10 +1,10 @@
from mipa.ext import commands
from mipa.router import Router
-from mipac import Note, NotificationFollow, NotificationFollowRequest, ChatMessage
+from mipac import Note, NotificationFollow, NotificationFollowRequest, ChatMessage, NotificationAchievement
from defs.chat import send_chat_message
from defs.misskey import send_update
-from defs.notice import send_user_followed, send_follow_request, send_follow_request_accept
+from defs.notice import send_user_followed, send_follow_request, send_follow_request_accept, send_achievement_earned
from glover import admin, topic_group_id, timeline_topic_id, notice_topic_id
@@ -36,5 +36,8 @@ class MisskeyBot(commands.Bot):
async def on_chat_unread_message(self, message: ChatMessage):
await message.api.read()
+ async def on_achievement_earned(self, notice: NotificationAchievement):
+ await send_achievement_earned(notice)
+
misskey_bot = MisskeyBot()
diff --git a/modules/announcement.py b/modules/announcement.py
new file mode 100644
index 0000000..0c4ea5f
--- /dev/null
+++ b/modules/announcement.py
@@ -0,0 +1,12 @@
+from scheduler import scheduler
+from defs.announcement import get_unread_announcements
+
+
+@scheduler.scheduled_job("interval", minutes=15, id="check_announcement")
+async def announcement():
+ data = await get_unread_announcements()
+ for an in data:
+ try:
+ await an.send_notice()
+ finally:
+ await an.mark_as_read()