-
-
Notifications
You must be signed in to change notification settings - Fork 31.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
530 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Validating CODEOWNERS rules …
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,57 @@ | ||
"""The discord integration.""" | ||
from aiohttp.client_exceptions import ClientConnectorError | ||
import nextcord | ||
|
||
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry | ||
from homeassistant.const import CONF_API_TOKEN, CONF_PLATFORM, Platform | ||
from homeassistant.core import HomeAssistant | ||
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady | ||
from homeassistant.helpers import discovery | ||
from homeassistant.helpers.typing import ConfigType | ||
|
||
from .const import DOMAIN | ||
|
||
PLATFORMS = [Platform.NOTIFY] | ||
|
||
|
||
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: | ||
"""Set up the Discord component.""" | ||
# Iterate all entries for notify to only get Discord | ||
if Platform.NOTIFY in config: | ||
for entry in config[Platform.NOTIFY]: | ||
if entry[CONF_PLATFORM] == DOMAIN: | ||
hass.async_create_task( | ||
hass.config_entries.flow.async_init( | ||
DOMAIN, context={"source": SOURCE_IMPORT}, data=entry | ||
) | ||
) | ||
|
||
return True | ||
|
||
|
||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: | ||
"""Set up Discord from a config entry.""" | ||
nextcord.VoiceClient.warn_nacl = False | ||
discord_bot = nextcord.Client() | ||
try: | ||
await discord_bot.login(entry.data[CONF_API_TOKEN]) | ||
except nextcord.LoginFailure as ex: | ||
raise ConfigEntryAuthFailed("Invalid token given") from ex | ||
except (ClientConnectorError, nextcord.HTTPException, nextcord.NotFound) as ex: | ||
raise ConfigEntryNotReady("Failed to connect") from ex | ||
finally: | ||
await discord_bot.close() | ||
|
||
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = entry.data | ||
|
||
hass.async_create_task( | ||
discovery.async_load_platform( | ||
hass, | ||
Platform.NOTIFY, | ||
DOMAIN, | ||
hass.data[DOMAIN][entry.entry_id], | ||
hass.data[DOMAIN], | ||
) | ||
) | ||
|
||
return True |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
"""Config flow for Discord integration.""" | ||
from __future__ import annotations | ||
|
||
import logging | ||
|
||
from aiohttp.client_exceptions import ClientConnectorError | ||
import nextcord | ||
import voluptuous as vol | ||
|
||
from homeassistant import config_entries | ||
from homeassistant.const import CONF_API_TOKEN, CONF_NAME, CONF_TOKEN | ||
from homeassistant.data_entry_flow import FlowResult | ||
|
||
from .const import DOMAIN, URL_PLACEHOLDER | ||
|
||
_LOGGER = logging.getLogger(__name__) | ||
|
||
CONFIG_SCHEMA = vol.Schema({vol.Required(CONF_API_TOKEN): str}) | ||
|
||
|
||
class DiscordFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): | ||
"""Handle a config flow for Discord.""" | ||
|
||
async def async_step_reauth(self, user_input: dict | None = None) -> FlowResult: | ||
"""Handle a reauthorization flow request.""" | ||
if user_input is not None: | ||
return await self.async_step_reauth_confirm() | ||
|
||
self._set_confirm_only() | ||
return self.async_show_form(step_id="reauth") | ||
|
||
async def async_step_reauth_confirm( | ||
self, user_input: dict[str, str] | None = None | ||
) -> FlowResult: | ||
"""Confirm reauth dialog.""" | ||
errors = {} | ||
|
||
if user_input: | ||
error, info = await _async_try_connect(user_input[CONF_API_TOKEN]) | ||
if info and (entry := await self.async_set_unique_id(str(info.id))): | ||
self.hass.config_entries.async_update_entry( | ||
entry, data=entry.data | user_input | ||
) | ||
await self.hass.config_entries.async_reload(entry.entry_id) | ||
return self.async_abort(reason="reauth_successful") | ||
if error: | ||
errors["base"] = error | ||
|
||
user_input = user_input or {} | ||
return self.async_show_form( | ||
step_id="reauth_confirm", | ||
data_schema=CONFIG_SCHEMA, | ||
description_placeholders=URL_PLACEHOLDER, | ||
errors=errors, | ||
) | ||
|
||
async def async_step_user( | ||
self, user_input: dict[str, str] | None = None | ||
) -> FlowResult: | ||
"""Handle a flow initiated by the user.""" | ||
errors = {} | ||
|
||
if user_input is not None: | ||
error, info = await _async_try_connect(user_input[CONF_API_TOKEN]) | ||
if error is not None: | ||
errors["base"] = error | ||
elif info is not None: | ||
await self.async_set_unique_id(str(info.id)) | ||
self._abort_if_unique_id_configured() | ||
return self.async_create_entry( | ||
title=info.name, | ||
data=user_input | {CONF_NAME: user_input.get(CONF_NAME, info.name)}, | ||
) | ||
|
||
user_input = user_input or {} | ||
return self.async_show_form( | ||
step_id="user", | ||
data_schema=CONFIG_SCHEMA, | ||
description_placeholders=URL_PLACEHOLDER, | ||
errors=errors, | ||
) | ||
|
||
async def async_step_import(self, import_config: dict[str, str]) -> FlowResult: | ||
"""Import a config entry from configuration.yaml.""" | ||
_LOGGER.warning( | ||
"Configuration of the Discord integration in YAML is deprecated and " | ||
"will be removed in Home Assistant 2022.6; Your existing configuration " | ||
"has been imported into the UI automatically and can be safely removed " | ||
"from your configuration.yaml file" | ||
) | ||
for entry in self._async_current_entries(): | ||
if entry.data[CONF_API_TOKEN] == import_config[CONF_TOKEN]: | ||
return self.async_abort(reason="already_configured") | ||
import_config[CONF_API_TOKEN] = import_config.pop(CONF_TOKEN) | ||
return await self.async_step_user(import_config) | ||
|
||
|
||
async def _async_try_connect(token: str) -> tuple[str | None, nextcord.AppInfo | None]: | ||
"""Try connecting to Discord.""" | ||
discord_bot = nextcord.Client() | ||
try: | ||
await discord_bot.login(token) | ||
info = await discord_bot.application_info() | ||
except nextcord.LoginFailure: | ||
return "invalid_auth", None | ||
except (ClientConnectorError, nextcord.HTTPException, nextcord.NotFound): | ||
return "cannot_connect", None | ||
except Exception as ex: # pylint: disable=broad-except | ||
_LOGGER.exception("Unexpected exception: %s", ex) | ||
return "unknown", None | ||
await discord_bot.close() | ||
return None, info |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
"""Constants for the Discord integration.""" | ||
|
||
from typing import Final | ||
|
||
from homeassistant.const import CONF_URL | ||
|
||
DEFAULT_NAME = "Discord" | ||
DOMAIN: Final = "discord" | ||
|
||
URL_PLACEHOLDER = {CONF_URL: "https://www.home-assistant.io/integrations/discord"} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,10 @@ | ||
{ | ||
"domain": "discord", | ||
"name": "Discord", | ||
"config_flow": true, | ||
"documentation": "https://www.home-assistant.io/integrations/discord", | ||
"requirements": ["nextcord==2.0.0a8"], | ||
"codeowners": [], | ||
"codeowners": ["@tkdrob"], | ||
"iot_class": "cloud_push", | ||
"loggers": ["discord"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
{ | ||
"config": { | ||
"step": { | ||
"user": { | ||
"description": "Refer to the documentation on getting your Discord bot key.\n\n{url}", | ||
"data": { | ||
"api_token": "[%key:common::config_flow::data::api_token%]" | ||
} | ||
}, | ||
"reauth_confirm": { | ||
"description": "Refer to the documentation on getting your Discord bot key.\n\n{url}", | ||
"data": { | ||
"api_token": "[%key:common::config_flow::data::api_token%]" | ||
} | ||
} | ||
}, | ||
"error": { | ||
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]", | ||
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]", | ||
"unknown": "[%key:common::config_flow::error::unknown%]" | ||
}, | ||
"abort": { | ||
"already_configured": "[%key:common::config_flow::abort::already_configured_service%]", | ||
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]" | ||
} | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
{ | ||
"config": { | ||
"abort": { | ||
"already_configured": "Service is already configured", | ||
"reauth_successful": "Re-authentication was successful" | ||
}, | ||
"error": { | ||
"cannot_connect": "Failed to connect", | ||
"invalid_auth": "Invalid authentication", | ||
"unknown": "Unexpected error" | ||
}, | ||
"step": { | ||
"user": { | ||
"data": { | ||
"api_token": "API Token" | ||
}, | ||
"description": "Refer to the documentation on getting your Discord bot key.\n\n{url}" | ||
}, | ||
"reauth_confirm": { | ||
"data": { | ||
"api_token": "API Token" | ||
}, | ||
"description": "Refer to the documentation on getting your Discord bot key.\n\n{url}" | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -73,6 +73,7 @@ | |
"dexcom", | ||
"dialogflow", | ||
"directv", | ||
"discord", | ||
"dlna_dmr", | ||
"dlna_dms", | ||
"dnsip", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.