Automatic responder¶
Added in version 4.0.0.
Discord Advertisement Framework also supports the so called automatic responder.
The automated responder can promptly reply to messages directed to either the guild or private messages. It can be customized to trigger based on specific keyword patterns within a message, provided the constrains are met.
Warning
For the automatic responder to work, ACCOUNT
’s intents
parameter
needs to have the following intents enabled:
members
guild_messages
dm_messages
message_content
intents = Intents.default()
intents.members=True
intents.guild_messages=True
intents.dm_messages=True
intents.message_content=True
There are 2 responder classes:
daf.responder.DMResponder
- responds to messages sent into the bot’s direct messages.daf.responder.GuildResponder
- responds to messages sent into a guild channel. The bot must be joined into that guild, otherwise it will not see the message.
They can be used on each account through the ACCOUNT
’s responders
parameter.
The parameter is a list of responders.
1import daf
2
3daf.client.ACCOUNT(
4 ...,
5 responders=[daf.responder.DMResponder(...), ...]
6)
Both responders accept the following parameters:
- condition:
Represents the message match condition. If both the condition and the constraints are met, then an action (response) will be triggered.
The Matching logic chapter explains how matching is done (same as
daf.guild.AutoGUILD
anddaf.message.AutoCHANNEL
)- action:
Represent the action taken upon message match (and constraint fulfillment). Currently the only action is a message response. There are 2 types of responses, which both send a message in response to the original trigger message.
Will send a reply to the message author’s private messages.
Will send a reply to same channel as the trigger message.
This is only available for the
GuildResponder
responder.Both response classes accept a single parameter
data
of base typeBaseTextData
, which represents the data that will be sent in the response message. TheBaseTextData
type has two different implementations:TextMessageData
- for fixed dataimport daf daf.responder.DMResponse( data=daf.messagedata.TextMessageData("My content") )
DynamicMessageData
- for data obtained through a function.import daf import requests class MyCustomText(DynamicMessageData): def __init__(self, a: int): self.a = a def get_data(self): # Can also be async mydata = requests.get('https://daf.davidhozic.com').text return TextMessageData(content=mydata) daf.responder.DMResponse( data=MyCustomText(5) )
- constraints:
In addition to the
condition
parameter, constrains represent extra checks. These checks (constraints) must all be fulfilled, otherwise no reply will me made to the trigger message.A constraint can be any class implementing a constraint interface. The constraint interface is different for different responder types:
Constraints are implementations of the
BaseDMConstraint
interface.Built-in implementations:
Constraints are implementations of the
BaseGuildConstraint
interface.Built-in implementations:
In addition to the built-in implementations, custom constrains can be made by implementing one of the two interfaces.
from daf import discord from daf.responder import GuildResponder from daf.responder.constraints import BaseGuildConstraint class MyConstraint(BaseGuildConstraint): def __init__(self, <some parameters>): ... def check(self, message: discord.Message, client: discord.Client) -> bool: return <True / False> GuildResponder(..., constraints=[MyConstraint(...)])
Here is a full example of a DM responder:
1
2"""
3The example shows how to use the automatic responder feature.
4
5DMResponder is used. It listens to messages inside DMs.
6RegEx (regex) is used to match the text pattern.
7MemberOfGuildConstraint is used for ensuring the author of the dm message is a member
8of guild with ID 863071397207212052.
9"""
10# Import the necessary items
11from _discord.flags import Intents
12from daf.messagedata.textdata import TextMessageData
13from daf.responder.constraints.dmconstraint import MemberOfGuildConstraint
14from daf.client import ACCOUNT
15from daf.responder.dmresponder import DMResponder
16from daf.responder.actions.response import DMResponse
17from daf.logic import regex
18import daf
19
20
21# Defined accounts
22intents = Intents.default()
23intents.members=True
24intents.guild_messages=True
25intents.dm_messages=True
26intents.message_content=True
27
28accounts = [
29 ACCOUNT(
30 token="CLIENT_TOKEN_HERE",
31 is_user=False,
32 intents=intents,
33 responders=[
34 DMResponder(
35 condition=regex(
36 pattern="(buy|sell).*nft",
37 ),
38 action=DMResponse(
39 data=TextMessageData(
40 content="Instructions on how to buy / sell NFTs are provided on our official website:\nhttps://daf.davidhozic.com",
41 ),
42 ),
43 constraints=[
44 MemberOfGuildConstraint(
45 guild=863071397207212052,
46 ),
47 ],
48 ),
49 ],
50 ),
51]
52
53# Run the framework (blocking)
54daf.run(
55 accounts=accounts
56)
In the above example, we can see that the daf.responder.DMResponder
has a regex
condition defined. The RegEx pattern is as follows: (buy|sell).*nft
.
We can interpret the pattern as “match the message when it contains either the word “buy” or “sell”, followed by any text
as long as “nft” also appears (after “buy” / “sell” ) in that text.
We can also see a MemberOfGuildConstraint
instance.
It is given a guild=863071397207212052
ID parameter, which only allows a response
if the author of the DM message is a member of the guild (server) with ID 863071397207212052.
The intents
parameter of our ACCOUNT
defines 4 intents.
Intents are settings of which events Discord will send to our client.
Without them the auto responder does not work.