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

skpy.core.SkypeApiException since today 10/08/2020 #146

Open
idanieri opened this issue Oct 8, 2020 · 10 comments
Open

skpy.core.SkypeApiException since today 10/08/2020 #146

idanieri opened this issue Oct 8, 2020 · 10 comments

Comments

@idanieri
Copy link

idanieri commented Oct 8, 2020

Since today I'm receiving a SkypeApiException that stops my script. Something I discovered is it matches with a new update made by Microsoft during last night.

This is my code:

from skpy import Skype
from skpy import SkypeAuthException
import os
username = "user"
password = "pass"

proxysrv = "proxywsg-ar"

try:
    px = socket.gethostbyname(proxysrv)
    if px:
        # Estas variables solamente están activas durante la duración del programa
        os.environ['http_proxy'] = "http://" + proxysrv + ":3128"
        os.environ['HTTP_PROXY'] = "http://" + proxysrv + ":3128"
        os.environ['https_proxy'] = "https://" + proxysrv + ":3128"
        os.environ['HTTPS_PROXY'] = "https://" + proxysrv + ":3128"
        print("Voy a usar el proxy")
        print(os.environ['http_proxy'], "\n", os.environ['HTTP_PROXY'], "\n", os.environ['https_proxy'], "\n",
              os.environ['HTTPS_PROXY'])
except:
    print("No voy a usar proxy")
    os.environ['https_proxy'] = ""
    os.environ['http_proxy'] = ""
    os.environ['HTTP_PROXY'] = ""
    os.environ['https_proxy'] = ""
    os.environ['HTTPS_PROXY'] = ""

sk = Skype(connect=False)
sk.conn.setTokenFile(".tokens-app")
try:
    sk.conn.readToken()
except SkypeAuthException:
    # Prompt the user for their credentials.
    sk.conn.setUserPwd(username, password)
    sk.conn.getSkypeToken()
print(sk.contacts["ballarati"])
chat = sk.contacts["ballarati"].chat
chat.sendMsg("this is a message")

And this is the output:

