Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvement for the Sound played #19

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

config.yml
43 changes: 26 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,36 @@
# discord-link-opener
Automatically open browser tabs when links matching given constraints are sent in discord channels.

# Disclaimer
Use at own risk!

Automating normal user accounts (generally called "self-bots") is against the [Discord Guidelines](https://discord.com/guidelines) and may result in an account termination (ban) without prior notice.

# Installation and Usage
1. Download Python 3.6.x or 3.7.x . Before installing, make sure to check “Add Python to PATH”.
2. Once installed, open CMD and type:
pip install discord.py[voice] and
pip install asyncio
3. Download Link Opener: https://github.com/clearyy/discord-link-opener
4. Copy open.py to your desktop.
5. Right click open.py and select “Edit with IDLE”. Once in the code, only do the following two things:
Add the discord channel IDs (separated by commas) that you would like to monitor.
Add your Discord token. (Tutorial on how to find your token:
https://www.youtube.com/watch?v=tI1lzqzLQCs)
Do not edit the keyword and blacklist lines.
6. Save the file.
7. Run open.py and you will be prompted for keywords and blacklisted words. Enter words in lowercase, separated by spaces and press enter when completed.
8. Wait for the bot to automatically open Chrome browser tabs when links matching given constraints are sent in the specified discord channels.
9. Cook.
10. To change keywords at any point, press Ctrl + c to terminate the script. Then simply run the script again and enter new words when prompted.
1. Download Python 3.6.x or 3.7.x or 3.8.x . Before installing, make sure to check “Add Python to PATH”.
2. Once installed, open CMD and type:
```
pip install discord.py[voice]
pip install asyncio
pip install pyyaml
```
3. Download Link Opener: https://github.com/Smidelis/discord-link-opener/
4. Extract the contents of the *.zip file to a local folder of your choice (desktop/documents/...)
5. Copy config_example.yaml and rename it to config.yml.
6. Open the config.yml and replace the placeholders with the values for the token (tutorial on how to find your token: https://www.youtube.com/watch?v=tI1lzqzLQCs), the keywords you're looking for, the blacklisted words and the channels.
7. Three browsers have been implemented: chrome, edgechromium and firefox. Change the user_choice to the value of your preferred browser.
8. Save the file.
9. Open PowerShell/CMD and change directory (cd) to the folder, where you have extracted the *.zip file to.
10. Run open.py.
11. Wait for the bot to automatically open new browser tabs when links matching given constraints are sent in the specified discord channels.
12. Cook.

# Requirements
asyncio, discord.py
asyncio, discord.py, pyyaml

# Operating Systems
This was designed for and only tested on windows.

# Credits
This script is a combination of the versions by clearyy and Vincentt1705 and some own ideas. Thanks for the inspiration!
Config files added by elevul.
Binary file added bell.wav
Binary file not shown.
25 changes: 25 additions & 0 deletions config_example.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
token: discordtoken
filters:
keywords:
- 3090
- 3080
- 3070
- 3060
blacklist:
#If you don't want any value in the blacklist set it to null, otherwise replace it with the words you want to blacklist
- null
various:
playBellSound: True
channels:
- 123456789123456789
- 123456789123456789
- 123456789123456789
browsers:
chrome:
path: 'C:\Program Files\Google\Chrome\Application\chrome.exe'
edgechromium:
path: 'C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe'
firefox:
path: 'C:\Program Files\Mozilla Firefox\firefox.exe'
#replace with the name of any of the browsers in the list above. Default is chrome
user_choice: 'chrome'
175 changes: 113 additions & 62 deletions open.py
Original file line number Diff line number Diff line change
@@ -1,84 +1,135 @@
'''
Script to monitor links sent to discord channels and opening them in a new browser tab.
Adapted to monitor links sent by https://partalert.net/join-discord

by https://github.com/Smidelis
based on https://github.com/clearyy/discord-link-opener and https://github.com/Vincentt1705/partalert-link-opener

'''

import webbrowser
import asyncio
import discord
from discord.ext.commands import Bot
from discord.ext import commands
import re

'''
by cleary#6546 // @preorderd
'''
import winsound
from datetime import datetime
import urllib.parse as urlparse
from urllib.parse import parse_qs
import yaml

#pylint: disable=anomalous-backslash-in-string

client = Bot('adawd@@#^^')
client = Bot('KarlaKolumna')
client.remove_command('help')

#prompt user enter keywords to check for in links
keywords = list(map(str,input("Enter keywords seperated by space: ").split()))
#Pulling configuration from yaml file
with open("config.yml", "r") as ymlfile:
cfg = yaml.load(ymlfile, Loader=yaml.FullLoader)

#Registering the browsers and preparing the choice
webbrowser.register('chrome', None, webbrowser.BackgroundBrowser(cfg['browsers']['chrome']['path']))
webbrowser.register('edgechromium', None, webbrowser.BackgroundBrowser(cfg['browsers']['edgechromium']['path']))
webbrowser.register('firefox', None, webbrowser.BackgroundBrowser(cfg['browsers']['firefox']['path']))
browserchoice = cfg['browsers']['user_choice']

#prompt user to enter negative keywords that will prevent a browser window from opening to have no blacklisted words, press enter right away
blacklist = list(map(str,input("Enter blacklisted keywords seperated by space: ").split()))
# Pulling keywords from yml config file
keywords = cfg['filters']['keywords']

#enter channel id(s) where links would be picked up (monitor channel id) seperated by commas. these should be ints
channels = []
# Pulling blacklist from yml file and accounting for it being null
black = cfg['filters']['blacklist']
if black == [None]:
blacklist = ''
else:
blacklist = black
print(blacklist)

#enter token of discord account that has access to watch specified channels
token = ''
# Pulling channels from yml file
channels = cfg['channels']

# Pulling token from the yml file
token = cfg['token']

global start_count
start_count = 0

#check for keywords and blacklisted words in message urls and open browser if conditions are met
async def check_urls(urls):
# Decide whether you want to hear a bell sound when a link is opened (True/False)
playBellSound = cfg['various']['playBellSound']

# Based on https://github.com/Vincentt1705/partalert-link-opener
# Function to print the current time before the information about the link.
def print_time(*content):
"""
Can be used as a normal print function but includes the current date and time
enclosed in brackets in front of the printed content.
:param content: The content you would normally put in a print() function
"""
now = datetime.now()
date_time = now.strftime("%d/%m/%Y %H:%M:%S")
print(f"[{date_time}] - [INFO] ", *content)

# Function to build the amazon url, where partalert is redirecting to
# Obsolete, as partalert URL is not containing Amazon information anymore.
def get_amazon_url(url):
"""
This function collects and returns an amazon link
that would be linked through the green button on the webpage.
:param url: An partalert.net link for an amazon product
:return: The extracted amazon link to the product
"""

# Parse url to obtain query parameters
parsed = urlparse.urlparse(url)

country = parse_qs(parsed.query)['tld'][0]
prod_id = parse_qs(parsed.query)['asin'][0]
tag = parse_qs(parsed.query)['tag'][0]
smid = parse_qs(parsed.query)['smid'][0]

# Create full Amazon url
url = f"https://www.amazon{country}/dp/{prod_id}?tag={tag}&linkCode=ogi&th=1&psc=1&smid={smid}"
return url

# Check for keywords and blacklisted words in message urls and open browser if conditions are met
async def check_urls(urls, channel_name):
for url in urls:
if any(x in url.lower() for x in keywords) and all(x not in url.lower() for x in blacklist):
#enter path to chrome here, for windows 10, this should work
webbrowser.get("C:/Program Files (x86)/Google/Chrome/Application/chrome.exe %s").open(url)
print(f'Opened {url}')
webbrowser.get(browserchoice).open_new_tab(url)
print_time(f'Link opened from #{channel_name}: {url}')
if playBellSound:
winsound.PlaySound('bell.wav', winsound.SND_FILENAME)

async def get_last_msg(channelid):
msg = await client.get_channel(channelid).history(limit=1).flatten()
return msg[0]

@client.event
async def on_message(message):
global start_count
# temporary bypass to weird d.py cacheing issue
# only print this info on the first time the client launches. this is due to d.py calling on_ready() after the bot regains connection
if start_count == 0:
print('\n{} is ready to cop some restocks.\n'.format(str(client.user)))
if len(keywords) >= 1 and keywords[0] != '':
print('Watching for keywords {}.\n'.format(', '.join(keywords)))
else:
print('No keywords have been provided.\n')
if len(blacklist) > 0:
print('Ignoring keywords {}.\n'.format(', '.join(blacklist)))
else:
print('No keywords currently blacklisted.\n')
start_count += 1
async def on_ready():
print_time('{} is ready to watch for links.'.format(str(client.user)))
if len(keywords) >= 1 and keywords[0] != '':
print_time('Watching for keywords {}.'.format(', '.join(keywords)))
else:
if message.channel.id in channels:
if message.embeds:
for embed in message.embeds:
toembed = embed.to_dict()
if str(toembed['type']).lower() != 'link':
urls = re.findall("(?:(?:https?|ftp):\/\/|\b(?:[a-z\d]+\.))(?:(?:[^\s()<>]+|\((?:[^\s()<>]+|(?:\([^\s()<>]+\)))?\))+(?:\((?:[^\s()<>]+|(?:\(?:[^\s()<>]+\)))?\)|[^\s`!()\[\]{};:'.,<>?«»“”‘’]))?",toembed['title'])
if urls:
await check_urls(urls)
try:
urls2 = re.findall("(?:(?:https?|ftp):\/\/|\b(?:[a-z\d]+\.))(?:(?:[^\s()<>]+|\((?:[^\s()<>]+|(?:\([^\s()<>]+\)))?\))+(?:\((?:[^\s()<>]+|(?:\(?:[^\s()<>]+\)))?\)|[^\s`!()\[\]{};:'.,<>?«»“”‘’]))?",toembed['description'])
if urls2:
await check_urls(urls2)
except:
pass
try:
for field in toembed['fields']:
urls3 = re.findall("(?:(?:https?|ftp):\/\/|\b(?:[a-z\d]+\.))(?:(?:[^\s()<>]+|\((?:[^\s()<>]+|(?:\([^\s()<>]+\)))?\))+(?:\((?:[^\s()<>]+|(?:\(?:[^\s()<>]+\)))?\)|[^\s`!()\[\]{};:'.,<>?«»“”‘’]))?",str(field))
if urls3:
await check_urls(urls3)
except:
pass
if message.content != '':
print(message.content)
urls4 = re.findall("(?:(?:https?|ftp):\/\/|\b(?:[a-z\d]+\.))(?:(?:[^\s()<>]+|\((?:[^\s()<>]+|(?:\([^\s()<>]+\)))?\))+(?:\((?:[^\s()<>]+|(?:\(?:[^\s()<>]+\)))?\)|[^\s`!()\[\]{};:'.,<>?«»“”‘’]))?",message.content)
if urls4:
await check_urls(urls4)
print_time('No keywords have been provided.')
if len(blacklist) > 0:
print_time('Ignoring keywords {}.'.format(', '.join(blacklist)))
else:
print_time('No keywords currently blacklisted.')

client.run(token,bot=False)
# Fixed discordpy not able to read embeds anymore. Thanks to dubble#0001 on Discord.
@client.event
async def on_message(message):
if message.channel.id in channels:
await asyncio.sleep(0.3)
try:
last_msg = await get_last_msg(message.channel.id)
fields = last_msg.embeds[0].fields
linkembed = next(x for x in fields if x.name == "Link")
urls = re.findall('http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*(),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', linkembed.value if linkembed else "")
for url in urls:
await check_urls(urls, message.channel.name)
except:
if message.content != '':
urls = re.findall("(?:(?:https?|ftp):\/\/)?[\w/\-?=%.#&+]+\.[\w/\-?=%.#&+]+",message.content)

if urls:
asyncio.ensure_future(check_urls(urls, message.channel.name))
client.run(token,bot=False)