ocilo / skype-http

Unofficial Skype API for Node.js via HTTP
https://ocilo.github.io/skype-http
MIT License
51 stars 24 forks source link

Email login does not work and model errors #73

Closed AidanLovelace closed 6 years ago

AidanLovelace commented 6 years ago

When you login with email, it sets the context username to the email so that getting contacts fails in addition to anything that depends on the username.

{
    "username": REDACTED"@outlook.com",
    "skypeToken": {
        "value": REDACTED,
        "expirationDate": REDACTED
    },
    "registrationToken": {
        "value": REDACTED,
        "expirationDate": REDACTED,
        "endpointId": "{78ee4110-26ee-42f1-b487-10e6de41228c}",
        "raw": "registrationToken="REDACTED,
        "host": "bn2-client-s.gateway.messenger.live.com"
    }
}
demurgos commented 6 years ago

Thanks for your report.

This should have been fixed in #71. This is part of the version 0.0.14 released a few hours ago. (This version also has some breaking changes due to the changes in Skype's contacts API so take care when updating, I'm interested in any feedback).

Which version are you using?

Edit: I'm marking it as a duplicate of https://github.com/ocilo/skype-http/issues/58

AidanLovelace commented 6 years ago

I am not really using. Just found this and might use it in an omni chat client I'm working on(project doublethink). The version is what ever was the latest commit on the master branch about 24 hours ago.

demurgos commented 6 years ago

@MrKoookaburra This is odd: the fix was merged 3 days ago. I just re-tried to login with an email address and the state properly listed "username": "live:alice" (while I passed alice@outlook.com).

Could you double-check that you have the latest version and run the example in the repo (using npm start)? Did you use npm install@next or clone the repo? You should get something like below. Please note the Acquired username line: it indicates that the step to get the correct username was successful. Do you see this line?

Username? alice@outlook.com
Password? hunter2
Acquired SkypeToken
Acquired username
Acquired RegistrationToken
Subscribed to resources
Created presence docs
Obtained context trough authentication:
{ username: 'live:alice',
  skypeToken: ... },
  registrationToken: ... }

Depending on the result:


By the way: good luck with your project. I tried to do the same thing two years ago. It worked at the time but only low-level Skype library (this one) is still maintained. (I just did not have time to continue working on a full client)

AidanLovelace commented 6 years ago

I just now recloned the repo. Some people have skype accounts that have been converted from only skype to microsoft account. When this is the case, Skype's api returns an error: "User is in a different cloud." Let me know if you want the full json response. To fix this for my account, I had to change SKYPEWEB_DEFAULT_MESSAGES_HOST from client-s.gateway.messenger.live.com to bn2-client-s.gateway.messenger.live.com (I got the new url by looking at web skype's network activity)

When I do this, the correct username is now in the context.

AidanLovelace commented 6 years ago

When parsing the contacts, it fails with UnexpectedResult from src/lib/contacts/api/get-contacts.ts at line 35.

Edit: tslint says that the property readJson does not exist on type 'DocumentType'

Here is the trimmed down and redacted form of the data that caused the error:

{
    "contacts": [
        {
            "person_id": REDACTED,
            "mri": REDACTED,
            "display_name": "A Name I Set This Person to",
            "display_name_source": "user_edits",
            "profile": {
                "avatar_url": REDACTED,
                "birthday": REDACTED,
                "gender": REDACTED,
                "locations": [
                    {
                        "type": REDACTED,
                        "country": REDACTED,
                        "city": REDACTED,
                        "state": REDACTED
                    }
                ],
                "mood": REDACTED,
                "name": {
                    "first": REDACTED
                },
                "about": REDACTED,
                "language": "en"
            },
            "authorized": true,
            "auth_certificate": REDACTED,
            "blocked": false,
            "favorite": true,
            "phone_hashes": [
                REDACTED,
                REDACTED
            ],
            "creation_time": "2016-11-14T04:28:12.26Z",
            "relationship_history": {
                "sources": [
                    {
                        "type": "scd",
                        "time": "2017-12-03T15:27:37.019204Z"
                    },
                    {
                        "type": "scd",
                        "subtype": "auto_accept",
                        "time": "2017-12-03T15:27:37.019204Z"
                    }
                ]
            }
        },
        {
            "person_id": REDACTED,
            "mri": REDACTED,
            "display_name": REDACTED,
            "display_name_source": "profile",
            "profile": {
                "avatar_url": REDACTED,
                "birthday": REDACTED,
                "gender": REDACTED,
                "locations": [
                    {
                        "type": REDACTED,
                        "country": REDACTED,
                        "city": REDACTED,
                        "state": REDACTED
                    }
                ],
                "mood": REDACTED,
                "name": {
                    "first": REDACTED,
                    "nickname": REDACTED
                },
                "about": REDACTED,
                "language": "en"
            },
            "authorized": true,
            "auth_certificate": REDACTED,
            "blocked": false,
            "creation_time": "2016-11-14T04:28:12.753Z"
        }
    ],
    "blocklist": [
        {
            "mri": REDACTED
        }
    ],
    "groups": [
        {
            "id": REDACTED,
            "name": REDACTED
        },
        {
            "id": REDACTED,
            "name": "Favorites",
            "contacts": [
                REDACTED,
                REDACTED
            ],
            "is_favorite": true
        }
    ],
    "scope": "full"
}

