forked from yymin1022/KakaoEmoticon2TelegramSticker
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
189 lines (147 loc) · 6.06 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
import logging
class ColorFormatter(logging.Formatter):
# ANSI codes are a bit weird to decipher if you're unfamiliar with them, so here's a refresher
# It starts off with a format like \x1b[XXXm where XXX is a semicolon separated list of commands
# The important ones here relate to colour.
# 30-37 are black, red, green, yellow, blue, magenta, cyan and white in that order
# 40-47 are the same except for the background
# 90-97 are the same but "bright" foreground
# 100-107 are the same as the bright ones but for the background.
# 1 means bold, 2 means dim, 0 means reset, and 4 means underline.
LEVEL_COLOURS = [
(logging.DEBUG, "\x1b[40;1m"),
(logging.INFO, "\x1b[34;1m"),
(logging.WARNING, "\x1b[33;1m"),
(logging.ERROR, "\x1b[31m"),
(logging.CRITICAL, "\x1b[41m"),
]
FORMATS = {
level: logging.Formatter(
f"\x1b[30;1m%(asctime)s\x1b[0m {colour}%(levelname)-8s\x1b[0m \x1b[35m%(name)s\x1b[0m %(message)s",
"%Y-%m-%d %H:%M:%S",
)
for level, colour in LEVEL_COLOURS
}
def format(self, record):
formatter = self.FORMATS.get(record.levelno)
if formatter is None:
formatter = self.FORMATS[logging.DEBUG]
# Override the traceback to always print in red
if record.exc_info:
text = formatter.formatException(record.exc_info)
record.exc_text = f"\x1b[31m{text}\x1b[0m"
output = formatter.format(record)
# Remove the cache layer
record.exc_text = None
return output
handler = logging.StreamHandler()
handler.setFormatter(ColorFormatter())
logging.basicConfig(handlers=[handler], level=logging.INFO)
from telegram import Update, InputSticker
from telegram.ext import ContextTypes, ApplicationBuilder, CommandHandler
from telegram.constants import StickerFormat
from PIL import Image
from aiohttp import ClientSession
import datetime
import os
from io import BytesIO
from re import compile
from typing import TypedDict, List, Sequence
class EmoticonMeta(TypedDict):
title: str
thumbnailUrls: List[str]
EMOTICON_ID_REGEX = compile("https://e.kakao.com/t/.+")
async def createEmoticon(update: Update, context: ContextTypes.DEFAULT_TYPE):
assert update.effective_chat
assert context.args
emoticonURL = context.args[0]
if not EMOTICON_ID_REGEX.match(emoticonURL):
await context.bot.send_message(
chat_id=update.effective_chat.id, text="유효한 이모티콘 URL이 아닙니다."
)
return
await context.bot.send_message(
chat_id=update.effective_chat.id, text="이모티콘 정보를 불러오는 중입니다."
)
emoticonURL = emoticonURL.replace(
"https://e.kakao.com/t/", "https://e.kakao.com/api/v1/items/t/"
)
async with ClientSession() as session:
async with session.get(emoticonURL) as resp:
emoticonMeta = EmoticonMeta((await resp.json())["result"])
await context.bot.send_message(
chat_id=update.effective_chat.id,
text=f"{emoticonMeta['title']} 이모티콘을 다운로드 합니다.",
)
stickers: Sequence[InputSticker] = []
for emoticon in emoticonMeta["thumbnailUrls"]:
async with session.get(emoticon) as img:
img_bytes = BytesIO()
Image.open(BytesIO(await img.read())).resize((512, 512)).save(
img_bytes, "png"
)
stickers.append(InputSticker(img_bytes.getvalue(), ["😀"]))
curTime = str(datetime.datetime.now(datetime.UTC).timestamp()).replace(".", "")
stickerName = f"t{curTime}_by_{context.bot.name[1:]}"
await context.bot.send_message(
chat_id=update.effective_chat.id,
text=f"총 {len(emoticonMeta['thumbnailUrls'])}개의 이모티콘을 텔레그램 서버로 업로드합니다.",
)
assert update.effective_user
doing_message = await context.bot.send_message(
chat_id=update.effective_chat.id,
text=f"업로드 중... (0/{len(emoticonMeta['thumbnailUrls'])})",
)
await context.bot.create_new_sticker_set(
user_id=update.effective_user.id,
name=stickerName,
title=emoticonMeta["title"],
sticker_format=StickerFormat.STATIC,
stickers=[stickers[0]],
)
await doing_message.edit_text(
text=f"업로드 중... (1/{len(emoticonMeta['thumbnailUrls'])})"
)
for index, sticker in enumerate(stickers[1:], 2):
await context.bot.add_sticker_to_set(
user_id=update.effective_user.id, name=stickerName, sticker=sticker
)
await doing_message.edit_text(
text=f"업로드 중... ({index}/{len(emoticonMeta['thumbnailUrls'])})"
)
await doing_message.edit_text(text=f"{emoticonMeta['title']} 스티커 생성이 완료되었습니다!")
await context.bot.send_message(
chat_id=update.effective_chat.id,
text="https://t.me/addstickers/%s" % (stickerName),
)
async def helpMenu(update: Update, context: ContextTypes.DEFAULT_TYPE):
assert update.effective_chat
await context.bot.send_message(chat_id=update.effective_chat.id, text="Help Menu")
async def startBot(update: Update, context: ContextTypes.DEFAULT_TYPE):
assert update.effective_chat
await context.bot.send_message(
chat_id=update.effective_chat.id, text="Bot Started!"
)
if __name__ == "__main__":
application = (
ApplicationBuilder()
.token(os.getenv("TELEGRAM_TOKEN", "NO_TOKEN"))
.http_version("2")
.read_timeout(600)
.get_updates_read_timeout(600)
.write_timeout(600)
.get_updates_write_timeout(600)
.pool_timeout(600)
.get_updates_pool_timeout(600)
.connect_timeout(600)
.get_updates_connect_timeout(600)
.build()
)
application.add_handlers(
[
CommandHandler("start", startBot),
CommandHandler("help", helpMenu),
CommandHandler("create", createEmoticon),
]
)
application.run_polling()