C:\Users\cdanieri\python_projects\jira>python test.py
No voy a usar proxy
[SkypeContact]
Id: ballarati
Name: Federico Ballarati | 542596
Location: Ciudad Autónoma de Buenos Aires, AR
Language: ES
Avatar: https://avatar.skype.com/v1/avatars/ballarati?auth_key=-xxxxxxxxxxx
Mood: None
Phones: +54xxxxxxxxxxx
+54xxxxxxxxxx
Birthday: 1970-07-12
Authorised: True
Blocked: False
Favourite: False
Traceback (most recent call last):
File "test.py", line 38, in
chat.sendMsg("this is a message")
File "C:\Users\cdanieri\AppData\Local\Programs\Python\Python38\lib\site-packages\skpy\chat.py", line 201, in sendMsg
return self.sendRaw(editId=edit, messagetype=msgType, content=content,
File "C:\Users\cdanieri\AppData\Local\Programs\Python\Python38\lib\site-packages\skpy\chat.py", line 138, in sendRaw
msgId, arriveTime = self.createRaw(msg)
File "C:\Users\cdanieri\AppData\Local\Programs\Python\Python38\lib\site-packages\skpy\chat.py", line 74, in createRaw
resp = self.skype.conn("POST", "{0}/users/ME/conversations/{1}/messages"
File "C:\Users\cdanieri\AppData\Local\Programs\Python\Python38\lib\site-packages\skpy\conn.py", line 219, in call
raise SkypeApiException("{0} response from {1} {2}".format(resp.status_code, method, url), resp)
skpy.core.SkypeApiException: ('400 response from POST https://azwcus1-client-s.gateway.messenger.live.com/v1/users/ME/conversations/8:ballarati/messages', <Response [400]>)

@Terrance
Copy link
Owner

Terrance commented Oct 8, 2020

Reiterating points in the issue template that you didn't include:

  • If your issue is specific to conversations or messages, include the affected chat types.
    Conversations are either 1-to-1s or groups, with Skype or Skype for Business contacts.
  • If applicable, test the corresponding action on https://web.skype.com to see if it works there.
  • Please set SKPY_DEBUG_HTTP=1 in your environment to capture API requests to Skype's servers.
    Include the relevant parts (not the entire output), `enclosed in backticks` for readability.
    Make sure to remove any personal information such as passwords or tokens before posting.

@idanieri
Copy link
Author

idanieri commented Oct 9, 2020

Hi, thanks for replying.

The issue happend with both chat types but today is working fine. I think the issue was related to some server the api tried to connect to and received this 400 message:

skpy.core.SkypeApiException: ('400 response from POST https://azwcus1-client-s.gateway.messenger.live.com/v1/users/ME/conversations/8:ballarati/messages', <Response [400]>

I'll keep you informed if it happen again with the debug output.

Thanks

@idanieri
Copy link
Author

Hi Terrace, the issue is happening again with 1-to-1 and group conversations. I setted SKPY_DEBUG_HTTP=1 as you asked before and received this:

<= [21/10 10:57:43] POST https://azscus1-client-s.gateway.messenger.live.com/v1/users/ME/conversations/8:ballarati/messages
{'json': {'Has-Mentions': 'false',
          'clientmessageid': '1603288663662',
          'content': 'prueba',
          'contenttype': 'text',
          'imdisplayname': 'Ivan Danieri | 54 6854',
          'messagetype': 'Text'}}
=> [21/10 10:57:44] 400
{'Content-Length': '111',
 'Content-Type': 'application/json; charset=utf-8',
 'ContextId': 'tcid=6014529016411316109,server=BY3PEPF00008599',
 'Date': 'Wed, 21 Oct 2020 13:57:43 GMT'}
{'errorCode': 201,
 'message': 'Either "startTime", "startComposeTime"query string parameter must '
            'be provided'}

I read the documentation but didn't find out a way to send startTime or startComposeTime parameters to the messages.
I'm using the last version available of SkPy: 0.10.1

Can you help me?

Thanks!

@Terrance
Copy link
Owner

Looks like Skype for Web sends a compose time now, I wonder if that's what it's complaining about. I can't reproduce the error with any of my test contacts, but if it's still failing can you try adding this (line 139 of skpy/chat.py):

diff --git skpy/chat.py skpy/chat.py
index 12c249d..1c4649c 100644
--- skpy/chat.py
+++ skpy/chat.py
@@ -137,4 +137,5 @@ class SkypeChat(SkypeObj):
             clientTime = int(time.time() * 1000)
             msg["clientmessageid"] = str(clientTime)
+            msg["composetime"] = "{0}Z".format(datetime.utcnow().isoformat()[:23])
             msgId, arriveTime = self.createRaw(msg)
         arriveDate = datetime.fromtimestamp(arriveTime / 1000) if arriveTime else datetime.now()

([:23] on the timestamp because it seems to be strict on 3 decimal places for the milliseconds, any more and it returns a 400 saying the request isn't valid.)

@Terrance Terrance added bug and removed incomplete labels Oct 21, 2020
@idanieri
Copy link
Author

idanieri commented Oct 21, 2020

Your workaround makes sense but sadly It's no longer failing so I can't test it...
If this issue happen again I'll try it and let you know if it works.

Thanks

@idanieri
Copy link
Author

Hi Terrace. The issue is happening again, I tried your line but didn't worked.
Also I tried changing the format from 20 to 24 but I still receive a 400 msg

<= [23/10 11:16:40] POST https://azwcus1-client-s.gateway.messenger.live.com/v1/users/ME/conversations/8:ballarati/messages
{'json': {'Has-Mentions': 'false',
          'clientmessageid': '1603462600295',
          'composetime': '2020-10-23T14:16:40.295Z',
          'content': 'prueba',
          'contenttype': 'text',
          'imdisplayname': 'Ivan Danieri | 54 6854',
          'messagetype': 'Text'}}
=> [23/10 11:16:40] 400
{'Content-Length': '111',
 'Content-Type': 'application/json; charset=utf-8',
 'ContextId': 'tcid=5475015910442935801,server=MN1PEPF00000E4E',
 'Date': 'Fri, 23 Oct 2020 14:16:39 GMT'}
{'errorCode': 201,
 'message': 'Either "startTime", "startComposeTime"query string parameter must '
            'be provided'}
Traceback (most recent call last):
  File "test.py", line 70, in <module>
    chat.sendMsg("prueba")
  File "C:\Users\cdanieri\AppData\Local\Programs\Python\Python38\lib\site-packages\skpy\chat.py", line 202, in sendMsg
    return self.sendRaw(editId=edit, messagetype=msgType, content=content,
  File "C:\Users\cdanieri\AppData\Local\Programs\Python\Python38\lib\site-packages\skpy\chat.py", line 139, in sendRaw
    msgId, arriveTime = self.createRaw(msg)
  File "C:\Users\cdanieri\AppData\Local\Programs\Python\Python38\lib\site-packages\skpy\chat.py", line 74, in createRaw
    resp = self.skype.conn("POST", "{0}/users/ME/conversations/{1}/messages"
  File "C:\Users\cdanieri\AppData\Local\Programs\Python\Python38\lib\site-packages\skpy\conn.py", line 237, in __call__
    raise SkypeApiException("{0} response from {1} {2}".format(resp.status_code, method, url), resp)
skpy.core.SkypeApiException: ('400 response from POST https://azwcus1-client-s.gateway.messenger.live.com/v1/users/ME/conversations/8:ballarati/messages', <Response [400]>)

@Terrance
Copy link
Owner

Unless I can see what your account does normally in Skype for Web (you'll need to inspect the web traffic in a browser when you send a message), I can't reproduce the problem so I'm unsure how to fix it. It's particularly odd given it only fails some of the time, presumably from a change of messaging host.

@idanieri
Copy link
Author

idanieri commented Oct 26, 2020

Attached is the POST payload that I could capture during my troubleshooting on Friday (saddly it didn't happen again to capture more info).
POST message 2020-10-23 12_57_26-Skype

Something I verified is that all the tags used in Skype for web are the same as in a failed message using SkPy (including the format of "composetime"). Maybe If you can guide me to understand how this messages are built in SkPy I can provide beter testing.

@Terrance
Copy link
Owner

You can use SkypeChat.sendRaw() to manually set most of the fields:

chat = sk.chats["8:joe.4"]
msg = chat.sendRaw(
    messagetype="RichText",
    contenttype="text",
    content="Hello",
    imdisplayname="Fred Adams",
    receiverdisplayname="Joe Bloggs",
)

Note that clientmessageid is handled for you by this method -- there is also SkypeChat.createRaw() that just passes the payload directly to the request body, returning a (message ID, arrival time) tuple:

chat.createRaw({
    "clientmessageid": "1603753046123",
    "composetime": "2020-10-26T22:57:26.123Z",
    "messagetype": "RichText",
    "contenttype": "text",
    "content": "Hello",
    "imdisplayname": "Fred Adams",
    "receiverdisplayname": "Joe Bloggs",
})

See also SkypeChat.sendMsg()'s implementation: https://github.com/Terrance/SkPy/blob/v0.10.1/skpy/chat.py#L192-L202

@idanieri
Copy link
Author

You can use SkypeChat.sendRaw() to manually set most of the fields:

chat = sk.chats["8:joe.4"]
msg = chat.sendRaw(
    messagetype="RichText",
    contenttype="text",
    content="Hello",
    imdisplayname="Fred Adams",
    receiverdisplayname="Joe Bloggs",
)

Note that clientmessageid is handled for you by this method -- there is also SkypeChat.createRaw() that just passes the payload directly to the request body, returning a (message ID, arrival time) tuple:

chat.createRaw({
    "clientmessageid": "1603753046123",
    "composetime": "2020-10-26T22:57:26.123Z",
    "messagetype": "RichText",
    "contenttype": "text",
    "content": "Hello",
    "imdisplayname": "Fred Adams",
    "receiverdisplayname": "Joe Bloggs",
})

See also SkypeChat.sendMsg()'s implementation: https://github.com/Terrance/SkPy/blob/v0.10.1/skpy/chat.py#L192-L202

Thanks for the info! PS: I never hoped so much that something start to failing again as I do right now :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants