diff --git a/config.json b/config.json deleted file mode 100644 index b4e1494..00000000 --- a/config.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "individual_delay": 6, - "rate_limit_delay": 650, - "offset": 100, - "skip_completed": true, - "skip_failed": true, - "remove_dead_tokens": true, - "remove_completed_members": true, - "stop_dead_tokens": true, - "check_mutual": false, - "friend_before_DM": false, - "online_tokens": false, - "online_scraper_delay": 2000, - "call": false, - "proxy_from_file": true, - "proxy_protocol": "http", - "max_dms_per_token": 0, - "receive_messages": false, - "use_proxy_for_gateway": false, - "timeout": 60, - "captcha_api": "anti-captcha.com", - "captcha_api_key": "", - "proxy_for_captcha": false, - "max_attempt_invite_rejoin": 3, - "disable_keep_alives": false, - "scrape_usernames": false, - "scrape_avatars": false, - "block_after_dm": false, - "close_dm_after_message": false -} diff --git a/config.yml b/config.yml new file mode 100644 index 00000000..2b60df7 --- /dev/null +++ b/config.yml @@ -0,0 +1,216 @@ + +# Config for https://github.com/V4NSH4J/discord-mass-DM-GO + + +# # +# ---- UserBot Behaviour ---- # +# # + +# Duration in seconds that one account waits in between of sends 2 messages. +# Due to how discord rate limits are structured, you can only send 10 new messages every 10 minutes. +# To avoid hitting the rate limit, the recommended duration is 60, but this can be slow. +# Default: 6 +# Type: int +individual_delay: 6 + + +# Duration in seconds that the account sleeps for when rate limited. +# If you send 10 messages very quickly, this rate limit is of 600 seconds (10 minutes). +# With the recommended settings, you'd never hit it, so it's recommended to set at 60. +# Default: 650 +# Type: int +rate_limit_delay: 650 + + +# Duration in Milliseconds (1/1000th of a second) that the program waits in between of starting 2 instances. +# Perhaps one of the most important settings which is why it has it's own section. +# Recommended offset is (60/number of tokens) * 1000 but it does not matter with a few tokens and can be set to any small value like 50. +# Defaut: 100 +# Type: int +offset: 100 + + +# Program will avoid sending DMs to IDs it has already messaged. +# When someone is messaged, his ID is added to "input/completed.txt". +# Adding IDs to "input/completed.txt" will in a way blacklist them. +# Default: true +# Type: bool +skip_completed: true + + +# Program will avoid sending DMs to IDs it has already attempted to message but failed. +# When someone is attempted to be messaged but fails, his ID is added to "input/failed.txt". +# Default: true +# Type: bool +skip_failed: true + +# After completion of Mass DM, DMDGO will attempt to remove non-working tokens from input/tokens.txt +# Default: true +# Type: bool +remove_dead_tokens: true + +# After completion of Mass DM, DMDGO will attempt to remove completed members from "input/memberids.txt" leaving behind only the failed/unattempted IDs. +# This is so the user can re-run the program to target them. +# Default: true +# Type: bool +remove_completed_members: true + + +# Once a token is locked/disabled, it will stop DMing if this is set to true. +# Recommended to be true. +# Default: true +# Type: bool +stop_dead_tokens: true + + +# DMDGO will check if the user has a mutual guild with the token and also gather the user's Name and Discrim. +# This has been buggy in the past. Recommended to be set to false. +# Default: false +# Type: bool +check_mutual: false + + +# DMDGO will send a friend request to everyone in the list before attempting to DM them. Requires online_tokens and check_mutual. +# It needs online_tokens as a precautionary measure. Incase a token has never connected to gateway before and it tries sending a friend request, it will get locked. +# Default: false +# Type: bool +friend_before_DM: false + + +# DMDGO will online tokens before starting mass DM. This is a very important setting, certain functions like receive_messages, friend_before_DM and call cannot be used without it. +# But if you're not planning to use those features anyways, it can be set to false. +# Default: false +# Type: bool +online_tokens: false + + +# Time in milliseconds DMDGO will sleep between 2 consecutive scrapes to avoid being websocket-rate-limited. +# Default: 2000 +# Type: int +online_scraper_delay: 2000 + + +# After a succesful DM, DMDGO will attempt to call the user. This is unnecessary as it would make no difference. +# The calls don't "ring" if the users are not friended which they're not in most cases. So in essence, it would be a call without a ring. Recommended is false. +# Default: false +# Type: bool +call: false + + +# Number of maximum DMs you want your tokens to send. If set to 0 they will send DMs till they are locked or the list is completed. +# Default: 0 +# Type: int +max_dms_per_token: 0 + + +# If set to true, the messages from other users will be logged on console and in "input\received.txt". +# Default: false +# Type: bool +receive_messages: false + + +# If True, the program will block users after DMing them. +# Default: false +# Type: bool +block_after_dm: false + + +# If True, the program will close the user's DMs with them after DMing them. +# This won't delete the message, just hide the channel for the bot-user. +# Default: false +# Type: bool +close_dm_after_message: false + + +# Maximum attempts to rejoin token to server. Use minimum of 2. Introduced since Discord added Captchas to join servers on some tokens. +# Default: 3 +# Type: int +max_attempt_invite_rejoin: 3 + + + +# # +# ---- Proxy Settings ---- # +# # + + +# If set to true, DMDGO will use proxies from input\proxies.txt +# Default: true +# Type: bool +proxy_from_file: true + + +# What protocal to use when using proxies. +# Default: http +# Type: str +proxy_protocol: http + + +# If set to true, websocket connections will use proxy as well. Recommend keeping it at false unless you have very good proxies. +# Default: false +# Type: bool +use_proxy_for_gateway: false + + +# Whether to use your proxies for solving captchas. +# Default: false +# Type: bool +proxy_for_captcha: false + + +# Timeout for all requests in seconds. Increase if slow connection or proxies. +# Default: 60 +# Type: int +timeout: 60 + + +# Closes the underlying TCP connection after every request. Might be helpful to change IPs on every request with rotating proxies. +# Only used with proxies_from_file and not with the proxy field in config. Added because older versions of DMDGO which used only rotating proxies did this by default. +# Default: false +# Type: bool +disable_keep_alives: false + + + +# # +# ---- Captcha Settings ---- # +# # + + +# Domain of the Captcha API you wish to use. The current supported Captcha APIs are: +# - capmonster.cloud +# - anti-captcha.com +# - 2captcha.com +# - rucaptcha.com +# - deathbycaptcha.com +# - anycaptcha.com +# - azcaptcha.com +# - solvecaptcha.com +# Type: str (as url) +captcha_api: "anti-captcha.com" + + +# Your Captcha API Key with balance loaded +# Type: str +captcha_api_key: "your-captcha-key-here" + + + +# # +# ---- Scraping Settings ---- # +# # + + +# When scraping, save usernames. +# Default: false +# Type: bool +scrape_usernames: false + + +# When scraping, save avatars. +# Default: false +# Type: bool +scrape_avatars: false + + + diff --git a/utilities/files.go b/utilities/files.go index 35ff032..8c07bee 100644 --- a/utilities/files.go +++ b/utilities/files.go @@ -19,6 +19,8 @@ import ( "strings" "github.com/fatih/color" + + "gopkg.in/yaml.v2" ) func ReadLines(filename string) ([]string, error) { @@ -183,59 +185,59 @@ func GetMessage() ([]Message, error) { } type Config struct { - Delay int `json:"individual_delay"` - LongDelay int `json:"rate_limit_delay"` - Offset int `json:"offset"` - Skip bool `json:"skip_completed"` - Proxy string `json:"proxy"` - Call bool `json:"call"` - Remove bool `json:"remove_dead_tokens"` - RemoveM bool `json:"remove_completed_members"` - Stop bool `json:"stop_dead_tokens"` - Mutual bool `json:"check_mutual"` - Friend bool `json:"friend_before_DM"` - Websocket bool `json:"online_tokens"` - SleepSc int `json:"online_scraper_delay"` - ProxyFromFile bool `json:"proxy_from_file"` - ProxyProtocol string `json:"proxy_protocol"` - MaxDMS int `json:"max_dms_per_token"` - Receive bool `json:"receive_messages"` - GatewayProxy bool `json:"use_proxy_for_gateway"` - Timeout int `json:"timeout"` - SkipFailed bool `json:"skip_failed"` - ClientKey string `json:"captcha_api_key"` - CaptchaAPI string `json:"captcha_api"` - MaxInvite int `json:"max_attempt_invite_rejoin"` - DisableKL bool `json:"disable_keep_alives"` - ScrapeUsernames bool `json:"scrape_usernames"` - ScrapeAvatars bool `json:"scrape_avatars"` - ProxyForCaptcha bool `json:"proxy_for_captcha"` - Block bool `json:"block_after_dm"` - Close bool `json:"close_dm_after_message"` + Delay int `yaml:"individual_delay"` + LongDelay int `yaml:"rate_limit_delay"` + Offset int `yaml:"offset"` + Skip bool `yaml:"skip_completed"` + Proxy string `yaml:"proxy"` + Call bool `yaml:"call"` + Remove bool `yaml:"remove_dead_tokens"` + RemoveM bool `yaml:"remove_completed_members"` + Stop bool `yaml:"stop_dead_tokens"` + Mutual bool `yaml:"check_mutual"` + Friend bool `yaml:"friend_before_DM"` + Websocket bool `yaml:"online_tokens"` + SleepSc int `yaml:"online_scraper_delay"` + ProxyFromFile bool `yaml:"proxy_from_file"` + ProxyProtocol string `yaml:"proxy_protocol"` + MaxDMS int `yaml:"max_dms_per_token"` + Receive bool `yaml:"receive_messages"` + GatewayProxy bool `yaml:"use_proxy_for_gateway"` + Timeout int `yaml:"timeout"` + SkipFailed bool `yaml:"skip_failed"` + ClientKey string `yaml:"captcha_api_key"` + CaptchaAPI string `yaml:"captcha_api"` + MaxInvite int `yaml:"max_attempt_invite_rejoin"` + DisableKL bool `yaml:"disable_keep_alives"` + ScrapeUsernames bool `yaml:"scrape_usernames"` + ScrapeAvatars bool `yaml:"scrape_avatars"` + ProxyForCaptcha bool `yaml:"proxy_for_captcha"` + Block bool `yaml:"block_after_dm"` + Close bool `yaml:"close_dm_after_message"` } func GetConfig() (Config, error) { - var config Config ex, err := os.Executable() if err != nil { color.Red("Error while finding executable") return Config{}, err } ex = filepath.ToSlash(ex) - file, err := os.Open(path.Join(path.Dir(ex) + "/" + "config.json")) - if err != nil { - color.Red("Error while Opening config.json") - return Config{}, err - } - defer file.Close() - bytes, _ := io.ReadAll(file) - errr := json.Unmarshal(bytes, &config) - if errr != nil { - fmt.Println(err) + file, err1 := os.Open(path.Join(path.Dir(ex) + "/" + "config.yml")) + if err1 != nil { + color.Red("Error while Opening Config (tried .json + .yml)") return Config{}, err + } else { + defer file.Close() + var config Config + bytes, _ := io.ReadAll(file) + errr := yaml.Unmarshal(bytes, &config) + if errr != nil { + fmt.Println(err) + return Config{}, err + } + return config, nil } - - return config, nil } func ProcessAvatar(av string, memberid string) error {