Skip to content

Commit 19296ec

Browse files
authored
fix(twitter): prompt user for username if login fails with email (#31)
* refactor(app): pass thread to start() * fix(twitter): prompt user for username if login failed with emails * refactor(discord): use absolute imports
1 parent 38ffc73 commit 19296ec

File tree

5 files changed

+48
-10
lines changed

5 files changed

+48
-10
lines changed

npi/app/discord/app.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from npi.core import App, npi_tool
88
from npi.config import config
99
from npi.error.auth import UnauthorizedError
10+
from npi.core.thread import Thread
1011
from .schema import *
1112

1213
client = discord.Client(intents=discord.Intents.default())
@@ -47,8 +48,8 @@ def __init__(self, llm=None):
4748
self.client = discord.Client(intents=discord.Intents.default())
4849
self._access_token = cred.access_token
4950

50-
async def start(self):
51-
await super().start()
51+
async def start(self, thread: Thread = None):
52+
await super().start(thread)
5253
await self.client.login(self._access_token)
5354

5455
async def dispose(self):

npi/browser_app/twitter/app.py

+41-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import json
22
import os
33
import re
4+
5+
from npiai_proto import api_pb2
46
from playwright.async_api import TimeoutError
57
from markdownify import MarkdownConverter
68

@@ -9,6 +11,8 @@
911
from npi.browser_app.navigator import Navigator
1012
from npi.config import config
1113
from npi.error.auth import UnauthorizedError
14+
from npi.core.callback import callback
15+
from npi.core.thread import Thread
1216
from .schema import *
1317

1418
__SYSTEM_PROMPT__ = """
@@ -117,12 +121,12 @@ def __init__(self, llm=None, headless: bool = True):
117121

118122
self.register(Navigator(playwright=self.playwright))
119123

120-
async def start(self):
124+
async def start(self, thread: Thread = None):
121125
if not self._started:
122-
await super().start()
123-
await self._login()
126+
await super().start(thread)
127+
await self._login(thread)
124128

125-
async def _login(self):
129+
async def _login(self, thread: Thread):
126130
if os.path.exists(self.state_file):
127131
with open(self.state_file, 'r') as f:
128132
state = json.load(f)
@@ -141,6 +145,19 @@ async def _login(self):
141145
await self.playwright.page.get_by_test_id('loginButton').click()
142146
await self.playwright.page.get_by_label('Phone, email, or username').fill(self.creds.username)
143147
await self.playwright.page.get_by_role('button', name='Next').click()
148+
149+
# check if username(not email) is required
150+
await self.playwright.page.wait_for_timeout(1000)
151+
username_input = self.playwright.page.get_by_test_id("ocfEnterTextTextInput")
152+
if await username_input.count() != 0:
153+
username = await self._request_username(thread)
154+
await username_input.fill(username)
155+
await self.playwright.page.get_by_test_id("ocfEnterTextNextButton").click()
156+
157+
await self.playwright.page.wait_for_timeout(1000)
158+
if await username_input.count() != 0:
159+
raise UnauthorizedError('Unable to login to Twitter. Please try again with the correct credentials.')
160+
144161
await self.playwright.page.get_by_label('Password', exact=True).fill(self.creds.password)
145162
await self.playwright.page.get_by_test_id('LoginForm_Login_Button').click()
146163
await self.playwright.page.wait_for_url(__ROUTES__['home'])
@@ -150,6 +167,26 @@ async def _login(self):
150167
os.makedirs(save_dir, exist_ok=True)
151168
await self.playwright.context.storage_state(path=self.state_file)
152169

170+
await thread.send_msg(callback.Callable('Logged in to Twitter'))
171+
172+
@staticmethod
173+
async def _request_username(thread: Thread) -> str:
174+
if thread is None:
175+
raise Exception('`thread` must be provided to request username')
176+
177+
cb = callback.Callable(
178+
action=api_pb2.ActionResponse(
179+
type=api_pb2.ActionType.HUMAN_FEEDBACK,
180+
human_feedback=api_pb2.HumanFeedbackAction(
181+
type=api_pb2.HumanFeedbackActionType.INPUT,
182+
notice='Please enter your username (not email) to continue the login process.',
183+
)
184+
),
185+
)
186+
cb.action.action_id = cb.id()
187+
await thread.send_msg(cb=cb)
188+
return await cb.wait()
189+
153190
@npi_tool
154191
async def get_current_page(self):
155192
"""Get the title and url of the current page."""

npi/core/app.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ def __init__(
150150
self.fn_map = {}
151151
_register_tools(self)
152152

153-
async def start(self):
153+
async def start(self, thread: Thread = None):
154154
"""Start the app"""
155155
self._started = True
156156

npi/core/browser_app.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,10 @@ def __init__(
4343
self.use_screenshot = use_screenshot
4444
self.playwright = playwright or PlaywrightContext(headless)
4545

46-
async def start(self):
46+
async def start(self, thread: Thread = None):
4747
"""Start the Browser App"""
4848
if not self._started:
49-
await super().start()
49+
await super().start(thread)
5050
await self.playwright.start()
5151

5252
async def dispose(self):

npi/server/app.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ async def run(self, thread: Thread):
161161
app = None
162162
try:
163163
app = self.get_app(thread.app_type)
164-
await app.start()
164+
await app.start(thread)
165165
result = await app.chat(thread.instruction, thread)
166166
thread.finish(result)
167167
except UnauthorizedError as e:

0 commit comments

Comments
 (0)