Edit: I feel so stupid. I forgot the main part of the error: ExtraKeys: Unexpected extra keys: ["suggested","phone_hashes"]

demurgos commented 6 years ago

Thanks for the report. With the new contacts API, we introduced stricter model checks, and since you may be one of the first users after the update you are catching some cases that we missed. (tslint is confused by the DOM DocumentType, but this is a local import. Use npm run lint to lint the source code).

I fixed the model and released the constraints to not throw an exception until we have a better solution.

demurgos commented 6 years ago

See #74 and #75

I need some time to check the effects of these changes but it should be merged this evening. I'll let you know (it will be published as npm install skype-http@next).

demurgos commented 6 years ago

@MrKoookaburra The patches are merged and published (0.0.14-build.164). Let me know if you still have an issue.

AidanLovelace commented 6 years ago

Now, it gives MissingKeys: Expected missing keys: ["name"] when retreiving contacts. I think the key might should be display_name in typescript. Or possibly it's wierd for some accounts and you should have them both as optional? (I only barely know typescript) and when grabbing the name, do display_name || name

demurgos commented 6 years ago

Thank you again. name is the only property that was expected to be present on all the contact profiles. Typescript serves more as documentation for you ("contact profiles always have a name field") but we use a library to verify it at runtime (so you receive what is documented).

The goal of this library is to offer a low level API but we are relying on the Skype API and don't control its changes. The main issue we have to tackle is to detect changes and handle them as quickly as possible: that's why the default behavior was designed to throw an error. I test changes using 4 various accounts, but it's obviously not enough data points to reconstruct Skype's model so your feedback is very valuable. We're also often in contact with the author of the Python implementation so it helps to find issues. One of the next objectives would be to try to automatically recover from error and simply issue a warning. It may come in February. (I'll at least send an update to get all the issues in a single error instead of going back and forth between fixing and testing)

Just to be clear, in your last comment you mean that the contact causing the issue had the following shape?

{
  "mri": "8:bob",
  "profile": {
    "display_name": "Some String",
    ...
  },
  ...
}

Or do you have a display_name and display_name_source at the same level as mri? What's the display_name_source value?

If possible, could you also send me an example or describe the values of the "phone_hashes" field? I suppose it's an array of strings: are those hex strings? With a fixed length? Some prefix?

AidanLovelace commented 6 years ago

Yes it is of that shape. Now, it returns the following error: MissingKeys: Expected missing keys: ["is_favorite"]

I wrote a simple script to remove private information from the contacts. I have below a cleansed contacts json file.

Edit(demurgos): Moved code to Gist

AidanLovelace commented 6 years ago

Note for some things that you can't get from my cleansed json:

Here is my cleansing script in case it could be of some use to you:

let fs = require("fs");

let contactsJson = fs.readFileSync(__dirname + "/contacts.json", { encoding: "UTF-8" });

let contactsData = JSON.parse(contactsJson);

contactsData.contacts = contactsData.contacts.map(contact => ({
    person_id: "a person id",
    mri: "an mri",
    display_name: "a display name",
    display_name_source: "identifier",
    profile: {
        avatar_url: "some image URL",
        birthday: contact.profile.birthday || undefined,
        gender: contact.profile.gender || undefined,
        locations: contact.locations,
        mood: "Some wierd mood message",
        name: {
            first: "First Name",
            surname: "Last Name",
            nickname: "someNickNameThing",
            company: (contact.profile.name != undefined ? (contact.profile.name.company || undefined) : undefined)
        },
        phones: [
            {
                number: "+18005555555",
                type: "home"
            },
            {
                number: "+18005555555",
                type: "mobile"
            }
        ],
        language: contact.profile.language || "en"
    },
    authorized: contact.auth_certificate != null,
    auth_certificate: contact.auth_certificate,
    blocked: false,
    suggested: true,
    phone_hashes: contact.phone_hashes || undefined,
    email_hashes: contact.email_hashes || undefined,
    creation_time: contact.creation_time,
    relationship_history: contact.relationship_history,

    agent: contact.agent || undefined
}));

fs.writeFileSync(__dirname + "/contactsProcessed.json", JSON.stringify(contactsData, null, 4));
AidanLovelace commented 6 years ago

I got it to work by changing isFavorite: { type: new BooleanType()} in types/contact-group to isFavorite: { type: new BooleanType(), optional: true }

demurgos commented 6 years ago

Thanks for the cleaning script, it will certainly help. I'm closing this issue since you found the solution. Open new issues if you find something else.

demurgos commented 6 years ago

The fix is merged and published as 0.0.14-build.169 (@next). I'll probably bump to 0.0.15 next week.