Skip to content

Commit

Permalink
branch refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
fabioo29 committed Aug 23, 2021
0 parents commit fef9acc
Show file tree
Hide file tree
Showing 9 changed files with 951 additions and 0 deletions.
19 changes: 19 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
>> https://console.actions.google.com/u/0/ > select project > 3 vert. dots > project settings > Project ID
DEVICE_ID = "something-something"

>> https://console.actions.google.com/u/0/project/<DEVICE_ID>/deviceregistration/
DEVICE_MODEL_ID = "<DEVICE_ID>-something-something"

>> https://console.cloud.google.com/ >> select project >> search google assistant API >> add
>> google assistant >> Credentials >> OAuth 2.0 >> Create >> Download secrets.json

>> OAuth permission Screen >> Switch to Test(email setup needed)/Production according to your needs

>> exec cmd command >> google-oauthlib-tool --client-secrets path/to/secrets.json --scope https://www.googleapis.com/auth/assistant-sdk-prototype
>> paste output below
CREDENTIALS = '{'key1': 'value1', 'key2': 'value2'}'

ASSISTANT_TOKEN = "Token from CREDENTIALS"

>> Get a discord bot >> https://www.writebots.com/discord-bot-token/
DISCORD_TOKEN = "discord Token"
12 changes: 12 additions & 0 deletions .github/workflows/keep_alive.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
on:
schedule:
- cron: "*/30 * * * *"

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: mikeesto/[email protected]
with:
URL: "https://LikelyCandidAlgorithms.fabioo29.repl.co"
148 changes: 148 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so
./ven/
credentials.json
client_secret_*.json
*.mp3
*.wav
test.py
.vscode/
audio-chunks/
ven/

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
*.pcm

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
.pybuilder/
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version

# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock

# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

# pytype static type analyzer
.pytype/

# Cython debug symbols
cython_debug/
83 changes: 83 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<h2 align="center">Voice assistant discord bot</h2>
<h4 align="center">Music discord bot with built-in google assistant</h4>

<br>
<p style="text-align: justify"><b>Bot default prefixes</b>: ['-', '!', 'google '] - The bot will recognize your voice if it starts with those prefixes or any chat command in the same way. You can see what the bot is catching in your console with the '<i>-sp</i>' argument. Check <b>Input arguments</b> below for more info.</p>

<br>

<h4><b>-help command</b> <i> (known existing google commands + some usefull ones)</i></h4>

```
Voice commands
tell me a joke
temperature braga {in centigrades}
rain today lisbon
what's python language?
time in japan
day in 29/04/1998
423*12+23-1
spin the wheel
cristiano ronaldo {born,married, age, play for}
who wrote rich dad poor dad
10cm to inch
real madrid win
surprise me
Chat commands (+ voice commands)\n
-translate hello {en, english} {pt, portuguese}
-convert 100 USD EUR
-quote AAPL
-play {youtube url/search terms}
-{pause, unpause, skip, queue}
```

<p></p>

<b>Input arguments</b> <i> (optional features)</i>
```shell
python discord-bot/main.py --help
usage: main.py [-h] [-sp] [-cd] [-rt RESPONSETIME]

optional arguments:
-h, --help show this help message and exit
-sp, --speechdetection
show speech detection print in console
-cd, --channeldialog hide dialog User/BOT in channel chat
-rt RESPONSETIME, --responsetime RESPONSETIME
time for user to ask something to BOT in voice channel
```
<br>
<b>SETUP: </b>You need to change the `.env` file according to your data:
```python
# .env file you need to change
# check .env.example for instructions

DEVICE_ID = "something-something"

DEVICE_MODEL_ID = "<DEVICE_ID>-something-something"

CREDENTIALS = '{'key1': 'value1', 'key2': 'value2'}'

ASSISTANT_TOKEN = "Token from credentials.json"

DISCORD_TOKEN = "discord Token"
```
```
virtualenv venv -p python3.9 # create virtualenv
source venv/bin/activate

# install dependencies
pip install -r requirements
sudo apt update; sudo apt-install ffmpeg

python discord-bot/main.py # start discord app
```
<b>To add: </b>: (1) Top.gg integrationn
<br>
<p align="center">Tested in Ubuntu 18.04, Python3.9</p>
80 changes: 80 additions & 0 deletions discord-bot/assist.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@

import json
import logging
import os

from google.assistant.embedded.v1alpha2 import (embedded_assistant_pb2, embedded_assistant_pb2_grpc)
from google.assistant.embedded.v1alpha2.embedded_assistant_pb2 import (
AssistConfig, AssistRequest, AudioOutConfig, DeviceConfig, DialogStateIn,
ScreenOutConfig)
from google.assistant.embedded.v1alpha2.embedded_assistant_pb2_grpc import \
EmbeddedAssistantStub
from google.auth.transport.grpc import secure_authorized_channel
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from html2text import html2text

ASSISTANT_API_ENDPOINT = 'embeddedassistant.googleapis.com'
DEFAULT_GRPC_DEADLINE = 60 * 3 + 5


class Assistant(object):
def __init__(self, language_code='en-US', device_model_id=None, device_id=None, credentials=None, token=None):
loaded_credentials, http_request = self.load_oath2_credentials(
credentials, token)
channel = secure_authorized_channel(
loaded_credentials, http_request, ASSISTANT_API_ENDPOINT)
logging.info('Connecting to %s', ASSISTANT_API_ENDPOINT)

self.stub = EmbeddedAssistantStub(channel)
self.language_code = language_code
self.device_model_id = device_model_id
self.device_id = device_id
self.conversation_state = None

def text_assist(self, query: str, is_new_conversation=True) -> str:
result: str = None
better_result: str = None
for response in self.stub.Assist(self.iter_text_assist_requests(query, is_new_conversation=is_new_conversation), DEFAULT_GRPC_DEADLINE):
if response.dialog_state_out.conversation_state:
self.conversation_state = response.dialog_state_out.conversation_state
if response.dialog_state_out.supplemental_display_text:
result = response.dialog_state_out.supplemental_display_text
if response.screen_out.data:
better_result = html2text(response.screen_out.data)

if result == None:
return "I don't have an answer for what you are looking for!"
else:
return result

def iter_text_assist_requests(self, query, is_new_conversation):
config = AssistConfig(
audio_out_config=AudioOutConfig(
encoding='LINEAR16',
sample_rate_hertz=16000,
volume_percentage=0,
),
dialog_state_in=DialogStateIn(
language_code=self.language_code,
conversation_state=self.conversation_state,
is_new_conversation=is_new_conversation,
),
device_config=DeviceConfig(
device_id=self.device_id,
device_model_id=self.device_model_id,
),
text_query=query,
)
req = AssistRequest(config=config)
yield req

def load_oath2_credentials(self, credentials: str, token: str):
loaded_credentials = Credentials(
token=token,
**(credentials)
)

http_request = Request()
loaded_credentials.refresh(http_request)
return loaded_credentials, http_request
Loading

0 comments on commit fef9acc

Please sign in to comment.