Discord是一款專為社群設計的免費網路即時通話軟體與數位發行平台
使用者之間可以在聊天頻道通過資訊、圖片、影片和音訊進行互動。
- Wikipedia
~~online compiler
Coder の本当の友達だ
主要著重在"版本管理"此重點上
也是備份的方法之一
隨時隨地都可以編錯 淪為被專案壓榨的coder
機器人列表
指令使用範例
賦予天職!
解除搖光限制 (Intents)!
邀請到伺服器中!
discord.py
from discord.ext import commands
import discord
intents = discord.Intents.all()
bot = commands.Bot(command_prefix=<your prefix>: str, intents=intents)
# your program goes here
bot.run(<your token>: str)
@bot.event
@bot.event
async def on_ready():
print("~~~~~~>> Bot is online <<~~~~~~")
@bot.event
async def on_member_join(member):
await member.send('歡迎加入伺服器!')
@bot.event
async def on_member_remove(member):
welcome_channel = bot.get_channel(<channel id>: int)
await channel.send(f'我們懷念 {member.name}')
@bot.event
async def on_message(message):
if message.content == 'apple':
await message.channel.send('I like apple! ^~^')
if message.author == bot.user:
return
if message.author.bot:
return
@bot.event
async def on_message(message):
if message.author == bot.user:
return
if message.author.bot:
await message.channel.send('Yes')
else:
await message.channel.send('No')
@bot.command()
bot.latency # return in seconds
やってみなさい!
@bot.command()
async def ping(ctx):
await ctx.send(f':stopwatch: {round(bot.latency * 1000)} (ms)')
@bot.command()
async def for_admin(ctx):
if ctx.author.bot:
return
is_admin = bool(False)
for role in ctx.author.roles:
if role.name == 'admin':
is_admin = True
break
if is_admin == False:
await ctx.send('You are not admin!')
return
await ctx.send('You are admin!')
@bot.command()
@commands.has_any_role('admin1', 'admin2')
async def for_admin(ctx):
await ctx.send('You are admin!')
\(\leftarrow\) main.py (repl.it)
\(\leftarrow\) !!
TOKEN=<your token>
import os
# ...
bot.run(os.environ.get("TOKEN"))
# Token
.env
A cog is an organization of DC Bot functions
from discord.ext import commands
import discord
class Event(commands.Cog):
def __init__(self, bot):
self.bot = bot
@commands.Cog.listener() # bot.event
async def on_ready(self):
print('---> I\'m online! <---')
@commands.command() # bot.command()
async def ping(self, ctx):
await ctx.send(f':stopwatch: {round(self.bot.latency * 1000)} (ms)')
def setup(bot):
bot.add_cog(Event(bot))
from discord.ext import commands
import discord
import os
intents = discord.Intents.all()
bot = commands.Bot(command_prefix='+', intents=intents)
for filename in os.listdir('./cogs'):
if filename.endswith('.py'):
bot.load_extension(f'cogs.{filename[:-3]}')
bot.run(os.environ.get("TOKEN"))
# ...
for filename in os.listdir('./cogs'):
if filename.endswith('.py'):
bot.load_extension(f'cogs.{filename[:-3]}')
# ...
class Event(commands.Cog):
def __init__(self, bot):
self.bot = bot
# ...
def setup(bot):
bot.add_cog(Event(bot))
(1)
(2)
(3)
main.py
event.py
簡化步驟:繼承
import discord
from discord.ext import commands
class Cog_Extension(commands.Cog):
def __init__(self, bot):
self.bot = bot
from discord.ext import commands
from core.classes import Cog_Extension
import discord
class Event(Cog_Extension):
@commands.Cog.listener() # bot.event
async def on_ready(self):
print('---> I\'m online! <---')
@commands.command() # bot.command()
async def ping(self, ctx):
await ctx.send(f':stopwatch: {round(self.bot.latency * 1000)} (ms)')
def setup(bot):
bot.add_cog(Event(bot))
@bot.command()
async def load(ctx, msg):
try:
bot.load_extension(f'cogs.{msg}')
await ctx.send(f':white_check_mark: Extension {msg} loaded.')
except:
await ctx.send(f':exclamation: There are no extension called {msg}!')
@bot.command()
async def unload(ctx, msg):
try:
bot.unload_extension(f'cogs.{msg}')
await ctx.send(f':white_check_mark: Extension {msg} unloaded.')
except:
await ctx.send(f':exclamation: There are no extension called {msg}!')
@bot.command()
async def reload(ctx, msg):
if msg != '*':
try:
bot.reload_extension(f'cogs.{msg}')
await ctx.send(f':white_check_mark: Extension {msg} reloaded.')
except:
await ctx.send(f':exclamation: There are no extension called {msg}!')
else:
for filename in os.listdir('./cogs'):
if filename.endswith('.py'):
bot.reload_extension(f'cogs.{filename[:-3]}')
將區塊再分更小吧
@commands.group()
async def <group name>(self, ctx):
pass
@<group name>.command()
async def <cmd name>(self, ctx):
# ...
# ...
from flask import Flask
from threading import Thread
app = Flask('')
@app.route('/')
def show_panel():
return 'Bot is alive!'
def run():
app.run(host="0.0.0.0", port=8080)
def keep_alive():
server = Thread(target=run)
server.start()
from discord.ext import commands
import discord
import keep_alive
intents = discord.Intents.all()
bot = commands.Bot(command_prefix=<your prefix>: str, intents=intents)
# your program goes here
keep_alive.keep_alive()
bot.run(<your token>: str)
# ...
def keep_alive():
server = Thread(target=run)
server.start()
# ...
keep_alive.keep_alive()
bot.run(<your token>: str)
將結構化資料 (structured data) 呈現為 JavaScript 物件的標準格式,常用於網站上的資料呈現、傳輸
~我們感謝維基百科/(_ _)\~
舒適主義又出現了!
糖炒的呦
{
"join": {
"opening": {
"morning": [
"早上好呀 ><",
"不知道你有沒有睡飽呢?"
],
"noon": [
"中午好呀 ><",
"等等要不要去睡個午覺呢?"
],
"after_noon": [
"下午好呀 ><",
"不知道你剛剛有沒有睡了個飽滿的午覺?"
],
"evening": [
"晚上好呀 ><",
"等一下要早早睡覺呦!"
],
"night": [
"姆姆...我好愛睡呦&^&~",
"你也不要熬夜!",
"(或是你已經起床惹 ><"
],
"main": [
"歡迎來到SQCS的群組!",
"我是負責管理伺服器的機器人 - **Q ちゃん!**",
"讓我為你說明伺服器中現在的相關設定",
"現在伺服器中有著名為**天命系統**的東西運行著",
"詳細的原因可以看一下這篇 hackmd",
"https://hackmd.io/@Quantum-GrAyee/rkalZ7wiP"
]
},
"hackmd_read": [
"姆姆, 你應該看完了吧?那我要繼續說惹",
"總而言之,我將負責建立你的個人檔案 \\\\^~^",
"但因最近伺服器中可能會有學測生",
"或是有點忙碌的參與者",
"可能沒有空來參加相關的活動",
"不知道你是不是其中的一員呢...?(y/n)"
],
"df_1": [
"辛苦你了!",
"先在這邊預祝你進行得順利 \\\\^~^",
"那我就先將你的 `deep freeze` 狀態改為**是**囉!"
],
"df_0": [
"那太好了,在閒暇時段要多多參與伺服器中的活動呦!\\\\^~^",
"那我就先將你的 `deep freeze` 狀態設為**否**囉!"
],
"invalid_syntax": [
"姆姆!",
"不要傳給我我看不懂的符號啦 (氣><",
"我就先認定你很閒囉!"
],
"time_out": [
"齁!都不回我話 (氣><",
"那我就先認定你很閒囉!",
"記得來參加群組內的活動呦!"
],
"contact_method": [
"> 日後如果之後要進行修改的話",
"> 可以跟我的創造者",
"> -- **phantom0174(小灰灰總召)**說一聲!"
],
"fl_create_finish": [
"久等了,我幫你創建好了屬於你的資料了!",
"我好像也沒有甚麼要對你說的了",
"那就祝你在SQCS的世界中玩得開心,掰掰 ><",
"> 日後可使用指令 `mv!query all me`",
"> 查詢個人的搖光資料"
]
},
"kick": {
"kick_single": [
"姆姆...",
"看來你好像因為下列原因被管理者踢出伺服器惹 qwq"
],
"kick_all": [
"齁呦",
"你的違反指數爆表惹啦><"
],
"re_join": [
"醬子不優呦 ><",
"> Q ちゃん 偷偷給你一個加回來的機會><",
"> https://discord.gg/KjWMRewQB2"
]
},
"lecture": {
"start": {
"pt_1": [
":loudspeaker: @everyone",
"大家大家><"
],
"pt_2": [
":bulb: 等等搶答時記得用 `&` 作為訊息的前綴",
"我才看得到你說惹什麼咚咚!"
]
},
"end": {
"main": [
":loudspeaker: @everyone",
"感謝今天有來參加講座的人 :partying_face:",
"你們都很棒><"
],
"reactions": [
"但人數太少惹qwq,之後繼續加油!",
"人數好像有多一點點了,再多多呼朋引伴吧!",
"耶耶!人數終於超過上限的一半惹!繼續加油!",
"差一點點,就一點點就要到上限惹!加油加油!",
"耶耶\\\\^~^\nQ ちゃん 超級超級~ 滿意今天的參與度呦 ><"
]
}
},
"main": {
"mibu": {
"pt_1": "> 肯定是做了什麼好事"
}
},
"quiz": {
"repeat_answer": [
"哼,還想偷偷傳新的答案呀",
"都被我發現惹 >^<"
],
"get_answer": [
"耶耶!我已經吃到你好吃的答案惹><",
"記得下星期要再餵我呦!"
],
"invalid_syntax": {
"pt_1": [
"齁呦我看不懂你傳惹什麼啦><",
"我來教教你\\\\^~^"
],
"pt_2": [
"> 不然你的答案會被其他人看光光呦><",
"都了解了嗎?",
"那再傳一次吧!><"
]
},
"answer_tut": [
"> 如果正確答案依題序為 `abe`",
"> 請在懸賞區中輸入 `||abe||`"
],
"start": {
"pt_1": [
":loudspeaker: @everyone",
"有個新的懸賞(餵食)活動開始了呦!",
"為了避免你傳的訊息被其他人看光光 *~*",
"請記得使用 `||<答案>||` 的格式傳送訊息 \\\\^~^!"
],
"pt_2": [
"如果我不小心吃掉惹不該吃的訊息",
"請立刻 @總召 或是直接私訊他們!",
"大家都要把我餵飽呦 >< 祝好運!",
"> 還在忙的總召可能等一下才會把問題傳上來 ><",
"> 不過或許是他們有點怠惰也說不定(?"
]
},
"end": {
"main": {
"pt_1": [
":loudspeaker: @everyone",
"懸賞(餵食)活動結束惹!"
],
"pt_2": [
"不知道大家都有沒有答對呢?><",
"對了對了"
]
},
"reactions": [
"太少了啦,連填牙縫都不夠惹qwq\n大家再加油吧!",
"零食好吃!不過我想要吃多一點 ><",
"食物好像有多一點點了!但好像只有宵夜分量呢 >^<",
"耶耶!開胃菜正在朝著我走來!",
"我看到副菜正在不遠處!",
"終於吃到主餐了 ><",
"耶耶 這片生菜感覺很好玩的樣子(x",
"終於有甜點可以吃惹!Yummy yummy >^<",
"大家終於把我餵飽了,感謝感謝 ><"
]
}
}
}
@commands.Cog.listener()
async def on_member_join(self, member):
if member.bot:
return
time_status = await func.get_time_title(func.now_time_info('hour'))
msg = '\n'.join(rsp["join"]["opening"][time_status]) + '\n'
msg += '\n'.join(rsp["join"]["opening"]["main"])
await member.send(msg)
await asyncio.sleep(60)
msg = '\n'.join(rsp["join"]["hackmd_read"])
await member.send(msg)
def check(message):
return message.channel == member.dm_channel and message.author == member
try:
deep_freeze_status = (await self.bot.wait_for('message', check=check, timeout=60.0)).content
if deep_freeze_status == 'y':
msg = '\n'.join(rsp["join"]["df_1"])
deep_freeze_status = 1
elif deep_freeze_status == 'n':
msg = '\n'.join(rsp["join"]["df_0"])
deep_freeze_status = 0
else:
msg = '\n'.join(rsp["join"]["invalid_syntax"])
deep_freeze_status = 0
except asyncio.TimeoutError:
msg = '\n'.join(rsp["join"]["time_out"])
deep_freeze_status = 0
# another \n for last un-inserted \n
msg += '\n' + '\n'.join(rsp["join"]["contact_method"])
await member.send(msg)
# create personal fluctlight data
start_time = time.time()
fluctlight_client = MongoClient(link)["LightCube"]
fluctlight_cursor = fluctlight_client["light-cube-info"]
member_fluctlight = {"_id": member.id,
"score": 0,
"du": 0,
"oc_auth": 0,
"sc_auth": 0,
"lvl_ind": 0,
"mdu": 0,
"odu": 0,
"odu_time": time.time(),
"contrib": 0,
"week_active": 0,
"deep_freeze": deep_freeze_status}
try:
fluctlight_cursor.insert_one(member_fluctlight)
except:
fluctlight_cursor.delete_one({"_id": member.id})
fluctlight_cursor.insert_one(member_fluctlight)
end_time = time.time()
msg = '\n'.join(rsp["join"]["fl_create_finish"])
await member.send(msg)
await member.send(f'順帶一提,我用了 {round(end_time - start_time, 2)} (sec) 建立你的檔案><!')
{
"Cmd_channel": "743677861000380527",
"pic": [
"https://i.imgur.com/uomJXkr.jpg",
"https://i.imgur.com/1XwWvXC.png",
"https://i.imgur.com/26skltl.png"
],
"department_id": [
"743512536695177327",
"745600386030764084",
"743512574938710078",
"743670948384866357",
"760747391484952577",
"760746923208212530"
]
}
非關聯式資料庫(NoSQL(Not Only SQL))
混用關聯式資料庫和NoSQL資料庫來達成最佳的儲存效果,通常是透過簡單的API來新增、更新或刪除資料庫中的內容
data = {"_id": 5, "name": "星期五晚上固定講座", "status": 0, "population": 12}
據說對_id進行賦值是毒瘤寫法
import pymongo
from pymongo import MongoClient
link = <your link>
client = MongoClient(link)[<database name>: str]
cursor = client[<collection name>: str]
cursor 就是對單一 collection 進行操作的物件
# 尋找單一物件
# 回傳單一物件
cursor.find_one({<條件>}, {<要回傳的column>: 1})
# 尋找符合條件的所有物件
# 回傳一個包含所有符合條件物件的cursor物件,可使用list()將其打回2維陣列
cursor.find({<條件>}, {<要回傳的column>: 1})
# 對單一物件的值進行修改
cursor.update_one({<條件>}, {<改變方式>: {<改變的物件>: <改變值>}})
# 對符合條件的複數物件修改數值
cursor.update_many({<條件>}, {<改變方式>: {<改變的物件>: <改變值>}})
# 對於 one 和 many 都通用的
cursor.update({<條件>}, {<改變方式>: {<改變的物件>: <改變值>}})
# 刪除符合條件的單一物件
cursor.delete_one({<條件>})
# 刪除符合條件的所有物件
cursor.delete_many({<條件>})