Skip to content

Commit ccdb291

Browse files
committed
Revert config_flow
1 parent 382b3fc commit ccdb291

File tree

1 file changed

+78
-63
lines changed

1 file changed

+78
-63
lines changed
Lines changed: 78 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,87 @@
1-
"""The BlueBubbles integration."""
1+
"""Config flow for BlueBubbles integration."""
22
import logging
3-
import re
43

54
import aiohttp
5+
import voluptuous as vol
66

7-
from homeassistant.config_entries import ConfigEntry
8-
from homeassistant.core import HomeAssistant, ServiceCall
7+
from homeassistant import config_entries
8+
from homeassistant.const import CONF_HOST
9+
from homeassistant.helpers import selector
910

10-
from .const import CONF_HOST, CONF_PASSWORD, CONF_SSL, DOMAIN
11+
from .const import CONF_PASSWORD, CONF_SSL, DOMAIN
1112

1213
_LOGGER = logging.getLogger(__name__)
1314

14-
PLATFORMS: list[str] = []
1515

16-
17-
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
18-
"""Set up BlueBubbles from a config entry."""
19-
20-
hass.data.setdefault(DOMAIN, {})
21-
hass.data[DOMAIN][entry.entry_id] = entry.data
22-
23-
async def send_message(service_call: ServiceCall) -> None:
24-
"""Handle the send_message service."""
25-
conf = entry.data
26-
host = conf[CONF_HOST]
27-
password = conf[CONF_PASSWORD]
28-
ssl = conf[CONF_SSL]
29-
private_api = conf.get("private_api", False)
30-
31-
addresses_str = service_call.data.get("addresses", "").strip()
32-
message = service_call.data.get("message", "").strip()
33-
34-
if not addresses_str:
35-
raise ValueError("At least one address is required")
36-
if not message:
37-
raise ValueError("Message is required")
38-
39-
# Split by , or ; and trim
40-
addresses = [n.strip() for n in re.split(r'[,;]', addresses_str) if n.strip()]
41-
42-
if not addresses:
43-
raise ValueError("No valid addresses provided")
44-
45-
url = f"{host}/api/v1/chat/new"
46-
params = {"password": password}
47-
method = "private-api" if private_api else "apple-script"
48-
payload = {"addresses": addresses, "message": message, "method": method}
49-
50-
try:
51-
async with aiohttp.ClientSession() as session, session.post(
52-
url,
53-
json=payload,
54-
params=params,
55-
ssl=ssl
56-
) as response:
57-
response.raise_for_status()
58-
_LOGGER.debug("Message sent successfully")
59-
except aiohttp.ClientError as err:
60-
_LOGGER.error("Error sending message: %s. Payload: %s", err, payload)
61-
raise
62-
63-
hass.services.async_register(DOMAIN, "send_message", send_message)
64-
65-
return True
66-
67-
68-
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
69-
"""Unload a config entry."""
70-
hass.services.async_remove(DOMAIN, "send_message")
71-
hass.data[DOMAIN].pop(entry.entry_id)
72-
return True
16+
class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
17+
"""Handle a config flow for BlueBubbles."""
18+
19+
VERSION = 1
20+
21+
async def async_step_user(self, user_input=None) -> config_entries.ConfigFlowResult:
22+
"""Handle the initial step."""
23+
24+
if user_input is not None:
25+
errors = {}
26+
27+
host = user_input[CONF_HOST]
28+
password = user_input[CONF_PASSWORD]
29+
ssl = user_input[CONF_SSL]
30+
url = f"{host}/api/v1/server/info"
31+
params = {"password": password}
32+
33+
try:
34+
async with aiohttp.ClientSession() as session, session.get(
35+
url,
36+
params=params,
37+
ssl=ssl
38+
) as response:
39+
response.raise_for_status()
40+
json_data = await response.json()
41+
if json_data.get("status") != 200:
42+
raise ValueError(f"Invalid status in response: {json_data.get('status')}")
43+
data = json_data["data"]
44+
private_api = data["private_api"]
45+
detected_imessage = data["detected_imessage"]
46+
entry_data = user_input.copy()
47+
entry_data["private_api"] = private_api
48+
_LOGGER.debug("Successfully connected to BlueBubbles")
49+
return self.async_create_entry(title=detected_imessage, data=entry_data)
50+
except (aiohttp.ClientError, ValueError, KeyError) as err:
51+
_LOGGER.error("Error connecting to BlueBubbles: %s", err)
52+
errors["base"] = "cannot_connect"
53+
except Exception as err:
54+
_LOGGER.error("Unexpected error: %s", err)
55+
errors["base"] = "unknown"
56+
57+
return self.async_show_form(
58+
step_id="user",
59+
data_schema=vol.Schema(
60+
{
61+
vol.Required(CONF_HOST): selector.TextSelector(
62+
selector.TextSelectorConfig(type=selector.TextSelectorType.URL)
63+
),
64+
vol.Required(CONF_PASSWORD): selector.TextSelector(
65+
selector.TextSelectorConfig(type=selector.TextSelectorType.PASSWORD)
66+
),
67+
vol.Optional(CONF_SSL, default=False): selector.BooleanSelector(),
68+
}
69+
),
70+
errors=errors,
71+
)
72+
73+
return self.async_show_form(
74+
step_id="user",
75+
data_schema=vol.Schema(
76+
{
77+
vol.Required(CONF_HOST): selector.TextSelector(
78+
selector.TextSelectorConfig(type=selector.TextSelectorType.URL)
79+
),
80+
vol.Required(CONF_PASSWORD): selector.TextSelector(
81+
selector.TextSelectorConfig(type=selector.TextSelectorType.PASSWORD)
82+
),
83+
vol.Optional(CONF_SSL, default=False): selector.BooleanSelector(),
84+
}
85+
),
86+
errors={},
87+
)

0 commit comments

Comments
 (0)