質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Discord

Discordは、ゲーマー向けのボイスチャットアプリです。チャット・通話がブラウザ上で利用可能で、個人専用サーバーも開設できます。通話中でも音楽を流したり、PC画面を共有できるなど多機能な点が特徴です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

591閲覧

on_user_updateが機能しない

nyana

総合スコア1

Discord

Discordは、ゲーマー向けのボイスチャットアプリです。チャット・通話がブラウザ上で利用可能で、個人専用サーバーも開設できます。通話中でも音楽を流したり、PC画面を共有できるなど多機能な点が特徴です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/06/20 05:30

前提・実現したいこと

on_user_updateが機能しません

発生している問題・エラーメッセージ

in on_user_update cursor.execute(f"SELECT log_channel FROM ServerSetting WHERE guild_id = {after.guild}") AttributeError: 'User' object has no attribute 'guild'

該当のソースコード

py

1@commands.Cog.listener() 2async def on_user_update(self, before, after): 3 await self.bot.wait_until_ready() 4 db = sqlite3.connect('main.sqlite') 5 cursor = db.cursor() 6 cursor.execute(f"SELECT log_channel FROM ServerSetting WHERE guild_id = {after.guild}") 7 result = cursor.fetchone() 8 if result is None: 9 return 10 else: 11 ch = self.bot.get_channel(id=int(result[0])) 12 13 if before.name != after.name: 14 e = discord.Embed(title="サーバーログ-ユーザーアップデート",description=f"ニックネームを変更しました\n変更メンバー:{str(after)}") 15 16 e.add_field(name="変更後",value=after.name) 17 await ch.send(embed=e) 18 elif before.status != after.status: 19 e = discord.Embed(title="サーバーログーユーザーアップデート",value=f"{after}のステータスが変わりました") 20 await ch.send(embed=e)

試したこと

{after.guild}のとこを色々変えてみました

補足情報(FW/ツールのバージョンなど)

discord.py→3.8.6

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

coolwind0202

2021/06/20 05:39

after.guild を使って参照したかったのは具体的にどのようなサーバーですか?
nyana

2021/06/20 05:43

一つミスしてて{after.guild}じゃなくて{after.id}でした。 それでだとエラー内容が表示されず、ユーザーネームを変更しても通知が来なかったです
coolwind0202

2021/06/20 05:53

after のユーザーが参加するすべてのサーバーに対してサーバーログを記録することを目的と推測して回答しました。 after.guild は discord.Guild で、データベース上の guild_id と一致することはありえません。 また、 after.id は int ですが、ユーザーのIDなので、 guild_id と一致することはありえません。 オブジェクトの型や、それが示す内容を把握されることをおすすめします。 Discord.pyのAPIリファレンスを参照しましょう。
nyana

2021/06/20 07:49

なるほど!ありがとうございます。
guest

回答1

0

ベストアンサー

エラー文のとおりですね。

まず、 on_user_updatebefore afterdicsord.Member インスタンスではなく discord.User インスタンスです。

UserとMemberの違いを把握しましょう。

User は、単にユーザーを指すデータです。
Discord全体に対して一意なユーザーを示します。

Member は、サーバーメンバーとしてのデータです。
Role (役職)などのサーバーメンバーのみが持ちうるデータを持っています。
また、そのユーザーがどのサーバーのメンバーであるかを示す guild 属性を持っています。

したがって、 User に guild という属性はありません。
あるのは、 guilds 属性のみです。


py

1@commands.Cog.listener() 2async def on_user_update(self, before, after): 3 await self.bot.wait_until_ready() 4 db = sqlite3.connect('main.sqlite') 5 cursor = db.cursor() 6 7 for guild in after.guilds: 8 cursor.execute(f"SELECT log_channel FROM ServerSetting WHERE guild_id = ?", (guild.id, )) 9 result = cursor.fetchone() 10 if result is None: 11 continue 12 else: 13 ch = self.bot.get_channel(id=int(result[0])) 14 15 if before.name != after.name: 16 e = discord.Embed(title="サーバーログ-ユーザーアップデート",description=f"ニックネームを変更しました\n変更メンバー:{str(after)}") 17 18 e.add_field(name="変更後",value=after.name) 19 await ch.send(embed=e) 20 elif before.status != after.status: 21 e = discord.Embed(title="サーバーログーユーザーアップデート",value=f"{after}のステータスが変わりました") 22 await ch.send(embed=e)

after のユーザーが参加しているすべてのサーバーに対して、サーバーログを記録していきます。
(不自然な部分を訂正しているだけなので、動作は保証できません)


あと、cursor.executeに渡す文字列を f-string で組み立てるのは避けたほうが良いと思います。
変数を埋め込むためのセキュアな機能が存在するので、自前で実装する必要はありません。

投稿2021/06/20 05:49

coolwind0202

総合スコア708

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問