Shilling list definition (core)¶
This document holds information regarding shilling with message objects.
We will now see how our shilling / advertisement list can be defined.
Definition of accounts (core)¶
Discord accounts / clients are inside DAF represented by the daf.client.ACCOUNT
class.
It accepts many parameters, out of which these are the most important:
token
: A string (text) parameter. It is the token an account needs to login into Discord. Token can be obtained through the developer portal for bot accounts and through a browser for user accounts.is_user
: An optionalTrue
/False
parameter. Discord has 2 types of clients - user accounts and bots. Set this to True when the abovetoken
belongs to a user and not a bot.proxy
: An optional string (text) parameter. Represents a proxy URL used to access Discord.servers
: A list of servers. In DAF, servers are referred to as “guild”, which was Discord’s original name for a server. Elements inside this list can be any objects inherited fromdaf.guild.BaseGUILD
class. Three types of servers exist (are inherited fromdaf.guild.BaseGUILD
):-
Represents an actual Discord server with channels and members.
-
Represents a user and their direct messages.
Caution
Shilling to DM’s is not recommended as there is no way to check if our client has permissions. There is a high risk of Discord automatically banning you if you attempt to shill messages to users, who can’t receive them from you.
-
Represents multiple Discord servers with channels and members, whose names match a configured pattern. Strictly speaking, this isn’t actually inherited from
daf.guild.BaseGUILD
, but is rather a wrapper for multipledaf.guild.GUILD
. It can be used to quickly define the entire the entire server list, without manually creating eachdaf.guild.GUILD
.Refer to the Automatic Generation (core) section for more information.
-
Now let’s see an example.
1from daf.client import ACCOUNT
2import daf
3
4accounts = [
5 ACCOUNT(
6 token="HHJSHDJKSHKDJASHKDASDHASJKDHAKSJDHSAJKHSDSAD",
7 is_user=True, # Above token is user account's token and not a bot token.
8 servers=[]
9 )
10]
11
12daf.run(accounts=accounts)
As you can see from the above example, the definition of accounts is rather simple. Notice we didn’t define our servers. We will do that in the next section.
After running the example, the following output is displayed.
Ignore the intents
warnings for now. These warnings are not even relevant for user accounts.
Intents are settings of what kind of events the ACCOUNT
should listen to and are controlled
with its intents
parameter. User accounts have no notion of intents.
Notice the first line of the output. It tells us that the logs will be stored into a specific folder.
DAF supports message logging, meaning that a message log is created for each sent message.
A logger can be given to the daf.core.run()
’s logger
parameter.
For more information about logging see Logging (core).
[2024-01-21 13:24:22.887679] (NORMAL) | daf.logging.logger_file: LoggerJSON logs will be saved to C:\Users\david\daf\History (None)
[2024-01-21 13:24:22.887679] (WARNING) | daf.client: Members intent is disabled, it is needed for automatic responders' constraints and invite link tracking. (None)
[2024-01-21 13:24:22.887679] (WARNING) | daf.client: Message content intent is disabled, it is needed for automatic responders. (None)
[2024-01-21 13:24:22.887679] (NORMAL) | daf.client: Logging in... (None)
[2024-01-21 13:24:25.910163] (NORMAL) | daf.client: Logged in as Aproksimacka (None)
[2024-01-21 13:24:25.910163] (NORMAL) | daf.core: Initialization complete. (None)
Definition of servers / guilds (core)¶
We will only cover the definition of daf.guild.GUILD
here.
We will not cover daf.guild.USER
separately as the definition process is exactly
the same.
We will also not cover daf.guild.AutoGUILD
here, as it is covered in Automatic Generation (core).
Let’s define our daf.guild.GUILD
object now. Its most important (but not all) parameters are:
snowflake
: An integer parameter. Represents a unique identifier, which identifies every Discord resource. Snowflake can be obtained by enabling the developer mode, right-clicking on the guild of interest, and then left-clicking on Copy Server ID.messages
: A list parameter of our message objects. Message objects represent the content that will be sent into specific channels, with a specific period. For ourdaf.guild.GUILD
, messages can be the following classes:daf.message.TextMESSAGE
: Message type for sending textual data. Data includes files as well.daf.message.VoiceMESSAGE
: Message type for sending audio data / playing audio to voice channels.
Let’s expand our example from Definition of accounts (core).
1from daf.client import ACCOUNT
2from daf.guild import GUILD
3import daf
4
5accounts = [
6 ACCOUNT(
7 token="HHJSHDJKSHKDJASHKDASDHASJKDHAKSJDHSAJKHSDSAD",
8 is_user=False, # Above token is user account's token and not a bot token.
9 servers=[
10 GUILD(
11 snowflake=863071397207212052,
12 messages=[]
13 )
14 ]
15 )
16]
17
18daf.run(accounts=accounts)
Now let’s define our messages.
Definition of messages (core)¶
Three kinds of messages exist. Additional to daf.message.TextMESSAGE
and daf.message.VoiceMESSAGE
, is the daf.message.DirectMESSAGE
message type.
This message type is used together with daf.guild.USER
for sending messages into DMs.
Unlike the previously mentioned message types, DirectMESSAGE
does not have
the channels
parameter.
Now let’s describe some parameters.
The most important parameters inside daf.message.TextMESSAGE
are:
data
: ATextMessageData
object or aDynamicMessageData
(Dynamically obtained data) inherited object. It represents the data that will be sent into our text channels.channels
: A list of integers or a singleAutoCHANNEL
object. The integers inside a list represents channel snowflake IDs. Obtaining the IDs is the same as for guilds. See Automatic Generation (core) for information aboutAutoCHANNEL
.period
: It represents the time period at which messages will be periodically sent. It can be one of the following types:FixedDurationPeriod
: A fixed time period.RandomizedDurationPeriod
: A randomized (within a certain range) time period.DaysOfWeekPeriod
: A period that sends at multiple specified days at a specific time.DailyPeriod
: A period that sends every day at a specific time.
constraints
: A list of constraints that only allow a message to be sent when they are fulfilled. This can for example be used to only send messages to channels when the last message in that channel is not or own, thus preventing unnecessary spam. Currently a single constraint is supported:
Now that we have an overview of the most important parameters, let’s define our message. We will define a message that sends fixed data into a single channel, with a fixed time (duration) period.
1from daf.message.constraints import AntiSpamMessageConstraint
2from daf.message.messageperiod import FixedDurationPeriod
3from daf.messagedata import TextMessageData
4from daf.message import TextMESSAGE
5from daf.client import ACCOUNT
6from daf.guild import GUILD
7
8from datetime import timedelta
9
10import daf
11
12accounts = [
13 ACCOUNT(
14 token="HHJSHDJKSHKDJASHKDASDHASJKDHAKSJDHSAJKHSDSAD",
15 is_user=False, # Above token is user account's token and not a bot token.
16 servers=[
17 GUILD(
18 snowflake=2312312312312312313123,
19 messages=[
20 TextMESSAGE(
21 data=TextMessageData(content="Looking for NFT?"),
22 channels=[3215125123123123123123],
23 period=FixedDurationPeriod(duration=timedelta(seconds=5)),
24 constraints=[AntiSpamMessageConstraint(per_channel=True)]
25 )
26 ]
27 )
28 ]
29 )
30]
31
32daf.run(accounts=accounts)
Similarly to text messages, voice messages can be defined with daf.message.VoiceMESSAGE
.
Definition is very similar to daf.message.TextMESSAGE
. The only thing that differs from the above
example is the data
parameter. That parameter is with VoiceMESSAGE
of type
VoiceMessageData
(Fixed data) or
DynamicMessageData
(Dynamically obtained data).
Additionally, it contains a volume
parameter.
Message advertisement examples¶
The following examples show a complete core script (without message constraints) setup needed to advertise periodic messages.
TextMESSAGE
1
2"""
3Example shows the basic message shilling into a fixed guild.
4A text message is sent every 8-12 hours (randomly chosen) and it contains a text content and 3 files.
5The message will be first sent in 4 hours.
6"""
7
8# Import the necessary items
9from daf.logging.logger_json import LoggerJSON
10
11from daf.messagedata import FILE
12from daf.messagedata.textdata import TextMessageData
13from datetime import timedelta
14from daf.client import ACCOUNT
15from daf.message.text_based import TextMESSAGE
16from daf.message.messageperiod import RandomizedDurationPeriod
17from daf.guild.guilduser import GUILD
18from daf.logging.tracing import TraceLEVELS
19import daf
20
21# Define the logger
22logger = LoggerJSON(
23 path="C:\\Users\\david\\daf\\History",
24)
25
26
27# Defined accounts
28accounts = [
29 ACCOUNT(
30 token="TOKEN",
31 is_user=True,
32 servers=[
33 GUILD(
34 snowflake=123456789,
35 messages=[
36 TextMESSAGE(
37 data=TextMessageData(
38 content="Buy our red dragon NFTs today!",
39 files=[
40 FILE(filename="C:/Users/david/Downloads/Picture1.png"),
41 FILE(filename="H:/My Drive/PR/okroznice/2023/2023_01_28 - Skiing.md"),
42 FILE(filename="H:/My Drive/PR/okroznice/2023/2023_10_16 - Volitve SSFE.md"),
43 ],
44 ),
45 channels=[123123231232131231, 329312381290381208321, 3232320381208321],
46 period=RandomizedDurationPeriod(
47 minimum=timedelta(hours=8.0),
48 maximum=timedelta(hours=12.0),
49 next_send_time=timedelta(hours=4.0),
50 ),
51 ),
52 ],
53 logging=True,
54 ),
55 ],
56 ),
57]
58
59# Run the framework (blocking)
60daf.run(
61 accounts=accounts,
62 logger=logger,
63 debug=TraceLEVELS.NORMAL,
64)
VoiceMESSAGE
1
2"""
3Example shows the basic message shilling into a fixed guild.
4A text message is sent every 30-90 minutes (randomly chosen) and it plays a single audio file.
5The message will be first sent in 10 minutes.
6"""
7
8# Import the necessary items
9from daf.logging.logger_json import LoggerJSON
10
11from daf.messagedata import FILE
12from daf.messagedata.voicedata import VoiceMessageData
13from datetime import timedelta
14from daf.client import ACCOUNT
15from daf.message.voice_based import VoiceMESSAGE
16from daf.message.messageperiod import RandomizedDurationPeriod
17from daf.guild.guilduser import GUILD
18from daf.logging.tracing import TraceLEVELS
19import daf
20
21# Define the logger
22logger = LoggerJSON(
23 path="C:\\Users\\david\\daf\\History",
24)
25
26# Defined accounts
27accounts = [
28 ACCOUNT(
29 token="TOKEN",
30 is_user=True,
31 servers=[
32 GUILD(
33 snowflake=318732816317823168276278,
34 messages=[
35 VoiceMESSAGE(
36 data=VoiceMessageData(FILE(filename="./VoiceMESSAGE.mp3")),
37 channels=[1136787403588255784, 1199125280149733449],
38 period=RandomizedDurationPeriod(
39 minimum=timedelta(minutes=30),
40 maximum=timedelta(minutes=90),
41 next_send_time=timedelta(minutes=10),
42 ),
43 ),
44 ],
45 logging=True,
46 ),
47 ],
48 ),
49]
50
51# Run the framework (blocking)
52daf.run(
53 accounts=accounts,
54 logger=logger,
55 debug=TraceLEVELS.NORMAL,
56)
DirectMESSAGE
1
2"""
3Example shows the basic message shilling into a fixed DM.
4A text message is sent every 8-12 hours (randomly chosen) and it contains a text content and 3 files.
5
6!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
7WARNING! Using this do directly shill to DM is VERY DANGEROUS!!!
8!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
9There is no way to check for permissions with DM messages, thus the client
10may try to make many forbidden requests. This will eventually result in Discord
11banning. USE AT YOUR OWN RISK!!!!
12
13If you just want to respond to DM messages, the DMResponder is a better example.
14"""
15
16# Import the necessary items
17from daf.logging.logger_json import LoggerJSON
18
19from daf.messagedata import FILE
20from daf.messagedata.textdata import TextMessageData
21from datetime import timedelta
22from daf.client import ACCOUNT
23from daf.message.text_based import DirectMESSAGE
24from daf.message.messageperiod import RandomizedDurationPeriod
25from daf.guild.guilduser import USER
26from daf.logging.tracing import TraceLEVELS
27import daf
28
29# Define the logger
30logger = LoggerJSON(
31 path="C:\\Users\\david\\daf\\History",
32)
33
34
35# Defined accounts
36accounts = [
37 ACCOUNT(
38 token="TOKEN",
39 is_user=False,
40 servers=[
41 USER(
42 snowflake=145196308985020416,
43 messages=[
44 DirectMESSAGE(
45 data=TextMessageData(
46 content="Buy our red dragon NFTs today!",
47 files=[
48 FILE(filename="C:/Users/david/Downloads/Picture1.png"),
49 FILE(filename="H:/My Drive/PR/okroznice/2023/2023_01_28 - Skiing.md"),
50 FILE(filename="H:/My Drive/PR/okroznice/2023/2023_10_16 - Volitve SSFE.md"),
51 ],
52 ),
53 period=RandomizedDurationPeriod(
54 minimum=timedelta(hours=8.0),
55 maximum=timedelta(hours=12.0),
56 ),
57 ),
58 ],
59 logging=True,
60 ),
61 ],
62 ),
63]
64
65# Run the framework (blocking)
66daf.run(
67 accounts=accounts,
68 logger=logger,
69 debug=TraceLEVELS.NORMAL,
70)
Next up, we will take a look how to setup and use message logging.