def notif(self, review,comment = False): review = review['data'] change = p4.Change() change.user = review['author'] change.changelist = str(review['changes'][len(review['changes'])-1]) change.review = str(review['id']) swarm_urls = p4.make_swarm_urls(change, self.perforce) message = discord.Message() message.user = change.user if review['state'] != 'approved': message.color = 0x7CFC00 elif review['state'] != 'archived': message.color = 0xFFA500 else: message.color = 0xc8702a if not comment: message.header = "Review #"+str(review['id'])+" Request from " + \ change.user+" Status: "+review['stateLabel'] else: message.header = "Review #"+str(review['id'])+" Request from " + \ change.user+" New Comment!" message.content = self.mentions(review['description'])+' Author:'+self.mentions("@"+review['author']) message.footer = swarm_urls.review message.url = swarm_urls.review self.discord.send(message) return
async def wait_for_dms(self, event, check, timeout=30): try: data = ( await self.cogs["Sharding"].handler( action="wait_for_dms", args={"event": event, "check": check, "timeout": timeout}, expected_count=1, _timeout=timeout, ) )[0] except IndexError: raise asyncio.TimeoutError() if event == "message": channel_id = int(data["channel_id"]) channel = ( self.get_channel(channel_id) or self.get_user(int(data["author"]["id"])).dm_channel ) return discord.Message(state=self._connection, channel=channel, data=data) elif event == "reaction_add": emoji = discord.PartialEmoji( name=data["emoji"]["name"], id=int(id_) if (id_ := data["emoji"]["id"]) else id_, animated=data["emoji"]["animated"], ) message = discord.utils.get( self._connection._messages, id=int(data["message_id"]) ) reaction = discord.Reaction( message=message, emoji=emoji, data={"me": False} ) return reaction, await self.get_user_global(int(data["user_id"]))
async def _send_message(self, content="", embed=None, file=None, delete_after=None, reference=None): channel = await self._get_channel() if embed and (not isinstance(embed, dict)): embed = embed.to_dict() if file: try: data = await self._state.http.send_files(channel.id, files=[file], content=content, embed=embed, reference=reference) finally: file.close() else: data = await self._state.http.send_message(channel.id, content=content, embed=embed, reference=reference) msg = dpy.Message(state=self._state, channel=channel, data=data) if delete_after: await msg.delete(delay=delete_after) return msg
def run_coro(self, event): channel = self.bot.get_channel(event.channel) try: server = channel.server prefix = self.bot.settings.get_prefixes(server)[0] except AttributeError: log.debug("Channel no longer found, not running scheduled event.") return data = {} data['timestamp'] = time.strftime("%Y-%m-%dT%H:%M:%S%z", time.gmtime()) data['id'] = randint(10**(17), (10**18) - 1) data['content'] = prefix + event.command data['channel'] = self.bot.get_channel(event.channel) data['author'] = {'id': event.author} data['nonce'] = randint(-2**32, (2**32) - 1) data['channel_id'] = event.channel data['reactions'] = [] fake_message = discord.Message(**data) # coro = self.bot.process_commands(fake_message) log.info("Running '{}' in {}".format(event.name, event.server)) # self.bot.loop.create_task(coro try: self.bot.dispatch('message', fake_message) except HTTPException as x: print(x)
async def send_persistent_notes(): notes = await self.bot.api.find_notes(self.recipient) ids = {} class State: def store_user(self, user): return user for note in notes: author = note["author"] class Author: name = author["name"] id = author["id"] discriminator = author["discriminator"] avatar_url = author["avatar_url"] data = { "id": round(time.time() * 1000 - discord.utils.DISCORD_EPOCH) << 22, "attachments": {}, "embeds": {}, "edited_timestamp": None, "type": None, "pinned": None, "mention_everyone": None, "tts": None, "content": note["message"], "author": Author(), } message = discord.Message(state=State(), channel=None, data=data) ids[note["_id"]] = str( (await self.note(message, persistent=True, thread_creation=True)).id ) await self.bot.api.update_note_ids(ids)
async def run_in_context(self, ctx, *, com: str): """ attempts to run a command as owner. """ try: self._sanity_checks(com) except SanityError: output = "Sanity error encountered: \n" + \ "User ID/Name: {0.id}: {0.name}\n" + \ "message attempted\n\n: {1.content}" + \ "".format(ctx.message.author, ctx.message) log.debug(output) owner = await self.bot.get_user_info(settings.owner) await self.bot.send_message(owner, output) return else: output = "INFO: User ID/Name: {0.id}: {0.name}\n" + \ "issued the following as owner: \n" + \ "{}".format(com) log.debug(output) data = \ {'timestamp': time.strftime("%Y-%m-%dT%H:%M:%S%z", time.gmtime()), 'content': ctx.prefix + com, 'channel': ctx.message.channel, 'channel_id': ctx.message.channel.id, 'author': {'id': settings.owner}, 'nonce': randint(-2**32, (2**32) - 1), 'id': randint(10**(17), (10**18) - 1), 'reactions': [] } message = discord.Message(**data) self.bot.dispatch('message', message)
async def run_in_context(self, ctx, *, com: str): if self.context is None and self.impersonate is None: return await \ self.bot.say("Hint: `{0.prefix}setcontext`" "and/or `{0.prefix}setauthor`".format(ctx)) chan = ctx.message.channel if self.context is None \ else self.context try: server = chan.server prefix = self.bot.settings.get_prefixes(server)[0] except AttributeError: return await self.bot.say("Are you sure I can see that channel?") author_id = ctx.message.author.id if self.impersonate is None \ else self.impersonate data = \ {'timestamp': time.strftime("%Y-%m-%dT%H:%M:%S%z", time.gmtime()), 'content': prefix + com, 'channel': chan, 'channel_id': chan.id, 'author': {'id': author_id}, 'nonce': randint(-2**32, (2**32) - 1), 'id': randint(10**(17), (10**18) - 1), 'reactions': [] } message = discord.Message(**data) self.bot.dispatch('message', message)
def _parse_message_create(self, data): if (not hasattr(self, "_is_ready")) or data["type"] or ( not data.get("guild_id")) or data.get("webhook_id"): return elif data["author"].get('bot') and (not data["author"]["id"] == str( self.user.id)): return channel, _ = self._get_guild_channel(data) if not data["author"].get("bot"): self.dispatch('message', dpy.Message(channel=channel, data=data, state=self)) else: self._messages.append( dpy.Message(channel=channel, data=data, state=self)) del channel, data
class InteractionButton(InteractionResponse): __slots__ = ("custom_id", "component_type", "message") def __init__(self, *, cog, data: dict): super().__init__(cog=cog, data=data) interaction_data = self.interaction_data self.custom_id = interaction_data["custom_id"] self.component_type = interaction_data["component_type"] message = data["message"] if reference := message.get("message_reference"): if "channel_id" not in reference: reference["channel_id"] = self.channel_id # used if dislash is loaded since Message.reference creation # pops channel_id from the message_reference dict try: self.message = discord.Message(channel=self.channel, data=message, state=self._state) except Exception as exc: log.exception("An error occured while creating the message for %r", self, exc_info=exc) self.message = None
async def on_raw_message_edit(self, payload): """Ensure that when a message containing emotes is edited, the corresponding emote reply is, too.""" # data = https://discordapp.com/developers/docs/resources/channel#message-object if 'content' not in payload.data: return reply = await self.db.get_reply_message(payload.message_id) type, reply_message_id = reply channel = self.bot.get_channel(payload.channel_id) message = discord.Message(state=self.bot._connection, channel=channel, data=payload.data) if reply_message_id is None: if getattr(channel, 'last_message_id', None) == payload.message_id: # allow an edited message to invoke the auto response # only if this is the last message in the channel await self.on_message(message) return await self.bot.set_locale(message) handlers = { MessageReplyType.auto: self._handle_extracted_edit, MessageReplyType.quote: self._handle_quoted_edit } await handlers[type](message, reply_message_id)
async def on_raw_message_edit(self, payload): """Ensure that when a message containing emotes is edited, the corresponding emote reply is, too.""" # data = https://discordapp.com/developers/docs/resources/channel#message-object if 'content' not in payload.data: return reply = await self.db.get_reply_message(payload.message_id) type, reply_message_id = reply if reply_message_id is None: return channel_id = int(payload.data['channel_id']) message = discord.Message(state=self.bot._connection, channel=self.bot.get_channel(channel_id), data=payload.data) await self.bot.set_locale(message) handlers = { MessageReplyType.auto: self._handle_extracted_edit, MessageReplyType.quote: self._handle_quoted_edit } await handlers[type](message, reply_message_id)
async def on_raw_message_edit(self, payload): """Ensure that when a message containing emotes is edited, the corresponding emote reply is, too.""" # data = https://discordapp.com/developers/docs/resources/channel#message-object if 'content' not in payload.data: return reply = await self.bot.pool.fetchrow( """ SELECT type, reply_message FROM replies WHERE invoking_message = $1 """, payload.message_id) if not reply: return type, reply_message_id = reply channel_id = int(payload.data['channel_id']) message = discord.Message(state=self.bot._connection, channel=self.bot.get_channel(channel_id), data=payload.data) handlers = { 'AUTO': self._handle_extracted_edit, 'QUOTE': self._handle_quoted_edit } await handlers[type](message, reply_message_id)
async def test_prompt_for_input_attachment(rfr_cog, utils_cog): config: dpytest.RunnerConfig = dpytest.get_config() author: discord.Member = config.members[0] guild: discord.Guild = config.guilds[0] channel: discord.TextChannel = guild.text_channels[0] await dpytest.message(koalabot.COMMAND_PREFIX + "store_ctx") ctx: commands.Context = utils_cog.get_last_ctx() await dpytest.empty_queue() attach: discord.Attachment = discord.Attachment( state=dpytest.back.get_state(), data=dpytest.back.facts.make_attachment_dict( "test.jpg", 15112122, "https://media.discordapp.net/attachments/some_number/random_number/test.jpg", "https://media.discordapp.net/attachments/some_number/random_number/test.jpg", height=1000, width=1000)) message_dict = dpytest.back.facts.make_message_dict(channel, author, attachments=[attach]) message: discord.Message = discord.Message(state=dpytest.back.get_state(), channel=channel, data=message_dict) with mock.patch('discord.client.Client.wait_for', mock.AsyncMock(return_value=message)): result = await rfr_cog.prompt_for_input(ctx, "test") assert dpytest.verify().message().content( "Please enter test so I can progress further. I'll wait 60 seconds, don't worry." ) assert isinstance(result, discord.Attachment) assert result.url == attach.url
def test_get_user(): bot = src.PereBlaiseBot.PereBlaiseBot() message = discord.Message(reactions=[]) message.author.id = "987654321" assert bot.get_user(["toto", "<@!123456789>"], message, 1) == "123456789" assert bot.get_user(["toto", "<@!123456789>"], message, 0) == "987654321" assert bot.get_user(["toto", "<@!123456789>"], message, 2) == "987654321"
async def process_raw_message_delete(self, msg_id, channel_id): if msg_id in self.delete_list: self.delete_list.remove(msg_id) return channel = self.get_channel(int(channel_id)) data = {'content': "What fun is there in making sense?", 'type': 0, 'edited_timestamp': None, 'id': msg_id, 'channel_id': channel_id, 'timestamp': '2017-01-15T02:59:58+00:00'} msg = discord.Message(channel=channel, state=self._connection, data=data) # Procreate a fake message object await self.on_message_delete(msg)
def __init__(self, *, cog, data: dict): super().__init__(cog=cog, data=data) interaction_data = self.interaction_data self.custom_id = interaction_data["custom_id"] self.component_type = interaction_data["component_type"] self.message = discord.Message(channel=self.channel, data=data["message"], state=self._state)
def read_chat(path): meta = json.load(open(path + '.meta.json')) if 'channel' not in meta: raise ValueError("Not a channel log") channel_id = meta['channel']['id'] channel_name = meta['channel']['name'] print(f"Channel {channel_name} (id {channel_id})") # Create a crippled state # TODO implement our own state = discord.state.ConnectionState.__new__( discord.state.ConnectionState) state.max_messages = 1000 state.http = None state.clear() # Mock a guild # TODO restore from run data guild = discord.Guild.__new__(discord.Guild) guild.id = 0 guild._members = {} guild._roles = {} guild.name = '' channel = discord.TextChannel(state=state, guild=guild, data={ 'id': channel_id, 'type': 0, 'name': channel_name, 'parent_id': 0, 'position': 0 }) if os.path.exists(path + '.jsonl.gz'): file = gzip.open(path + '.jsonl.gz') else: file = open(path + '.jsonl') for line in file: line = json.loads(line) if line['type'] != 'http': continue if line['request']['url'].endswith(f'/channels/{channel_id}/messages'): for message_data in reversed(line['response']['data']): message = discord.Message(state=state, channel=channel, data=message_data) if message.type == discord.MessageType.default: print( f"[{message.created_at}] <{message.author}> {message.content}" ) else: print(f"[{message.created_at}] {message.system_content}")
async def test_process_instagram(mocker: pytest_mock.MockerFixture): mkdir_notexists(["dump_json_instagram"]) client = mocker.patch("instagram_to_discord.util2.types.DiscordMemoClient") state, data, channel = make_settings() message = discord.Message(state=state, data=data, channel=channel) content = "https://www.instagram.com/p/CW4YfYIvgHD/ 5" text = "" with open("tests/data/dump_instagram_CW4YfYIvgHD.json") as f: text = f.read() mock_image_url = "dummy_url" # 一応作ってるけど mock です。 embed = discord.Embed( title="佐々木希", description=sophisticate_string("#VOCE 2022年1月号 \nオフショット💄💕"), url="https://www.instagram.com/p/CW4YfYIvgHD", color=discord.Color.red(), ) embed.set_image(url=mock_image_url) embed.set_author( name="佐々木希", url=instagram_make_author_page("nozomisasaki_official"), icon_url= "https://scontent-sjc3-1.cdninstagram.com/v/t51.2885-19/s150x150/24175048_1706810412710767_1281070886199230464_n.jpg?_nc_ht=scontent-sjc3-1.cdninstagram.com&_nc_cat=1&_nc_ohc=OzlpjF-F5_MAX_zYlhx&edm=AABBvjUBAAAA&ccb=7-4&oh=6954b174179012577379e144883a0456&oe=61B40F0F&_nc_sid=83d603" ) # 何もしないが、あとで embed で呼ばれたか確認する。 mocker.patch.object(discord.abc.Messageable, "send") # 何もしないようにする (dynamo put) mocker.patch.object( instagram_to_discord.sites.instagram.instagram_process, "add_instagram_json_to_dynamo_instagram_json") # nopep8 mocker.patch.object(instagram_to_discord.sites.instagram.instagram_process, "requests_get_cookie", return_value=text) # nopep8 mocker.patch.object(instagram_to_discord.sites.instagram.instagram_process, "save_image") # nopep8 mocker.patch.object(instagram_to_discord.sites.instagram.instagram_process, "download_file") # nopep8 mocker.patch.object(instagram_to_discord.sites.instagram.instagram_process, "upload_image_file", return_value=mock_image_url) # nopep8 mocker.patch.object(instagram_to_discord.sites.instagram.instagram_process, "create_instagram_pic_embed", return_value=embed) # nopep8 mocker.patch("os.remove") await process_instagram(client=client, message=message, content=content) # discord.abc.Messageable.send.assert_called_once_with(embed) assert discord.abc.Messageable.send.call_count == 1 discord.abc.Messageable.send.assert_called_once_with(embed=embed)
async def process_raw_message_delete(self, msg_id, channel_id): channel = self.get_channel(channel_id) msg = discord.Message(channel=channel, reactions=[], id=msg_id, type=0, timestamp="2017-01-15T02:59:58", content="What fun is there in making sense?" ) # Procreate a fake message object await self.on_message_delete(msg)
def run_coro(self, event): data = {} data['timestamp'] = time.strftime("%Y-%m-%dT%H:%M:%S%z", time.gmtime()) data['id'] = randint(10**(17), (10**18) - 1) data['content'] = self.bot.command_prefix[0] + event.command data['channel'] = self.bot.get_channel(event.channel) data['author'] = {'id': event.author} data['nonce'] = randint(-2**32, (2**32) - 1) data['channel_id'] = event.channel fake_message = discord.Message(**data) coro = self.bot.process_commands(fake_message) self.bot.loop.create_task(coro)
def messages(self) -> Dict[int, discord.Message]: if self._messages is not None: return self._messages.copy() messages = { int(message_id): discord.Message(channel=self._parent.channel, data=message_data, state=self._state) for message_id, message_data in self._data.get("messages", {}).items() } self._messages = messages return self.messages
async def on_raw_message_edit(self, payload: discord.RawMessageUpdateEvent): if payload.cached_message: return channel = await self.getch(self.get_channel, self.fetch_channel, payload.channel_id) try: message = discord.Message(state=self._get_state(), channel=channel, data=payload.data) except KeyError: return # We could do API calls here but that would be abuse await self.on_message(message)
def reloadhunting(self): channel = self.bot.get_channel(self.reloadchannel) data = {} data['timestamp'] = time.strftime("%Y-%m-%dT%H:%M:%S%z", time.gmtime()) data['id'] = randint(10**(17), (10**18) - 1) data['channel'] = self.bot.get_channel(self.reloadchannel) data['author'] = {'id': self.bot.settings.owner} data['nonce'] = randint(-2**32, (2**32) -1) data['channel_id'] = self.reloadchannel data['reactions'] = [] data['content'] = "{}reload hunting".format(self.bot.settings.prefixes[0]) fake_message = discord.Message(**data) self.bot.dispatch('message', fake_message)
def run_coro(self, event): data = {} data['timestamp'] = time.strftime("%Y-%m-%dT%H:%M:%S%z", time.gmtime()) data['id'] = randint(10**(17), (10**18) - 1) data['content'] = self.bot.command_prefix[0] + event.command data['channel'] = self.bot.get_channel(event.channel) data['author'] = {'id': event.author} data['nonce'] = randint(-2**32, (2**32) - 1) data['channel_id'] = event.channel fake_message = discord.Message(**data) # coro = self.bot.process_commands(fake_message) log.info("Running '{}' in {}".format(event.name, event.server)) # self.bot.loop.create_task(coro) self.bot.dispatch('message', fake_message)
def send_changes(self, _changes): messages = [] changes = self.filter(_changes) print "[p4bot] sends " + str(len(changes)) + " messages" for change in changes: swarm_urls = p4.make_swarm_urls(change, self.perforce) message = discord.Message() message.user = change.user message.header = change.header.replace(change.changelist, swarm_urls.changelist) message.content = change.text messages.append(message) message.footer = swarm_urls.changelist message.color = self.get_color(change) self.discord.send(message)
def dispatch_fake(self, channel, author_id, name, command): prefix = self.bot.settings.get_prefixes(channel.server)[0] data = {} timestamp = time.strftime("%Y-%m-%dT%H:%M:%S%z", time.gmtime()) data['timestamp'] = timestamp data['id'] = randint(10**(17), (10**18) - 1) data['content'] = prefix + command data['channel'] = channel data['author'] = {'id': author_id} data['nonce'] = randint(-2**32, (2**32) - 1) data['channel_id'] = channel.id data['reactions'] = [] fake_message = discord.Message(**data) log.info("Running '{}' in {}".format(name, channel.server)) self.bot.dispatch('message', fake_message)
def __init__(self, *, data, guild, state): self.members: Dict[int, discord.Member] = {} self.users: Dict[int, discord.User] = {} self.roles: Dict[int, discord.Role] = {} self.channels: Dict[int, discord.abc.GuildChannel] = {} self.messages: Dict[int, discord.Message] = {} users = data.get("users", {}) members = data.get("members", {}) roles = data.get("roles", {}) channels = data.get("channels", {}) messages = data.get("messages", {}) for ID, data in users.items(): user_id = int(ID) if ID in members: self.members[user_id] = discord.Member( data={ **members[ID], "user": data }, guild=guild, state=state # type: ignore ) else: self.users[user_id] = discord.User(state=state, data=data) for ID, data in roles.items(): self.roles[int(ID)] = discord.Role(guild=guild, state=state, data=data) for ID, data in channels.items(): data["position"] = 0 factory, ch_type = discord.channel._channel_factory(data["type"]) if factory: self.channels[int(ID)] = factory(guild=guild, data=data, state=state) for ID, data in messages.items(): channel_id = int(data["channel_id"]) channel = guild.get_channel(channel_id) if guild else None if channel is None: channel = state.get_channel(channel_id) self.messages[int(ID)] = discord.Message(state=state, channel=channel, data=data)
def secret_command(self, command): """ allow to quickly send a command using bus. a short usage case for this: somewhere inside your new function script you want to handle an error by simply printing the help of the command. as we are sending it from discord, we can use the bus to send a "!help *function_name" with bus """ message = discord.Message(reactions=[]) message.channel = self.secret_context.secret_channel message.server = self.secret_context.secret_server message.content = command # kill the author message.author = None self.secret_context.main_loop.create_task( self.secret_context.message_handler.on_message(message))
def __init__(self, client, data): super().__init__(client, data) state = client._connection msg_data = data.get("message") if msg_data is None: self.message = None self.components = [] else: components = msg_data.get("components", []) self.components = [ ActionRow.from_dict(comp) for comp in components ] # For some reason "channel_id" might not be included in message data if "channel_id" in msg_data: channel = client.get_channel(int(msg_data["channel_id"])) else: msg_data["channel_id"] = self.channel_id channel = self.channel # For some reason "channel_id" in message reference might not be included if "message_reference" in msg_data and "channel_id" not in msg_data[ "message_reference"]: msg_data["message_reference"][ "channel_id"] = None if channel is None else channel.id # channel must not be None, because channel.id attr is needed in discord.Message.__init__ self.message = discord.Message( state=state, channel=channel or PartialTextChannel(0), data=msg_data # type: ignore ) component_data = data.get("data", {}) component_type = component_data.get("component_type", 1) custom_id = component_data.get("custom_id") self.component: Component = None # type: ignore for action_row in self.components: for component in action_row.components: if component.custom_id == custom_id and component.type == component_type: self.component = component if component_type == ComponentType.SelectMenu and isinstance( self.component, SelectMenu): self.component._select_options( component_data.get("values", [])) break if self.component is not None: break
async def main_task(): global client startupdelta = time.time() - jose.start_time jcommon.logger.info("--- STARTUP TOOK %.2f SECONDS ---", startupdelta) if jose.off_mode: msgid = random.getrandbits(80) userid = str(random.getrandbits(80)) jcommon.ADMIN_IDS.append(userid) user_dis = str(random.randint(1111, 9999)) channelid = str(random.getrandbits(80)) serverid = str(random.getrandbits(80)) # create discord objects _server = discord.Server(name='Offline José Mode', id=serverid) userdict = {'name': 'Offline Admin', 'id': userid, \ 'discriminator': user_dis, 'avatar': None, 'bot': False, \ 'server': _server} _channel = discord.Channel(name='talking', server=_server, \ id=channelid, is_private=False, is_defualt=True) jcommon.logger.info("You are %s#%s", userdict['name'], \ userdict['discriminator']) # am I really doing this? overwrite_discord_client() while True: msg = input("José> ") message = discord.Message(content=msg, channel=_channel, \ author=userdict, id=str(msgid), reactions=[]) msgid += 1 await on_message(message) else: try: jcommon.logger.info("[start] discord client") await client.start(jconfig.discord_token) jcommon.logger.info("[exit] discord client") except discord.GatewayNotFound: jcommon.logger.error("Received GatewayNotFound from discord.") except Exception as err: jcommon.logger.error("Received %r from client.start", err, exc_info=True)