Twitchをやってると何かとサポートしてくれるボットが欲しくなったので作ることしました。これはまず作ってみたChatGPTで雑談するボットです。にゃんこ仕様ですにゃん
TwitchIO
ライブラリを使うと簡単にボットを作れるので、まずはシンプルなものを説明します。そのうちChatGPT入も解説します。
2024-12-03 翻訳AIのコードを公開しました。開発中のボットAIの会話も見れます。
今回説明することは4つ
- ACCESS_TOKEN の取得
- プログラミング
- チャンネルへのJoin
- コメントが書き込まれたらコメントを返す
- コマンドが入力されたらコメントを返す
ACCESS_TOKEN の取得
ボットをチャンネルにログインさせるには ACCESS_TOKEN が必要になります。ボット用のアカウントでログインした状態で以下のURLにアクセスし、画像の手順をふみます。
Twitch Chat OAuth Password Generator
表示されたものをコピっておいてください。
プログラミング
まずは TwitchIO
をインストールです。
$ pip install twitchio
全体のコードを見てから1つ1つ追って見ていきます。
from twitchio import Channel, Message
from twitchio.ext import commands
WTITCH_ACCESS_TOKEN = "XXXXXXXXXXXXXXXXXXXXXXXX"
LOGIN_CHANNEL = "akiraaak"
COMMAND_PREFIX = "!"
class Bot(commands.Bot):
def __init__(self):
super().__init__(
token=WTITCH_ACCESS_TOKEN,
prefix=COMMAND_PREFIX,
initial_channels=[LOGIN_CHANNEL]
)
async def event_channel_joined(self, channel: Channel):
print(f"ログインしました。チャンネル名: {channel.name}")
for chatter in channel.chatters:
print(f'ユーザーID: {chatter.id}')
print(f'ユーザー名: {chatter.name}')
print(f'表示名: {chatter.display_name}')
await channel.send(f"{chatter.name}があらわれた!")
async def event_ready(self):
print("全てのチャンネルにログインしました。")
print(f'ユーザーID: {self.user_id}')
print(f'ユーザー名: {self.nick}')
# コメントが書き込まれると呼び出される
async def event_message(self, message: Message):
# ボットの発言は無視する
if message.echo:
return
# メッセージがコマンドであれば、ここで処理を終了
if message.content.startswith(COMMAND_PREFIX):
await self.handle_commands(message)
return
print(f'ユーザーID: {message.author.name}')
print(f'ユーザー名: {message.author.display_name}')
# オウム返し
await message.channel.send(f"{message.content}")
# !hello こんにちは
@commands.command(name='hello')
async def cmd_hello(self, ctx: commands.Context):
await ctx.send(f'Hello! {ctx.author.name}! {ctx.message.content}')
def main():
bot = Bot()
bot.run()
if __name__ == "__main__":
main()
さきほど取得した ACCESS_TOKEN
は WTITCH_ACCESS_TOKEN
に設定してください。
Twitch のボットは TwitchIO
を使うととても簡単に作れます。commands.Bot
を継承した Bot
を定義して、そのインスタンスを作成し run()
するだけです。
class Bot(commands.Bot):
def __init__(self):
super().__init__(
token=WTITCH_ACCESS_TOKEN,
prefix=COMMAND_PREFIX,
initial_channels=[LOGIN_CHANNEL]
)
bot = Bot()
bot.run()
Bot
クラスのコンストラクタには、ボットのACCESS_TOKEN、Joinするチャンネル、コマンドラインのPrefixを指定します。
ACCESS_TOKEN は最初に取得したものですね。
チャンネルは配信のチャンネルで、僕のチャンネルだと https://www.twitch.tv/akiraaak なので akiraaak
になります。
コマンドラインのPrefixですが、のちのち出てきますが、ボットにはコマンドを設定できます。ビートセイバーのボットだと、!bsr
!bomb
!link
などがあるんですが、この先頭の !
になります。?
なんかも一般的です。 まずは!
を指定しておけばいいとおもいます。
チャンネルへのJoin
run()
を実行してチャンネルに入るとコールバック関数が呼ばれます。今回は2つ定義しています。
コンストラクタのチャンネルの指定は配列でした。 initial_channels=[LOGIN_CHANNEL]
コールバック関数はそれぞれのチャンネルに入った後に呼ばれるものと、全てに入ったあとに呼ばれるものと2つあります。
それぞれのチャンネルで呼ばれるコールバック関数
async def event_channel_joined(self, channel: Channel):
print(f"ログインしました。チャンネル名: {channel.name}")
for chatter in channel.chatters:
print(f'ユーザーID: {chatter.id}')
print(f'ユーザー名: {chatter.name}')
print(f'表示名: {chatter.display_name}')
await channel.send(f"{chatter.name}があらわれた!")
全てのチャンネルに入ったあとに呼ばれるコールバック関数
async def event_ready(self):
print("全てのチャンネルにログインしました。")
print(f'ユーザーID: {self.user_id}')
print(f'ユーザー名: {self.nick}')
ただし、event_channel_joined()のユーザー情報は正しいものが入ってきてないように思います。id,display_name が None だったり、全てのユーザーが返ってこなかったり。挙動がよくわかりません。
await channel.send()
を使うことでコメントを書くことができます。
await channel.send(f"{chatter.name}があらわれた!")
コメントが書き込まれたらコメントを返す
少し複雑なコードになっているので、先に下のコマンドの説明に目を通した方がいいかもしれません。
# コメントが書き込まれると呼び出される
async def event_message(self, message: Message):
# 1.ボットの発言は無視する
if message.echo:
return
# 2.メッセージがコマンドであれば、ここで処理を終了
if message.content.startswith(COMMAND_PREFIX):
await self.handle_commands(message)
return
print(f'ユーザーID: {message.author.name}')
print(f'ユーザー名: {message.author.display_name}')
# オウム返し
await message.channel.send(f"{message.content}")
コメントが書き込まれたらコメントを返すだけなのですが、最初に大切な儀式が2つあります。
- ボット自身が書き込んだコメントの場合は抜ける
- コメントがコマンドだったらコマンド処理を実行して抜ける
この2つにだけ気をつければ、あとは message.author
にユーザー情報が入ってくるのと message.content
にコメントが入ってくるのでそれを処理すれば大丈夫です。
await message.channel.send()
でそのままオウム返しをしてます。
コマンドが入力されたらコメントを返す
ボットにはコマンドという機能があります。コメントがprefix
(今回は!)から始まった特定の単語のときに関数が呼ばれます。
このコマンドは !hello
というコマンドになります。!hello こんにちは
とコマンドの後ろに文字を続けて使うこともできます。ビートセイバーだと !bsr 2142b
なんて使い方がされてますね。
# !hello こんにちは
@commands.command(name='hello')
async def cmd_hello(self, ctx: commands.Context):
await ctx.send(f'Hello! {ctx.author.name}! {ctx.message.content}')
!hello こんにちはこんにちわ
と入力されたので Hello! akiraaak !hello こんにちはこんにちわ
と返しています。
おわりに
TwitchIO
を使うととても簡単にTwitchボットが作れると思います。どうぞお試しくださいまし。
Twitchボット開発風景の配信もやってるのでよかったらみにきね
あキら