├── dist ├── src │ ├── demo │ │ ├── demo.d.ts │ │ ├── demo.js.map │ │ └── demo.js │ ├── status │ │ ├── status.d.ts │ │ ├── status.js │ │ └── status.js.map │ ├── polling │ │ ├── auth_request.d.ts │ │ ├── poll.d.ts │ │ ├── auth_request.js.map │ │ ├── auth_request.js │ │ ├── poll.js.map │ │ └── poll.js │ ├── request_service.d.ts │ ├── status_service.d.ts │ ├── consts.js.map │ ├── utils.d.ts │ ├── contacts_service.d.ts │ ├── thread_service.d.ts │ ├── message_service.d.ts │ ├── login.d.ts │ ├── skype_account.d.ts │ ├── contacts_service.js.map │ ├── status_service.js.map │ ├── consts.d.ts │ ├── thread_service.js.map │ ├── skyweb.d.ts │ ├── consts.js │ ├── skype_account.js.map │ ├── contacts_service.js │ ├── status_service.js │ ├── request_service.js.map │ ├── message_service.js.map │ ├── thread_service.js │ ├── request_service.js │ ├── skyweb.js.map │ ├── message_service.js │ ├── skype_account.js │ ├── skyweb.js │ ├── login.js.map │ ├── utils.js │ ├── utils.js.map │ └── login.js └── manual_typings │ ├── js-sha256.js │ ├── js-sha256.d.ts │ └── js-sha256.js.map ├── .vscode ├── settings.json ├── tasks.json └── launch.json ├── manual_typings └── js-sha256.ts ├── src ├── status │ └── status.ts ├── consts.ts ├── contacts_service.ts ├── status_service.ts ├── polling │ ├── auth_request.ts │ └── poll.ts ├── request_service.ts ├── demo │ └── demo.ts ├── skype_account.ts ├── thread_service.ts ├── message_service.ts ├── skyweb.ts ├── utils.ts └── login.ts ├── .editorconfig ├── .gitignore ├── tsconfig.json ├── package.json ├── LICENSE.md └── readme.md /dist/src/demo/demo.d.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | -------------------------------------------------------------------------------- /dist/manual_typings/js-sha256.js: -------------------------------------------------------------------------------- 1 | //# sourceMappingURL=js-sha256.js.map -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.check.workspaceVersion": true 3 | } -------------------------------------------------------------------------------- /manual_typings/js-sha256.ts: -------------------------------------------------------------------------------- 1 | declare module "js-sha256" { 2 | let sh256: any; 3 | export = sh256; 4 | } 5 | -------------------------------------------------------------------------------- /src/status/status.ts: -------------------------------------------------------------------------------- 1 | export type Status = "Hidden" | "Online" | "Away" | "Busy"; 2 | 3 | export default Status; 4 | -------------------------------------------------------------------------------- /dist/manual_typings/js-sha256.d.ts: -------------------------------------------------------------------------------- 1 | declare module "js-sha256" { 2 | let sh256: any; 3 | export = sh256; 4 | } 5 | -------------------------------------------------------------------------------- /dist/src/status/status.d.ts: -------------------------------------------------------------------------------- 1 | export declare type Status = "Hidden" | "Online" | "Away" | "Busy"; 2 | export default Status; 3 | -------------------------------------------------------------------------------- /dist/src/status/status.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | //# sourceMappingURL=status.js.map -------------------------------------------------------------------------------- /dist/src/status/status.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/status/status.ts"],"names":[],"mappings":""} -------------------------------------------------------------------------------- /dist/manual_typings/js-sha256.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"js-sha256.js","sourceRoot":"","sources":["../../manual_typings/js-sha256.ts"],"names":[],"mappings":""} -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | charset = utf-8 7 | trim_trailing_whitespace = true 8 | insert_final_newline = true 9 | 10 | [*.ts] 11 | indent_size = 4 12 | 13 | [*.md] 14 | trim_trailing_whitespace = false 15 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "0.1.0", 5 | "command": "tsc", 6 | "isShellCommand": true, 7 | "args": ["-p", "."], 8 | "showOutput": "silent", 9 | "problemMatcher": "$tsc" 10 | } -------------------------------------------------------------------------------- /dist/src/polling/auth_request.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import { CookieJar } from "request"; 3 | import { EventEmitter } from "../utils"; 4 | export declare class AuthRequest { 5 | private requestWithJar; 6 | private eventEmitter; 7 | constructor(cookieJar: CookieJar, eventEmitter: EventEmitter); 8 | pollAll(skypeAccount: any, messagesCallback: any): void; 9 | } 10 | export default AuthRequest; 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### Dependencies ### 2 | # Node dependencies directory 3 | node_modules 4 | 5 | # Typings definitions 6 | typings 7 | 8 | ### Temporary files ### 9 | # Temporary directory 10 | tmp 11 | 12 | # Logs 13 | logs 14 | *.log 15 | 16 | # Runtime data 17 | pids 18 | *.pid 19 | *.seed 20 | 21 | 22 | ### IDE files ### 23 | # Komodo Tools 24 | *.komodoproject 25 | .komodotools 26 | 27 | # WebStorm 28 | .idea 29 | *.iml 30 | 31 | # vim 32 | *~ 33 | -------------------------------------------------------------------------------- /dist/src/request_service.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import { CookieJar } from "request"; 3 | import { EventEmitter } from "./utils"; 4 | export declare class RequestService { 5 | private requestWithJar; 6 | private eventEmitter; 7 | constructor(cookieJar: CookieJar, eventEmitter: EventEmitter); 8 | accept(skypeAccount: any, userName: any): void; 9 | decline(skypeAccount: any, userName: any): void; 10 | } 11 | export default RequestService; 12 | -------------------------------------------------------------------------------- /dist/src/status_service.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import SkypeAccount from './skype_account'; 3 | import { CookieJar } from "request"; 4 | import Status from "./status/status"; 5 | import { EventEmitter } from "./utils"; 6 | export declare class StatusService { 7 | private requestWithJar; 8 | private eventEmitter; 9 | constructor(cookieJar: CookieJar, eventEmitter: EventEmitter); 10 | setStatus(skypeAccount: SkypeAccount, status: Status): void; 11 | } 12 | export default StatusService; 13 | -------------------------------------------------------------------------------- /dist/src/consts.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"consts.js","sourceRoot":"","sources":["../../src/consts.ts"],"names":[],"mappings":";;AAAa,QAAA,cAAc,GAAG,UAAU,CAAC;AAC5B,QAAA,uBAAuB,GAAG,yBAAyB,CAAC;AACpD,QAAA,yBAAyB,GAAG,oBAAoB,CAAC;AACjD,QAAA,0BAA0B,GAAG,kBAAkB,CAAC;AAChD,QAAA,wBAAwB,GAAG,WAAW,CAAC;AACvC,QAAA,2BAA2B,GAAG,gBAAgB,CAAC;AAC/C,QAAA,uBAAuB,GAAG,eAAe,CAAC;AAC1C,QAAA,sBAAsB,GAAG,oBAAoB,CAAC;AAC9C,QAAA,8BAA8B,GAAG,qCAAqC,CAAC;AACvE,QAAA,wBAAwB,GAAG,yGAAyG,CAAC;AACrI,QAAA,4BAA4B,GAAG,mGAAmG,CAAC;AACnI,QAAA,0BAA0B,GAAM,+BAAuB,gQAA6P,CAAC;AACrT,QAAA,6BAA6B,GAAG,yBAAyB,CAAC"} -------------------------------------------------------------------------------- /dist/src/utils.d.ts: -------------------------------------------------------------------------------- 1 | export declare class EventEmitter { 2 | private _eventListeners; 3 | constructor(); 4 | on(eventName: string, listener: (eventName: string, content: any) => void): void; 5 | un(eventName: string, listener: (eventName: string, content: any) => void): void; 6 | fire(eventName: string, content: any): void; 7 | } 8 | export declare class Utils { 9 | static getCurrentTime(): number; 10 | static getTimezone(): string; 11 | static getMac256Hash(challenge: any, appId: any, key: any): string; 12 | } 13 | export default Utils; 14 | -------------------------------------------------------------------------------- /dist/src/contacts_service.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import SkypeAccount from './skype_account'; 3 | import { CookieJar } from "request"; 4 | import { EventEmitter } from "./utils"; 5 | export declare class ContactsService { 6 | contacts: Array<{}>; 7 | private requestWithJar; 8 | private eventEmitter; 9 | constructor(cookieJar: CookieJar, eventEmitter: EventEmitter); 10 | loadContacts(skypeAccount: SkypeAccount, resolve: (skypeAccount: SkypeAccount, contacts: Array<{}>) => {}, reject: any): void; 11 | } 12 | export default ContactsService; 13 | -------------------------------------------------------------------------------- /dist/src/polling/poll.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import SkypeAccount from './../skype_account'; 3 | import { CookieJar } from "request"; 4 | import { EventEmitter } from "../utils"; 5 | export declare class Poll { 6 | private requestWithJar; 7 | private cookieJar; 8 | private eventEmitter; 9 | constructor(cookieJar: CookieJar, eventEmitter: EventEmitter); 10 | pollAll(skypeAccount: SkypeAccount, messagesCallback: (messages: Array) => void): void; 11 | private static parsePollResult(pollResult, messagesCallback); 12 | } 13 | export default Poll; 14 | -------------------------------------------------------------------------------- /dist/src/thread_service.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import SkypeAccount from './skype_account'; 3 | import { CookieJar } from "request"; 4 | import { Promise } from "es6-promise"; 5 | import { EventEmitter } from "./utils"; 6 | export interface Member { 7 | id: string; 8 | role: 'User' | 'Admin'; 9 | } 10 | export declare class ThreadService { 11 | private requestWithJar; 12 | private eventEmitter; 13 | constructor(cookieJar: CookieJar, eventEmitter: EventEmitter); 14 | create(skypeAccount: SkypeAccount, members: Member[]): Promise; 15 | } 16 | export default ThreadService; 17 | -------------------------------------------------------------------------------- /dist/src/message_service.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import SkypeAccount from './skype_account'; 3 | import { CookieJar } from "request"; 4 | import { EventEmitter } from "./utils"; 5 | export declare class MessageService { 6 | private requestWithJar; 7 | private eventEmitter; 8 | constructor(cookieJar: CookieJar, eventEmitter: EventEmitter); 9 | sendMessage(skypeAccount: SkypeAccount, conversationId: string, message: string, messagetype?: string, contenttype?: string): void; 10 | setTopic(skypeAccount: SkypeAccount, conversationId: string, message: string): void; 11 | } 12 | export default MessageService; 13 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "declaration": true, 4 | "target": "ES5", 5 | "module": "commonjs", 6 | "outDir": "./dist", 7 | "sourceMap": true, 8 | "removeComments": true, 9 | "noImplicitAny" : true 10 | }, 11 | "files": [ 12 | "src/skyweb.ts", 13 | "src/login.ts", 14 | "src/skype_account.ts", 15 | "src/utils.ts", 16 | "src/consts.ts", 17 | "src/message_service.ts", 18 | "src/status_service.ts", 19 | "src/contacts_service.ts", 20 | "src/request_service.ts", 21 | "src/polling/auth_request.ts", 22 | "src/polling/poll.ts", 23 | "src/demo/demo.ts", 24 | "manual_typings/js-sha256.ts" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible Node.js debug attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "node", 9 | "request": "launch", 10 | "name": "Launch Program", 11 | "program": "${workspaceRoot}/dist/src/skyweb.js", 12 | "cwd": "${workspaceRoot}", 13 | "outFiles": [] 14 | }, 15 | { 16 | "type": "node", 17 | "request": "attach", 18 | "name": "Attach to Process", 19 | "port": 5858, 20 | "outFiles": [] 21 | } 22 | ] 23 | } -------------------------------------------------------------------------------- /dist/src/login.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import SkypeAccount from './skype_account'; 3 | import { CookieJar } from "request"; 4 | import { Promise } from "es6-promise"; 5 | import { EventEmitter } from "./utils"; 6 | export declare class Login { 7 | private requestWithJar; 8 | private cookieJar; 9 | private eventEmitter; 10 | constructor(cookieJar: CookieJar, eventEmitter: EventEmitter); 11 | doLogin(skypeAccount: SkypeAccount): Promise<{}>; 12 | private sendLoginRequestOauth(skypeAccount, resolve, reject); 13 | private promiseSkypeToken(skypeAccount, magicT); 14 | private getRegistrationToken(skypeAccount, resolve, reject); 15 | private subscribeToResources(skypeAccount, resolve, reject); 16 | private createStatusEndpoint(skypeAccount, resolve, reject); 17 | private getSelfDisplayName(skypeAccout, resolve, reject); 18 | } 19 | export default Login; 20 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "skyweb", 3 | "description": "Unofficial Skype API for nodejs via 'Skype (HTTP)'", 4 | "version": "0.4.3", 5 | "license": "MIT", 6 | "main": "./dist/src/skyweb.js", 7 | "repository": { 8 | "type": "git", 9 | "url": "git://github.com/ShyykoSerhiy/skyweb.git" 10 | }, 11 | "scripts": { 12 | "prepublishOnly": "tsc" 13 | }, 14 | "keywords": [ 15 | "Skype" 16 | ], 17 | "dependencies": { 18 | "big-integer": "^1.5.6", 19 | "cheerio": "^0.22.0", 20 | "es6-promise": "^3.0.2", 21 | "js-sha256": "^0.3.0", 22 | "request": "2.88.0", 23 | "tough-cookie": "^2.0.0" 24 | }, 25 | "devDependencies": { 26 | "@types/big-integer": "0.0.31", 27 | "@types/cheerio": "^0.22.7", 28 | "@types/es6-promise": "^3.3.0", 29 | "@types/form-data": "^2.2.1", 30 | "@types/node": "^9.4.6", 31 | "@types/request": "^2.47.0" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /dist/src/skype_account.d.ts: -------------------------------------------------------------------------------- 1 | export interface RegistrationTokenParams { 2 | raw: string; 3 | registrationToken: string; 4 | expires: number; 5 | endpointId: string; 6 | } 7 | export interface SelfInfo { 8 | displayname: string; 9 | firstname: string; 10 | lastname: string; 11 | namespace: string; 12 | username: string; 13 | } 14 | export declare class SkypeAccount { 15 | private _username; 16 | private _password; 17 | private _skypeToken; 18 | private _skypeTokenExpiresIn; 19 | private _messagesHost; 20 | private _registrationTokenParams; 21 | private _selfInfo; 22 | constructor(username: string, password: string); 23 | username: string; 24 | password: string; 25 | skypeToken: string; 26 | skypeTokenExpiresIn: number; 27 | messagesHost: string; 28 | registrationTokenParams: RegistrationTokenParams; 29 | selfInfo: SelfInfo; 30 | } 31 | export default SkypeAccount; 32 | -------------------------------------------------------------------------------- /dist/src/contacts_service.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"contacts_service.js","sourceRoot":"","sources":["../../src/contacts_service.ts"],"names":[],"mappings":";;AAAA,iCAAmC;AACnC,iCAAmC;AAOnC;IAKI,yBAAY,SAAmB,EAAE,YAA0B;QACvD,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,QAAQ,CAAC,EAAC,GAAG,EAAE,SAAS,EAAC,CAAC,CAAC;QACzD,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACrC,CAAC;IAEM,sCAAY,GAAnB,UAAoB,YAAyB,EAAE,OAA2D,EAAE,MAAW;QAAvH,iBAaC;QAZG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,cAAc,GAAG,MAAM,CAAC,sBAAsB,GAAG,qBAAqB,GAAG,YAAY,CAAC,QAAQ,CAAC,QAAQ,GAAG,WAAW,EAAE;YAClJ,OAAO,EAAE;gBACL,cAAc,EAAE,YAAY,CAAC,UAAU;aAC1C;SACJ,EAAE,UAAC,KAAS,EAAE,QAA6B,EAAE,IAAQ;YAClD,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,QAAQ,CAAC,UAAU,KAAK,GAAG,CAAC,CAAC,CAAC;gBACxC,KAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC;gBAC1C,OAAO,CAAC,YAAY,EAAE,KAAI,CAAC,QAAQ,CAAC,CAAC;YACzC,CAAC;YAAC,IAAI,CAAC,CAAC;gBACJ,KAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,0BAA0B,CAAC,CAAC;YAChE,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IACL,sBAAC;AAAD,CAAC,AAxBD,IAwBC;AAxBY,0CAAe;AA0B5B,kBAAe,eAAe,CAAC"} -------------------------------------------------------------------------------- /dist/src/status_service.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"status_service.js","sourceRoot":"","sources":["../../src/status_service.ts"],"names":[],"mappings":";;AAAA,iCAAmC;AACnC,iCAAmC;AAQnC;IAII,uBAAY,SAAmB,EAAE,YAA0B;QACvD,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,QAAQ,CAAC,EAAC,GAAG,EAAE,SAAS,EAAC,CAAC,CAAC;QACzD,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACrC,CAAC;IAEM,iCAAS,GAAhB,UAAiB,YAAyB,EAAE,MAAc;QAA1D,iBAmBC;QAlBG,IAAI,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC;YAC7B,MAAM,EAAE,MAAM;SACjB,CAAC,CAAC;QACH,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,cAAc,GAAG,YAAY,CAAC,YAAY,GAAG,4CAA4C,EAAE;YACtH,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE;gBACL,mBAAmB,EAAE,YAAY,CAAC,uBAAuB,CAAC,GAAG;aAChE;SACJ,EAAE,UAAC,KAAS,EAAE,QAA6B,EAAE,IAAQ;YAClD,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,QAAQ,CAAC,UAAU,KAAK,GAAG,CAAC,CAAC,CAAC;YAE5C,CAAC;YAAC,IAAI,CAAC,CAAC;gBACJ,KAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,yBAAyB;oBACrD,kBAAkB,GAAG,QAAQ,CAAC,UAAU;oBACxC,aAAa,GAAG,KAAK;oBACrB,YAAY,GAAG,IAAI,CAAC,CAAC;YAC7B,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IACL,oBAAC;AAAD,CAAC,AA7BD,IA6BC;AA7BY,sCAAa;AA+B1B,kBAAe,aAAa,CAAC"} -------------------------------------------------------------------------------- /dist/src/polling/auth_request.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"auth_request.js","sourceRoot":"","sources":["../../../src/polling/auth_request.ts"],"names":[],"mappings":";;AAAA,iCAAmC;AACnC,oCAAsC;AAUtC;IAII,qBAAY,SAAmB,EAAE,YAA0B;QACvD,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,QAAQ,CAAC,EAAC,GAAG,EAAE,SAAS,EAAC,CAAC,CAAC;QACzD,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACrC,CAAC;IAEM,6BAAO,GAAd,UAAe,YAAiB,EAAE,gBAAqB;QAAvD,iBAgBC;QAfG,UAAU,CAAC;YACP,KAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,cAAc,GAAG,MAAM,CAAC,uBAAuB,GAAG,mCAAmC,EAAE;gBAClH,OAAO,EAAE;oBACL,cAAc,EAAE,YAAY,CAAC,UAAU;iBAC1C;aACJ,EAAE,UAAC,KAAU,EAAE,QAAa,EAAE,IAAS;gBACpC,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,QAAQ,CAAC,UAAU,KAAK,GAAG,CAAC,CAAC,CAAC;oBACxC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;gBACvC,CAAC;gBACD,IAAI,CAAC,CAAC;oBACF,KAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,8BAA8B,GAAG,KAAK,GAAG,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAC7G,CAAC;gBACD,KAAI,CAAC,OAAO,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAC;YACjD,CAAC,CAAC,CAAC;QACP,CAAC,EAAE,MAAM,CAAC,CAAC;IACf,CAAC;IACL,kBAAC;AAAD,CAAC,AA1BD,IA0BC;AA1BY,kCAAW;AA4BxB,kBAAe,WAAW,CAAC"} -------------------------------------------------------------------------------- /dist/src/consts.d.ts: -------------------------------------------------------------------------------- 1 | export declare const SKYPEWEB_HTTPS = "https://"; 2 | export declare const SKYPEWEB_LOGIN_LIVE_COM = "https://login.live.com/"; 3 | export declare const SKYPEWEB_LOCKANDKEY_APPID = "msmsgs@msnmsgr.com"; 4 | export declare const SKYPEWEB_LOCKANDKEY_SECRET = "Q1P7W2E4J9R8U3S5"; 5 | export declare const SKYPEWEB_CLIENTINFO_NAME = "skype.com"; 6 | export declare const SKYPEWEB_CLIENTINFO_VERSION = "908/1.105.0.23"; 7 | export declare const SKYPEWEB_API_SKYPE_HOST = "api.skype.com"; 8 | export declare const SKYPEWEB_CONTACTS_HOST = "contacts.skype.com"; 9 | export declare const SKYPEWEB_DEFAULT_MESSAGES_HOST = "client-s.gateway.messenger.live.com"; 10 | export declare const SKYPEWEB_LOGIN_OAUTH_URL = "https://login.skype.com/login/oauth/microsoft?client_id=578134&redirect_uri=https%3A%2F%2Fweb.skype.com"; 11 | export declare const SKYPEWEB_LOGIN_MICROSOFT_URL = "https://login.skype.com/login/microsoft?client_id=578134&redirect_uri=https%3A%2F%2Fweb.skype.com"; 12 | export declare const SKYPEWEB_PPSECURE_OUTH_URL: string; 13 | export declare const SKYPEWEB_SELF_DISPLAYNAME_URL = "/users/self/displayname"; 14 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 shyyko.serhiy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /dist/src/thread_service.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"thread_service.js","sourceRoot":"","sources":["../../src/thread_service.ts"],"names":[],"mappings":";;AAAA,iCAAmC;AACnC,iCAAmC;AAKnC,2CAAoC;AAcpC;IAII,uBAAY,SAAmB,EAAE,YAA0B;QACvD,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,QAAQ,CAAC,EAAC,GAAG,EAAE,SAAS,EAAC,CAAC,CAAC;QACzD,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACrC,CAAC;IAKD,8BAAM,GAAN,UAAO,YAAyB,EAAE,OAAgB;QAAlD,iBA2BC;QA1BG,IAAI,OAAO,GAAG,IAAI,qBAAO,CAAU,UAAC,OAAO,EAAC,MAAM;YAC9C,IAAI,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC;gBAC7B,SAAS,EAAE,OAAO,IAAI,EAAE;aAC3B,CAAC,CAAC;YAEH,KAAI,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,GAAG,YAAY,CAAC,YAAY,GAAG,aAAa,EAAE;gBACxF,IAAI,EAAE,WAAW;gBACjB,OAAO,EAAE;oBACL,mBAAmB,EAAE,YAAY,CAAC,uBAAuB,CAAC,GAAG;iBAChE;aACJ,EAAE,UAAC,KAAS,EAAE,QAA6B,EAAE,IAAQ;gBAClD,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,QAAQ,CAAC,UAAU,KAAK,GAAG,CAAC,CAAC,CAAC;oBACxC,IAAI,QAAQ,GAAG,4BAA4B,CAAC,IAAI,CAAE,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAE,CAAC,CAAC,CAAC,CAAC;oBACjF,OAAO,CAAC,QAAQ,CAAC,CAAC;gBACtB,CAAC;gBAAC,IAAI,CAAC,CAAC;oBACJ,MAAM,CAAC,0BAA0B;wBAC7B,kBAAkB,GAAG,QAAQ,CAAC,UAAU;wBACxC,aAAa,GAAG,KAAK;wBACrB,YAAY,GAAG,IAAI,CACtB,CAAC;gBACN,CAAC;YACL,CAAC,CAAC,CAAC;QAEP,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,OAAO,CAAC;IACnB,CAAC;IACL,oBAAC;AAAD,CAAC,AAxCD,IAwCC;AAxCY,sCAAa;AA0C1B,kBAAe,aAAa,CAAC"} -------------------------------------------------------------------------------- /src/consts.ts: -------------------------------------------------------------------------------- 1 | export const SKYPEWEB_HTTPS = 'https://'; 2 | export const SKYPEWEB_LOGIN_LIVE_COM = 'https://login.live.com/'; 3 | export const SKYPEWEB_LOCKANDKEY_APPID = 'msmsgs@msnmsgr.com'; 4 | export const SKYPEWEB_LOCKANDKEY_SECRET = 'Q1P7W2E4J9R8U3S5'; 5 | export const SKYPEWEB_CLIENTINFO_NAME = 'skype.com'; 6 | export const SKYPEWEB_CLIENTINFO_VERSION = '908/1.105.0.23'; 7 | export const SKYPEWEB_API_SKYPE_HOST = 'api.skype.com'; 8 | export const SKYPEWEB_CONTACTS_HOST = "contacts.skype.com"; 9 | export const SKYPEWEB_DEFAULT_MESSAGES_HOST = 'client-s.gateway.messenger.live.com'; 10 | export const SKYPEWEB_LOGIN_OAUTH_URL = 'https://login.skype.com/login/oauth/microsoft?client_id=578134&redirect_uri=https%3A%2F%2Fweb.skype.com'; 11 | export const SKYPEWEB_LOGIN_MICROSOFT_URL = 'https://login.skype.com/login/microsoft?client_id=578134&redirect_uri=https%3A%2F%2Fweb.skype.com'; 12 | export const SKYPEWEB_PPSECURE_OUTH_URL = `${SKYPEWEB_LOGIN_LIVE_COM}ppsecure/post.srf?wa=wsignin1.0&wp=MBI_SSL&wreply=https%3A%2F%2Flw.skype.com%2Flogin%2Foauth%2Fproxy%3Fclient_id%3D578134%26redirect_uri%3Dhttps%253A%252F%252Fweb.skype.com%26intsrc%3Dclient-_-webapp-_-production-_-go-signin%26site_name%3Dlw.skype.com`; 13 | export const SKYPEWEB_SELF_DISPLAYNAME_URL = '/users/self/displayname'; 14 | -------------------------------------------------------------------------------- /dist/src/skyweb.d.ts: -------------------------------------------------------------------------------- 1 | import SkypeAccount from './skype_account'; 2 | import ContactsService from './contacts_service'; 3 | import ThreadService from "./thread_service"; 4 | import Status from "./status/status"; 5 | import { Promise } from "es6-promise"; 6 | import { Member } from "./thread_service"; 7 | export default class Skyweb { 8 | messagesCallback: (messages: Array) => void; 9 | skypeAccount: SkypeAccount; 10 | contactsService: ContactsService; 11 | private messageService; 12 | private requestService; 13 | private statusService; 14 | private eventEmitter; 15 | threadService: ThreadService; 16 | private cookieJar; 17 | constructor(); 18 | login(username: any, password: any): Promise<{}>; 19 | sendMessage(conversationId: string, message: string, messagetype?: string, contenttype?: string): void; 20 | setTopic(conversationId: string, message: string): void; 21 | setStatus(status: Status): void; 22 | acceptAuthRequest(username: any): void; 23 | declineAuthRequest(username: any): void; 24 | createThread(members: Member[]): Promise; 25 | on(eventName: string, listener: (eventName: string, content: any) => void): void; 26 | un(eventName: string, listener: (eventName: string, content: any) => void): void; 27 | } 28 | -------------------------------------------------------------------------------- /dist/src/consts.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.SKYPEWEB_HTTPS = 'https://'; 4 | exports.SKYPEWEB_LOGIN_LIVE_COM = 'https://login.live.com/'; 5 | exports.SKYPEWEB_LOCKANDKEY_APPID = 'msmsgs@msnmsgr.com'; 6 | exports.SKYPEWEB_LOCKANDKEY_SECRET = 'Q1P7W2E4J9R8U3S5'; 7 | exports.SKYPEWEB_CLIENTINFO_NAME = 'skype.com'; 8 | exports.SKYPEWEB_CLIENTINFO_VERSION = '908/1.105.0.23'; 9 | exports.SKYPEWEB_API_SKYPE_HOST = 'api.skype.com'; 10 | exports.SKYPEWEB_CONTACTS_HOST = "contacts.skype.com"; 11 | exports.SKYPEWEB_DEFAULT_MESSAGES_HOST = 'client-s.gateway.messenger.live.com'; 12 | exports.SKYPEWEB_LOGIN_OAUTH_URL = 'https://login.skype.com/login/oauth/microsoft?client_id=578134&redirect_uri=https%3A%2F%2Fweb.skype.com'; 13 | exports.SKYPEWEB_LOGIN_MICROSOFT_URL = 'https://login.skype.com/login/microsoft?client_id=578134&redirect_uri=https%3A%2F%2Fweb.skype.com'; 14 | exports.SKYPEWEB_PPSECURE_OUTH_URL = exports.SKYPEWEB_LOGIN_LIVE_COM + "ppsecure/post.srf?wa=wsignin1.0&wp=MBI_SSL&wreply=https%3A%2F%2Flw.skype.com%2Flogin%2Foauth%2Fproxy%3Fclient_id%3D578134%26redirect_uri%3Dhttps%253A%252F%252Fweb.skype.com%26intsrc%3Dclient-_-webapp-_-production-_-go-signin%26site_name%3Dlw.skype.com"; 15 | exports.SKYPEWEB_SELF_DISPLAYNAME_URL = '/users/self/displayname'; 16 | //# sourceMappingURL=consts.js.map -------------------------------------------------------------------------------- /dist/src/skype_account.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"skype_account.js","sourceRoot":"","sources":["../../src/skype_account.ts"],"names":[],"mappings":";;AAAA,iCAAoC;AAiBpC;IAWI,sBAAY,QAAe,EAAE,QAAe;QACxC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAEzB,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,8BAA8B,CAAC;IAC9D,CAAC;IAED,sBAAI,kCAAQ;aAIZ;YACI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC;QAC1B,CAAC;aAND,UAAa,QAAe;YACxB,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;QAC9B,CAAC;;;OAAA;IAMD,sBAAI,kCAAQ;aAIZ;YACI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC;QAC1B,CAAC;aAND,UAAa,QAAe;YACxB,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;QAC9B,CAAC;;;OAAA;IAMD,sBAAI,oCAAU;aAId;YACI,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC;QAC5B,CAAC;aAND,UAAe,UAAiB;YAC5B,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC;QAClC,CAAC;;;OAAA;IAMD,sBAAI,6CAAmB;aAIvB;YACI,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC;QACrC,CAAC;aAND,UAAwB,mBAA0B;YAC9C,IAAI,CAAC,oBAAoB,GAAG,mBAAmB,CAAC;QACpD,CAAC;;;OAAA;IAMD,sBAAI,sCAAY;aAIhB;YACI,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC;QAC9B,CAAC;aAND,UAAiB,YAAmB;YAChC,IAAI,CAAC,aAAa,GAAG,YAAY,CAAC;QACtC,CAAC;;;OAAA;IAMD,sBAAI,iDAAuB;aAI3B;YACI,MAAM,CAAC,IAAI,CAAC,wBAAwB,CAAC;QACzC,CAAC;aAND,UAA4B,uBAA+C;YACvE,IAAI,CAAC,wBAAwB,GAAG,uBAAuB,CAAC;QAC5D,CAAC;;;OAAA;IAMD,sBAAI,kCAAQ;aAIZ;YACI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC;QAC1B,CAAC;aAND,UAAa,QAAiB;YAC1B,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;QAC9B,CAAC;;;OAAA;IAKL,mBAAC;AAAD,CAAC,AAzED,IAyEC;AAzEY,oCAAY;AA2EzB,kBAAe,YAAY,CAAC"} -------------------------------------------------------------------------------- /dist/src/contacts_service.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var request = require("request"); 4 | var Consts = require("./consts"); 5 | var ContactsService = (function () { 6 | function ContactsService(cookieJar, eventEmitter) { 7 | this.requestWithJar = request.defaults({ jar: cookieJar }); 8 | this.eventEmitter = eventEmitter; 9 | } 10 | ContactsService.prototype.loadContacts = function (skypeAccount, resolve, reject) { 11 | var _this = this; 12 | this.requestWithJar.get(Consts.SKYPEWEB_HTTPS + Consts.SKYPEWEB_CONTACTS_HOST + '/contacts/v1/users/' + skypeAccount.selfInfo.username + '/contacts', { 13 | headers: { 14 | 'X-Skypetoken': skypeAccount.skypeToken 15 | } 16 | }, function (error, response, body) { 17 | if (!error && response.statusCode === 200) { 18 | _this.contacts = JSON.parse(body).contacts; 19 | resolve(skypeAccount, _this.contacts); 20 | } 21 | else { 22 | _this.eventEmitter.fire('error', 'Failed to load contacts.'); 23 | } 24 | }); 25 | }; 26 | return ContactsService; 27 | }()); 28 | exports.ContactsService = ContactsService; 29 | exports.default = ContactsService; 30 | //# sourceMappingURL=contacts_service.js.map -------------------------------------------------------------------------------- /dist/src/polling/auth_request.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var request = require("request"); 4 | var Consts = require("./../consts"); 5 | var AuthRequest = (function () { 6 | function AuthRequest(cookieJar, eventEmitter) { 7 | this.requestWithJar = request.defaults({ jar: cookieJar }); 8 | this.eventEmitter = eventEmitter; 9 | } 10 | AuthRequest.prototype.pollAll = function (skypeAccount, messagesCallback) { 11 | var _this = this; 12 | setTimeout(function () { 13 | _this.requestWithJar.get(Consts.SKYPEWEB_HTTPS + Consts.SKYPEWEB_API_SKYPE_HOST + '/users/self/contacts/auth-request', { 14 | headers: { 15 | 'X-Skypetoken': skypeAccount.skypeToken 16 | } 17 | }, function (error, response, body) { 18 | if (!error && response.statusCode === 200) { 19 | messagesCallback(JSON.parse(body)); 20 | } 21 | else { 22 | _this.eventEmitter.fire('error', 'Failed to get auth requests.' + error + "/" + JSON.stringify(response)); 23 | } 24 | _this.pollAll(skypeAccount, messagesCallback); 25 | }); 26 | }, 120000); 27 | }; 28 | return AuthRequest; 29 | }()); 30 | exports.AuthRequest = AuthRequest; 31 | exports.default = AuthRequest; 32 | //# sourceMappingURL=auth_request.js.map -------------------------------------------------------------------------------- /dist/src/status_service.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var request = require("request"); 4 | var Consts = require("./consts"); 5 | var StatusService = (function () { 6 | function StatusService(cookieJar, eventEmitter) { 7 | this.requestWithJar = request.defaults({ jar: cookieJar }); 8 | this.eventEmitter = eventEmitter; 9 | } 10 | StatusService.prototype.setStatus = function (skypeAccount, status) { 11 | var _this = this; 12 | var requestBody = JSON.stringify({ 13 | status: status 14 | }); 15 | this.requestWithJar.put(Consts.SKYPEWEB_HTTPS + skypeAccount.messagesHost + '/v1/users/ME/presenceDocs/messagingService', { 16 | body: requestBody, 17 | headers: { 18 | 'RegistrationToken': skypeAccount.registrationTokenParams.raw 19 | } 20 | }, function (error, response, body) { 21 | if (!error && response.statusCode === 200) { 22 | } 23 | else { 24 | _this.eventEmitter.fire('error', 'Failed to change status' + 25 | '.\n Error code: ' + response.statusCode + 26 | '.\n Error: ' + error + 27 | '.\n Body: ' + body); 28 | } 29 | }); 30 | }; 31 | return StatusService; 32 | }()); 33 | exports.StatusService = StatusService; 34 | exports.default = StatusService; 35 | //# sourceMappingURL=status_service.js.map -------------------------------------------------------------------------------- /dist/src/request_service.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"request_service.js","sourceRoot":"","sources":["../../src/request_service.ts"],"names":[],"mappings":";;AAAA,iCAAmC;AACnC,iCAAmC;AAOnC;IAII,wBAAY,SAAmB,EAAE,YAA0B;QACvD,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,QAAQ,CAAC,EAAC,GAAG,EAAE,SAAS,EAAC,CAAC,CAAC;QACzD,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACrC,CAAC;IAED,+BAAM,GAAN,UAAO,YAAiB,EAAE,QAAa;QAAvC,iBAYC;QAXG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,cAAc,GAAG,MAAM,CAAC,uBAAuB,GAAG,oCAAoC,GAAG,QAAQ,GAAG,SAAS,EAAE;YAC1I,OAAO,EAAE;gBACL,cAAc,EAAE,YAAY,CAAC,UAAU;aAC1C;SACJ,EAAE,UAAC,KAAU,EAAE,QAAa,EAAE,IAAS;YACpC,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,QAAQ,CAAC,UAAU,KAAK,GAAG,CAAC,CAAC,CAAC;gBACxC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC5B,CAAC;YAAC,IAAI,CAAC,CAAC;gBACJ,KAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,0BAA0B,GAAG,KAAK,GAAG,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;YACzG,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAED,gCAAO,GAAP,UAAQ,YAAiB,EAAE,QAAa;QAAxC,iBAYC;QAXG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,cAAc,GAAG,MAAM,CAAC,uBAAuB,GAAG,oCAAoC,GAAG,QAAQ,GAAG,UAAU,EAAE;YAC3I,OAAO,EAAE;gBACL,cAAc,EAAE,YAAY,CAAC,UAAU;aAC1C;SACJ,EAAE,UAAC,KAAU,EAAE,QAAa,EAAE,IAAS;YACpC,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,QAAQ,CAAC,UAAU,KAAK,GAAG,CAAC,CAAC,CAAC;gBACxC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC5B,CAAC;YAAC,IAAI,CAAC,CAAC;gBACJ,KAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,2BAA2B,GAAG,KAAK,GAAG,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;YAC1G,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IACL,qBAAC;AAAD,CAAC,AApCD,IAoCC;AApCY,wCAAc;AAsC3B,kBAAe,cAAc,CAAC"} -------------------------------------------------------------------------------- /src/contacts_service.ts: -------------------------------------------------------------------------------- 1 | import * as request from 'request'; 2 | import * as Consts from './consts'; 3 | import SkypeAccount from './skype_account'; 4 | import Utils from './utils'; 5 | import * as http from 'http'; 6 | import {CookieJar} from "request"; 7 | import {EventEmitter} from "./utils"; 8 | 9 | export class ContactsService { 10 | public contacts:Array<{}>; 11 | private requestWithJar: any; 12 | private eventEmitter: EventEmitter; 13 | 14 | constructor(cookieJar:CookieJar, eventEmitter: EventEmitter) { 15 | this.requestWithJar = request.defaults({jar: cookieJar}); 16 | this.eventEmitter = eventEmitter; 17 | } 18 | 19 | public loadContacts(skypeAccount:SkypeAccount, resolve:(skypeAccount:SkypeAccount, contacts:Array<{}>)=>{}, reject: any):void { 20 | this.requestWithJar.get(Consts.SKYPEWEB_HTTPS + Consts.SKYPEWEB_CONTACTS_HOST + '/contacts/v1/users/' + skypeAccount.selfInfo.username + '/contacts', { 21 | headers: { 22 | 'X-Skypetoken': skypeAccount.skypeToken 23 | } 24 | }, (error:any, response:http.IncomingMessage, body:any) => { 25 | if (!error && response.statusCode === 200) { 26 | this.contacts = JSON.parse(body).contacts; 27 | resolve(skypeAccount, this.contacts); 28 | } else { 29 | this.eventEmitter.fire('error', 'Failed to load contacts.'); 30 | } 31 | }); 32 | } 33 | } 34 | 35 | export default ContactsService; 36 | -------------------------------------------------------------------------------- /src/status_service.ts: -------------------------------------------------------------------------------- 1 | import * as request from 'request'; 2 | import * as Consts from './consts'; 3 | import SkypeAccount from './skype_account'; 4 | import Utils from './utils'; 5 | import * as http from 'http'; 6 | import {CookieJar} from "request"; 7 | import Status from "./status/status"; 8 | import {EventEmitter} from "./utils"; 9 | 10 | export class StatusService { 11 | private requestWithJar: any; 12 | private eventEmitter: EventEmitter; 13 | 14 | constructor(cookieJar:CookieJar, eventEmitter: EventEmitter) { 15 | this.requestWithJar = request.defaults({jar: cookieJar}); 16 | this.eventEmitter = eventEmitter; 17 | } 18 | 19 | public setStatus(skypeAccount:SkypeAccount, status: Status) { 20 | var requestBody = JSON.stringify({ 21 | status: status 22 | }); 23 | this.requestWithJar.put(Consts.SKYPEWEB_HTTPS + skypeAccount.messagesHost + '/v1/users/ME/presenceDocs/messagingService', { 24 | body: requestBody, 25 | headers: { 26 | 'RegistrationToken': skypeAccount.registrationTokenParams.raw 27 | } 28 | }, (error:any, response:http.IncomingMessage, body:any) => { 29 | if (!error && response.statusCode === 200) { 30 | //fixme? send success callback? 31 | } else { 32 | this.eventEmitter.fire('error', 'Failed to change status' + 33 | '.\n Error code: ' + response.statusCode + 34 | '.\n Error: ' + error + 35 | '.\n Body: ' + body); 36 | } 37 | }); 38 | } 39 | } 40 | 41 | export default StatusService; 42 | -------------------------------------------------------------------------------- /dist/src/message_service.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"message_service.js","sourceRoot":"","sources":["../../src/message_service.ts"],"names":[],"mappings":";;AAAA,iCAAmC;AACnC,iCAAmC;AAOnC;IAII,wBAAY,SAAmB,EAAE,YAA0B;QACvD,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,QAAQ,CAAC,EAAC,GAAG,EAAE,SAAS,EAAC,CAAC,CAAC;QACzD,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACrC,CAAC;IAEM,oCAAW,GAAlB,UAAmB,YAAyB,EAAE,cAAqB,EAAE,OAAc,EAAE,WAAmB,EAAE,WAAmB;QAA7H,iBAwBC;QAvBG,IAAI,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC;YAG7B,SAAS,EAAE,OAAO;YAClB,aAAa,EAAE,WAAW,IAAI,UAAU;YACxC,aAAa,EAAE,WAAW,IAAI,MAAM;SACvC,CAAC,CAAC;QACH,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,GAAG,YAAY,CAAC,YAAY,GAAG,6BAA6B,GAAG,cAAc,GAAG,WAAW,EAAE;YACvI,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE;gBACL,mBAAmB,EAAE,YAAY,CAAC,uBAAuB,CAAC,GAAG;aAChE;SACJ,EAAE,UAAC,KAAS,EAAE,QAA6B,EAAE,IAAQ;YAClD,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,QAAQ,CAAC,UAAU,KAAK,GAAG,CAAC,CAAC,CAAC;YAE5C,CAAC;YAAC,IAAI,CAAC,CAAC;gBACJ,KAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,yBAAyB;oBACrD,kBAAkB,GAAG,QAAQ,CAAC,UAAU;oBACxC,aAAa,GAAG,KAAK;oBACrB,YAAY,GAAG,IAAI,CACtB,CAAC;YACN,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IACG,iCAAQ,GAAf,UAAgB,YAAyB,EAAE,cAAqB,EAAE,OAAc;QAAhF,iBAmBI;QAlBG,IAAI,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC;YAC7B,OAAO,EAAE,OAAO;SACnB,CAAC,CAAC;QACH,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,cAAc,GAAG,YAAY,CAAC,YAAY,GAAG,cAAc,GAAG,cAAc,GAAG,wBAAwB,EAAE;YACpI,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE;gBACL,mBAAmB,EAAE,YAAY,CAAC,uBAAuB,CAAC,GAAG;aAChE;SACJ,EAAE,UAAC,KAAS,EAAE,QAA6B,EAAE,IAAQ;YAClD,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,QAAQ,CAAC,UAAU,KAAK,GAAG,CAAC,CAAC,CAAC;YAC5C,CAAC;YAAC,IAAI,CAAC,CAAC;gBACJ,KAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,yBAAyB;oBACrD,kBAAkB,GAAG,QAAQ,CAAC,UAAU;oBACxC,aAAa,GAAG,KAAK;oBACrB,YAAY,GAAG,IAAI,CACtB,CAAC;YACN,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IACL,qBAAC;AAAD,CAAC,AAtDD,IAsDC;AAtDY,wCAAc;AAwD3B,kBAAe,cAAc,CAAC"} -------------------------------------------------------------------------------- /src/polling/auth_request.ts: -------------------------------------------------------------------------------- 1 | import * as request from 'request'; 2 | import * as Consts from './../consts'; 3 | import SkypeAccount from './../skype_account'; 4 | import Utils from "./../utils"; 5 | import * as http from 'http'; 6 | import {CookieJar} from "request"; 7 | import {EventEmitter} from "../utils"; 8 | 9 | /** 10 | * @deprecated skype for web now uses websockets. 11 | */ 12 | export class AuthRequest { 13 | private requestWithJar: any; 14 | private eventEmitter: EventEmitter; 15 | 16 | constructor(cookieJar:CookieJar, eventEmitter: EventEmitter) { 17 | this.requestWithJar = request.defaults({jar: cookieJar}); 18 | this.eventEmitter = eventEmitter; 19 | } 20 | 21 | public pollAll(skypeAccount: any, messagesCallback: any) { 22 | setTimeout(()=> { 23 | this.requestWithJar.get(Consts.SKYPEWEB_HTTPS + Consts.SKYPEWEB_API_SKYPE_HOST + '/users/self/contacts/auth-request', { 24 | headers: { 25 | 'X-Skypetoken': skypeAccount.skypeToken 26 | } 27 | }, (error: any, response: any, body: any)=> { 28 | if (!error && response.statusCode === 200) { 29 | messagesCallback(JSON.parse(body)); 30 | } 31 | else { 32 | this.eventEmitter.fire('error', 'Failed to get auth requests.' + error + "/" + JSON.stringify(response)); 33 | } 34 | this.pollAll(skypeAccount, messagesCallback); 35 | }); 36 | }, 120000);//optimal request timeout for authcheck is 120 :( seconds. Or we'll get {"statusCode":429,"body":"{\"status\":{\"code\":42900,\"text\":\"Too Many Requests\"}} 37 | } 38 | } 39 | 40 | export default AuthRequest; 41 | -------------------------------------------------------------------------------- /dist/src/demo/demo.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"demo.js","sourceRoot":"","sources":["../../../src/demo/demo.ts"],"names":[],"mappings":";;AAAA,oCAA+B;AAE/B,IAAI,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC/B,IAAI,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC/B,EAAE,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;IACzB,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;AAC1F,CAAC;AAED,IAAI,MAAM,GAAG,IAAI,gBAAM,EAAE,CAAC;AAC1B,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,UAAC,YAAY;IAC/C,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;IACzC,OAAO,CAAC,GAAG,CAAC,8BAA8B,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,YAAY,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACpG,OAAO,CAAC,GAAG,CAAC,kBAAkB,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,eAAe,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC3F,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IAChC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;AAC/B,CAAC,CAAC,CAAC,KAAK,CAAC,UAAC,MAAc;IACpB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACxB,CAAC,CAAC,CAAC;AAaH,MAAM,CAAC,gBAAgB,GAAG,UAAC,QAAQ;IAC/B,QAAQ,CAAC,OAAO,CAAC,UAAC,OAAO;QACrB,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,WAAW,KAAK,gBAAgB,IAAI,OAAO,CAAC,QAAQ,CAAC,WAAW,KAAK,qBAAqB,CAAC,CAAC,CAAC;YAChK,IAAI,gBAAgB,GAAG,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC;YACzD,IAAI,cAAc,GAAG,gBAAgB,CAAC,SAAS,CAAC,gBAAgB,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YACvF,MAAM,CAAC,WAAW,CAAC,cAAc,EAAE,OAAO,CAAC,QAAQ,CAAC,OAAO,GAAG,4BAA4B,CAAC,CAAC;QAChG,CAAC;IACL,CAAC,CAAC,CAAC;AACP,CAAC,CAAC;AAGF,IAAI,UAAU,GAAG,CAAC,CAAC;AACnB,IAAM,aAAa,GAAG,UAAC,SAAiB,EAAE,KAAa;IACnD,OAAO,CAAC,GAAG,CAAI,UAAU,2BAAsB,KAAO,CAAC,CAAC;IACxD,UAAU,EAAE,CAAC;IACb,EAAE,CAAC,CAAC,UAAU,KAAK,EAAE,CAAC,CAAC,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;QACvC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IACtC,CAAC;AACL,CAAC,CAAC;AACF,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC"} -------------------------------------------------------------------------------- /dist/src/polling/poll.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"poll.js","sourceRoot":"","sources":["../../../src/polling/poll.ts"],"names":[],"mappings":";;AAAA,iCAAmC;AACnC,oCAAsC;AAKtC,kCAA+B;AAG/B;IAKI,cAAY,SAAmB,EAAE,YAA0B;QACvD,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,QAAQ,CAAC,EAAC,GAAG,EAAE,SAAS,EAAC,CAAC,CAAC;QACzD,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC/B,CAAC;IAEM,sBAAO,GAAd,UAAe,YAA0B,EAAE,gBAA4C;QAAvF,iBAyBC;QAxBG,UAAU,CAAC;YACP,KAAI,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,GAAG,YAAY,CAAC,YAAY,GAAG,kDAAkD,EAAE;gBAC7H,OAAO,EAAE;oBACL,mBAAmB,EAAE,YAAY,CAAC,uBAAuB,CAAC,GAAG;iBAChE;aACJ,EAAE,UAAC,KAAS,EAAE,QAA6B,EAAE,IAAQ;gBAClD,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,QAAQ,CAAC,UAAU,KAAK,GAAG,CAAC,CAAC,CAAC;oBACxC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,gBAAgB,CAAC,CAAC;gBAC7D,CAAC;gBAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,SAAS,KAAK,GAAG,CAAC,CAAC,CAAC;oBAGxC,IAAI,aAAK,CAAC,KAAI,CAAC,SAAS,EAAE,KAAI,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC;yBAC7D,IAAI,CAAC,KAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAI,EAAE,YAAY,EAAE,gBAAgB,CAAC,CAAC,CAAC;oBACnE,MAAM,CAAC;gBACX,CAAC;gBAAC,IAAI,CAAC,CAAC;oBACJ,KAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,0BAA0B;wBACtD,kBAAkB,GAAG,CAAC,QAAQ,IAAI,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC;wBACrF,aAAa,GAAG,KAAK;wBACrB,YAAY,GAAG,IAAI,CACtB,CAAC;gBACN,CAAC;gBACD,KAAI,CAAC,OAAO,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAC;YACjD,CAAC,CAAC,CAAC;QACP,CAAC,EAAE,IAAI,CAAC,CAAC;IACb,CAAC;IAEc,oBAAe,GAA9B,UAA+B,UAAc,EAAE,gBAA4C;QACvF,EAAE,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC;YAC3B,IAAI,QAAQ,GAAG,UAAU,CAAC,aAAa,CAAC,MAAM,CAAC,UAAC,IAAS;gBACrD,MAAM,CAAC,IAAI,CAAC,YAAY,KAAK,YAAY,CAAC;YAC9C,CAAC,CAAC,CAAC;YACH,EAAE,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;gBAClB,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YAC/B,CAAC;QACL,CAAC;IACL,CAAC;IACL,WAAC;AAAD,CAAC,AAhDD,IAgDC;AAhDY,oBAAI;AAkDjB,kBAAe,IAAI,CAAC"} -------------------------------------------------------------------------------- /dist/src/demo/demo.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var skyweb_1 = require("../skyweb"); 4 | var username = process.argv[2]; 5 | var password = process.argv[3]; 6 | if (!username || !password) { 7 | throw new Error('Username and password should be provided as commandline arguments!'); 8 | } 9 | var skyweb = new skyweb_1.default(); 10 | skyweb.login(username, password).then(function (skypeAccount) { 11 | console.log('Skyweb is initialized now'); 12 | console.log('Here is some info about you:' + JSON.stringify(skyweb.skypeAccount.selfInfo, null, 2)); 13 | console.log('Your contacts : ' + JSON.stringify(skyweb.contactsService.contacts, null, 2)); 14 | console.log('Going incognito.'); 15 | skyweb.setStatus('Hidden'); 16 | }).catch(function (reason) { 17 | console.log(reason); 18 | }); 19 | skyweb.messagesCallback = function (messages) { 20 | messages.forEach(function (message) { 21 | if (message.resource.from.indexOf(username) === -1 && message.resource.messagetype !== 'Control/Typing' && message.resource.messagetype !== 'Control/ClearTyping') { 22 | var conversationLink = message.resource.conversationLink; 23 | var conversationId = conversationLink.substring(conversationLink.lastIndexOf('/') + 1); 24 | skyweb.sendMessage(conversationId, message.resource.content + '. Cats will rule the World'); 25 | } 26 | }); 27 | }; 28 | var errorCount = 0; 29 | var errorListener = function (eventName, error) { 30 | console.log(errorCount + " : Error occured : " + error); 31 | errorCount++; 32 | if (errorCount === 10) { 33 | console.log("Removing error listener"); 34 | skyweb.un('error', errorListener); 35 | } 36 | }; 37 | skyweb.on('error', errorListener); 38 | //# sourceMappingURL=demo.js.map -------------------------------------------------------------------------------- /dist/src/thread_service.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var request = require("request"); 4 | var Consts = require("./consts"); 5 | var es6_promise_1 = require("es6-promise"); 6 | var ThreadService = (function () { 7 | function ThreadService(cookieJar, eventEmitter) { 8 | this.requestWithJar = request.defaults({ jar: cookieJar }); 9 | this.eventEmitter = eventEmitter; 10 | } 11 | ThreadService.prototype.create = function (skypeAccount, members) { 12 | var _this = this; 13 | var promise = new es6_promise_1.Promise(function (resolve, reject) { 14 | var requestBody = JSON.stringify({ 15 | 'members': members || [] 16 | }); 17 | _this.requestWithJar.post(Consts.SKYPEWEB_HTTPS + skypeAccount.messagesHost + '/v1/threads', { 18 | body: requestBody, 19 | headers: { 20 | 'RegistrationToken': skypeAccount.registrationTokenParams.raw 21 | } 22 | }, function (error, response, body) { 23 | if (!error && response.statusCode === 201) { 24 | var threadID = /threads\/(.*@thread.skype)/.exec(response.headers.location)[1]; 25 | resolve(threadID); 26 | } 27 | else { 28 | reject('Failed to create thread.' + 29 | '.\n Error code: ' + response.statusCode + 30 | '.\n Error: ' + error + 31 | '.\n Body: ' + body); 32 | } 33 | }); 34 | }); 35 | return promise; 36 | }; 37 | return ThreadService; 38 | }()); 39 | exports.ThreadService = ThreadService; 40 | exports.default = ThreadService; 41 | //# sourceMappingURL=thread_service.js.map -------------------------------------------------------------------------------- /src/request_service.ts: -------------------------------------------------------------------------------- 1 | import * as request from 'request'; 2 | import * as Consts from './consts'; 3 | import SkypeAccount from './skype_account'; 4 | import Utils from './utils'; 5 | import * as http from 'http'; 6 | import {CookieJar} from "request"; 7 | import {EventEmitter} from "./utils"; 8 | 9 | export class RequestService { 10 | private requestWithJar: any; 11 | private eventEmitter: EventEmitter; 12 | 13 | constructor(cookieJar:CookieJar, eventEmitter: EventEmitter) { 14 | this.requestWithJar = request.defaults({jar: cookieJar}); 15 | this.eventEmitter = eventEmitter; 16 | } 17 | 18 | accept(skypeAccount: any, userName: any) { 19 | this.requestWithJar.put(Consts.SKYPEWEB_HTTPS + Consts.SKYPEWEB_API_SKYPE_HOST + '/users/self/contacts/auth-request/' + userName + '/accept', { 20 | headers: { 21 | 'X-Skypetoken': skypeAccount.skypeToken 22 | } 23 | }, (error: any, response: any, body: any) => { 24 | if (!error && response.statusCode === 201) { 25 | return JSON.parse(body); 26 | } else { 27 | this.eventEmitter.fire('error', 'Failed to accept friend.' + error + "/" + JSON.stringify(response)); 28 | } 29 | }); 30 | } 31 | 32 | decline(skypeAccount: any, userName: any) { 33 | this.requestWithJar.put(Consts.SKYPEWEB_HTTPS + Consts.SKYPEWEB_API_SKYPE_HOST + '/users/self/contacts/auth-request/' + userName + '/decline', { 34 | headers: { 35 | 'X-Skypetoken': skypeAccount.skypeToken 36 | } 37 | }, (error: any, response: any, body: any) => { 38 | if (!error && response.statusCode === 201) { 39 | return JSON.parse(body); 40 | } else { 41 | this.eventEmitter.fire('error', 'Failed to decline friend.' + error + "/" + JSON.stringify(response)); 42 | } 43 | }); 44 | } 45 | } 46 | 47 | export default RequestService; 48 | -------------------------------------------------------------------------------- /dist/src/request_service.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var request = require("request"); 4 | var Consts = require("./consts"); 5 | var RequestService = (function () { 6 | function RequestService(cookieJar, eventEmitter) { 7 | this.requestWithJar = request.defaults({ jar: cookieJar }); 8 | this.eventEmitter = eventEmitter; 9 | } 10 | RequestService.prototype.accept = function (skypeAccount, userName) { 11 | var _this = this; 12 | this.requestWithJar.put(Consts.SKYPEWEB_HTTPS + Consts.SKYPEWEB_API_SKYPE_HOST + '/users/self/contacts/auth-request/' + userName + '/accept', { 13 | headers: { 14 | 'X-Skypetoken': skypeAccount.skypeToken 15 | } 16 | }, function (error, response, body) { 17 | if (!error && response.statusCode === 201) { 18 | return JSON.parse(body); 19 | } 20 | else { 21 | _this.eventEmitter.fire('error', 'Failed to accept friend.' + error + "/" + JSON.stringify(response)); 22 | } 23 | }); 24 | }; 25 | RequestService.prototype.decline = function (skypeAccount, userName) { 26 | var _this = this; 27 | this.requestWithJar.put(Consts.SKYPEWEB_HTTPS + Consts.SKYPEWEB_API_SKYPE_HOST + '/users/self/contacts/auth-request/' + userName + '/decline', { 28 | headers: { 29 | 'X-Skypetoken': skypeAccount.skypeToken 30 | } 31 | }, function (error, response, body) { 32 | if (!error && response.statusCode === 201) { 33 | return JSON.parse(body); 34 | } 35 | else { 36 | _this.eventEmitter.fire('error', 'Failed to decline friend.' + error + "/" + JSON.stringify(response)); 37 | } 38 | }); 39 | }; 40 | return RequestService; 41 | }()); 42 | exports.RequestService = RequestService; 43 | exports.default = RequestService; 44 | //# sourceMappingURL=request_service.js.map -------------------------------------------------------------------------------- /src/demo/demo.ts: -------------------------------------------------------------------------------- 1 | import Skyweb from '../skyweb'; 2 | 3 | var username = process.argv[2]; 4 | var password = process.argv[3]; 5 | if (!username || !password) { 6 | throw new Error('Username and password should be provided as commandline arguments!'); 7 | } 8 | 9 | var skyweb = new Skyweb(); 10 | skyweb.login(username, password).then((skypeAccount) => { 11 | console.log('Skyweb is initialized now'); 12 | console.log('Here is some info about you:' + JSON.stringify(skyweb.skypeAccount.selfInfo, null, 2)); 13 | console.log('Your contacts : ' + JSON.stringify(skyweb.contactsService.contacts, null, 2)); 14 | console.log('Going incognito.'); 15 | skyweb.setStatus('Hidden'); 16 | }).catch((reason: string) => { 17 | console.log(reason); 18 | }); 19 | /* 20 | 21 | authRequestCallback was removed because Skype web has moved to websockets for authRequests. 22 | 23 | skyweb.authRequestCallback = (requests) => { 24 | requests.forEach((request) => { 25 | skyweb.acceptAuthRequest(request.sender); 26 | skyweb.sendMessage("8:" + request.sender, "I accepted you!"); 27 | }); 28 | }; 29 | 30 | */ 31 | skyweb.messagesCallback = (messages) => { 32 | messages.forEach((message) => { 33 | if (message.resource.from.indexOf(username) === -1 && message.resource.messagetype !== 'Control/Typing' && message.resource.messagetype !== 'Control/ClearTyping') { 34 | var conversationLink = message.resource.conversationLink; 35 | var conversationId = conversationLink.substring(conversationLink.lastIndexOf('/') + 1); 36 | skyweb.sendMessage(conversationId, message.resource.content + '. Cats will rule the World'); 37 | } 38 | }); 39 | }; 40 | 41 | //error listening demo 42 | let errorCount = 0; 43 | const errorListener = (eventName: string, error: string) => { 44 | console.log(`${errorCount} : Error occured : ${error}`); 45 | errorCount++; 46 | if (errorCount === 10) { 47 | console.log(`Removing error listener`); 48 | skyweb.un('error', errorListener); 49 | } 50 | }; 51 | skyweb.on('error', errorListener); 52 | -------------------------------------------------------------------------------- /dist/src/polling/poll.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var request = require("request"); 4 | var Consts = require("./../consts"); 5 | var login_1 = require("../login"); 6 | var Poll = (function () { 7 | function Poll(cookieJar, eventEmitter) { 8 | this.requestWithJar = request.defaults({ jar: cookieJar }); 9 | this.eventEmitter = eventEmitter; 10 | this.cookieJar = cookieJar; 11 | } 12 | Poll.prototype.pollAll = function (skypeAccount, messagesCallback) { 13 | var _this = this; 14 | setTimeout(function () { 15 | _this.requestWithJar.post(Consts.SKYPEWEB_HTTPS + skypeAccount.messagesHost + '/v1/users/ME/endpoints/SELF/subscriptions/0/poll', { 16 | headers: { 17 | 'RegistrationToken': skypeAccount.registrationTokenParams.raw 18 | } 19 | }, function (error, response, body) { 20 | if (!error && response.statusCode === 200) { 21 | Poll.parsePollResult(JSON.parse(body), messagesCallback); 22 | } 23 | else if (body && body.errorCode === 729) { 24 | new login_1.Login(_this.cookieJar, _this.eventEmitter).doLogin(skypeAccount) 25 | .then(_this.pollAll.bind(_this, skypeAccount, messagesCallback)); 26 | return; 27 | } 28 | else { 29 | _this.eventEmitter.fire('error', 'Failed to poll messages.' + 30 | '.\n Error code: ' + (response && response.statusCode ? response.statusCode : 'none') + 31 | '.\n Error: ' + error + 32 | '.\n Body: ' + body); 33 | } 34 | _this.pollAll(skypeAccount, messagesCallback); 35 | }); 36 | }, 1000); 37 | }; 38 | Poll.parsePollResult = function (pollResult, messagesCallback) { 39 | if (pollResult.eventMessages) { 40 | var messages = pollResult.eventMessages.filter(function (item) { 41 | return item.resourceType === 'NewMessage'; 42 | }); 43 | if (messages.length) { 44 | messagesCallback(messages); 45 | } 46 | } 47 | }; 48 | return Poll; 49 | }()); 50 | exports.Poll = Poll; 51 | exports.default = Poll; 52 | //# sourceMappingURL=poll.js.map -------------------------------------------------------------------------------- /src/skype_account.ts: -------------------------------------------------------------------------------- 1 | import * as Consts from "./consts"; 2 | 3 | export interface RegistrationTokenParams { 4 | raw: string; 5 | registrationToken:string; 6 | expires: number; 7 | endpointId: string; 8 | } 9 | 10 | export interface SelfInfo { 11 | displayname: string; 12 | firstname: string; 13 | lastname: string; 14 | namespace: string; 15 | username: string 16 | } 17 | 18 | export class SkypeAccount { 19 | private _username:string; 20 | private _password:string; 21 | private _skypeToken:string; 22 | private _skypeTokenExpiresIn:number; 23 | 24 | private _messagesHost:string; 25 | 26 | private _registrationTokenParams:RegistrationTokenParams; 27 | private _selfInfo:SelfInfo; 28 | 29 | constructor(username:string, password:string) { 30 | this.username = username; 31 | this.password = password; 32 | 33 | this.messagesHost = Consts.SKYPEWEB_DEFAULT_MESSAGES_HOST; 34 | } 35 | 36 | set username(username:string) { 37 | this._username = username; 38 | } 39 | 40 | get username() { 41 | return this._username; 42 | } 43 | 44 | set password(password:string) { 45 | this._password = password; 46 | } 47 | 48 | get password() { 49 | return this._password; 50 | } 51 | 52 | set skypeToken(skypeToken:string) { 53 | this._skypeToken = skypeToken; 54 | } 55 | 56 | get skypeToken() { 57 | return this._skypeToken; 58 | } 59 | 60 | set skypeTokenExpiresIn(skypeTokenExpiresIn:number) { 61 | this._skypeTokenExpiresIn = skypeTokenExpiresIn; 62 | } 63 | 64 | get skypeTokenExpiresIn() { 65 | return this._skypeTokenExpiresIn; 66 | } 67 | 68 | set messagesHost(messagesHost:string) { 69 | this._messagesHost = messagesHost; 70 | } 71 | 72 | get messagesHost():string { 73 | return this._messagesHost; 74 | } 75 | 76 | set registrationTokenParams(registrationTokenParams:RegistrationTokenParams) { 77 | this._registrationTokenParams = registrationTokenParams; 78 | } 79 | 80 | get registrationTokenParams() { 81 | return this._registrationTokenParams; 82 | } 83 | 84 | set selfInfo(selfInfo:SelfInfo) { 85 | this._selfInfo = selfInfo; 86 | } 87 | 88 | get selfInfo() { 89 | return this._selfInfo; 90 | } 91 | } 92 | 93 | export default SkypeAccount; 94 | -------------------------------------------------------------------------------- /src/thread_service.ts: -------------------------------------------------------------------------------- 1 | import * as request from 'request'; 2 | import * as Consts from './consts'; 3 | import SkypeAccount from './skype_account'; 4 | import Utils from './utils'; 5 | import * as http from 'http'; 6 | import {CookieJar} from "request"; 7 | import {Promise} from "es6-promise"; 8 | import {EventEmitter} from "./utils"; 9 | 10 | export interface Member{ 11 | /** 12 | * Member id in format 8:tomriddle9154 if old skype account and 8:live:tomriddle9154 if live account 13 | */ 14 | id: string, 15 | /** 16 | * Role for this user in group. Note that you should probably add at least one 'Admin' to the group. 17 | */ 18 | role: 'User' | 'Admin' 19 | } 20 | 21 | export class ThreadService { 22 | private requestWithJar: any; 23 | private eventEmitter: EventEmitter; 24 | 25 | constructor(cookieJar:CookieJar, eventEmitter: EventEmitter) { 26 | this.requestWithJar = request.defaults({jar: cookieJar}); 27 | this.eventEmitter = eventEmitter; 28 | } 29 | /** 30 | * Creates thread (skype group) with provided members. You should include yourself as an Admin. 31 | * @return promise with thread id in format 19:0fe2w7d11fa649g99036e3sv39a52721@thread.skype 32 | */ 33 | create(skypeAccount:SkypeAccount, members:Member[]) : Promise { 34 | var promise = new Promise( (resolve,reject) => { 35 | var requestBody = JSON.stringify({ 36 | 'members': members || [] 37 | }); 38 | 39 | this.requestWithJar.post(Consts.SKYPEWEB_HTTPS + skypeAccount.messagesHost + '/v1/threads', { 40 | body: requestBody, 41 | headers: { 42 | 'RegistrationToken': skypeAccount.registrationTokenParams.raw 43 | } 44 | }, (error:any, response:http.IncomingMessage, body:any) => { 45 | if (!error && response.statusCode === 201) { 46 | var threadID = /threads\/(.*@thread.skype)/.exec( response.headers.location )[1]; 47 | resolve(threadID); 48 | } else { 49 | reject('Failed to create thread.' + 50 | '.\n Error code: ' + response.statusCode + 51 | '.\n Error: ' + error + 52 | '.\n Body: ' + body 53 | ); 54 | } 55 | }); 56 | 57 | }); 58 | 59 | return promise; 60 | } 61 | } 62 | 63 | export default ThreadService; 64 | -------------------------------------------------------------------------------- /dist/src/skyweb.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"skyweb.js","sourceRoot":"","sources":["../../src/skyweb.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /dist/src/message_service.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var request = require("request"); 4 | var Consts = require("./consts"); 5 | var MessageService = (function () { 6 | function MessageService(cookieJar, eventEmitter) { 7 | this.requestWithJar = request.defaults({ jar: cookieJar }); 8 | this.eventEmitter = eventEmitter; 9 | } 10 | MessageService.prototype.sendMessage = function (skypeAccount, conversationId, message, messagetype, contenttype) { 11 | var _this = this; 12 | var requestBody = JSON.stringify({ 13 | 'content': message, 14 | 'messagetype': messagetype || 'RichText', 15 | 'contenttype': contenttype || 'text' 16 | }); 17 | this.requestWithJar.post(Consts.SKYPEWEB_HTTPS + skypeAccount.messagesHost + '/v1/users/ME/conversations/' + conversationId + '/messages', { 18 | body: requestBody, 19 | headers: { 20 | 'RegistrationToken': skypeAccount.registrationTokenParams.raw 21 | } 22 | }, function (error, response, body) { 23 | if (!error && response.statusCode === 201) { 24 | } 25 | else { 26 | _this.eventEmitter.fire('error', 'Failed to send message.' + 27 | '.\n Error code: ' + response.statusCode + 28 | '.\n Error: ' + error + 29 | '.\n Body: ' + body); 30 | } 31 | }); 32 | }; 33 | MessageService.prototype.setTopic = function (skypeAccount, conversationId, message) { 34 | var _this = this; 35 | var requestBody = JSON.stringify({ 36 | 'topic': message 37 | }); 38 | this.requestWithJar.put(Consts.SKYPEWEB_HTTPS + skypeAccount.messagesHost + '/v1/threads/' + conversationId + '/properties?name=topic', { 39 | body: requestBody, 40 | headers: { 41 | 'RegistrationToken': skypeAccount.registrationTokenParams.raw 42 | } 43 | }, function (error, response, body) { 44 | if (!error && response.statusCode === 201) { 45 | } 46 | else { 47 | _this.eventEmitter.fire('error', 'Failed to send message.' + 48 | '.\n Error code: ' + response.statusCode + 49 | '.\n Error: ' + error + 50 | '.\n Body: ' + body); 51 | } 52 | }); 53 | }; 54 | return MessageService; 55 | }()); 56 | exports.MessageService = MessageService; 57 | exports.default = MessageService; 58 | //# sourceMappingURL=message_service.js.map -------------------------------------------------------------------------------- /src/polling/poll.ts: -------------------------------------------------------------------------------- 1 | import * as request from 'request'; 2 | import * as Consts from './../consts'; 3 | import SkypeAccount from './../skype_account'; 4 | import Utils from "./../utils"; 5 | import * as http from 'http'; 6 | import {CookieJar} from "request"; 7 | import {Login} from "../login"; 8 | import {EventEmitter} from "../utils"; 9 | 10 | export class Poll { 11 | private requestWithJar: any; 12 | private cookieJar:CookieJar; 13 | private eventEmitter: EventEmitter; 14 | 15 | constructor(cookieJar:CookieJar, eventEmitter: EventEmitter) { 16 | this.requestWithJar = request.defaults({jar: cookieJar}); 17 | this.eventEmitter = eventEmitter; 18 | this.cookieJar = cookieJar; 19 | } 20 | 21 | public pollAll(skypeAccount: SkypeAccount, messagesCallback:(messages:Array)=>void) { 22 | setTimeout(()=> { 23 | this.requestWithJar.post(Consts.SKYPEWEB_HTTPS + skypeAccount.messagesHost + '/v1/users/ME/endpoints/SELF/subscriptions/0/poll', { 24 | headers: { 25 | 'RegistrationToken': skypeAccount.registrationTokenParams.raw 26 | } 27 | }, (error:any, response:http.IncomingMessage, body:any) => { 28 | if (!error && response.statusCode === 200) { 29 | Poll.parsePollResult(JSON.parse(body), messagesCallback); 30 | } else if (body && body.errorCode === 729) { 31 | // statusCode: 404. 32 | // body: {"errorCode":729,"message":"You must create an endpoint before performing this operation."} 33 | new Login(this.cookieJar, this.eventEmitter).doLogin(skypeAccount) 34 | .then(this.pollAll.bind(this, skypeAccount, messagesCallback)); 35 | return; 36 | } else { 37 | this.eventEmitter.fire('error', 'Failed to poll messages.' + 38 | '.\n Error code: ' + (response && response.statusCode ? response.statusCode : 'none') + 39 | '.\n Error: ' + error + 40 | '.\n Body: ' + body 41 | ); 42 | } 43 | this.pollAll(skypeAccount, messagesCallback); 44 | }); 45 | }, 1000); 46 | } 47 | 48 | private static parsePollResult(pollResult:any, messagesCallback:(messages:Array)=>void) { 49 | if (pollResult.eventMessages) { 50 | var messages = pollResult.eventMessages.filter((item: any) => { 51 | return item.resourceType === 'NewMessage'; //Fixme there are a lot more EventMessage's types! 52 | }); 53 | if (messages.length) { 54 | messagesCallback(messages); 55 | } 56 | } 57 | } 58 | } 59 | 60 | export default Poll; 61 | -------------------------------------------------------------------------------- /dist/src/skype_account.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var Consts = require("./consts"); 4 | var SkypeAccount = (function () { 5 | function SkypeAccount(username, password) { 6 | this.username = username; 7 | this.password = password; 8 | this.messagesHost = Consts.SKYPEWEB_DEFAULT_MESSAGES_HOST; 9 | } 10 | Object.defineProperty(SkypeAccount.prototype, "username", { 11 | get: function () { 12 | return this._username; 13 | }, 14 | set: function (username) { 15 | this._username = username; 16 | }, 17 | enumerable: true, 18 | configurable: true 19 | }); 20 | Object.defineProperty(SkypeAccount.prototype, "password", { 21 | get: function () { 22 | return this._password; 23 | }, 24 | set: function (password) { 25 | this._password = password; 26 | }, 27 | enumerable: true, 28 | configurable: true 29 | }); 30 | Object.defineProperty(SkypeAccount.prototype, "skypeToken", { 31 | get: function () { 32 | return this._skypeToken; 33 | }, 34 | set: function (skypeToken) { 35 | this._skypeToken = skypeToken; 36 | }, 37 | enumerable: true, 38 | configurable: true 39 | }); 40 | Object.defineProperty(SkypeAccount.prototype, "skypeTokenExpiresIn", { 41 | get: function () { 42 | return this._skypeTokenExpiresIn; 43 | }, 44 | set: function (skypeTokenExpiresIn) { 45 | this._skypeTokenExpiresIn = skypeTokenExpiresIn; 46 | }, 47 | enumerable: true, 48 | configurable: true 49 | }); 50 | Object.defineProperty(SkypeAccount.prototype, "messagesHost", { 51 | get: function () { 52 | return this._messagesHost; 53 | }, 54 | set: function (messagesHost) { 55 | this._messagesHost = messagesHost; 56 | }, 57 | enumerable: true, 58 | configurable: true 59 | }); 60 | Object.defineProperty(SkypeAccount.prototype, "registrationTokenParams", { 61 | get: function () { 62 | return this._registrationTokenParams; 63 | }, 64 | set: function (registrationTokenParams) { 65 | this._registrationTokenParams = registrationTokenParams; 66 | }, 67 | enumerable: true, 68 | configurable: true 69 | }); 70 | Object.defineProperty(SkypeAccount.prototype, "selfInfo", { 71 | get: function () { 72 | return this._selfInfo; 73 | }, 74 | set: function (selfInfo) { 75 | this._selfInfo = selfInfo; 76 | }, 77 | enumerable: true, 78 | configurable: true 79 | }); 80 | return SkypeAccount; 81 | }()); 82 | exports.SkypeAccount = SkypeAccount; 83 | exports.default = SkypeAccount; 84 | //# sourceMappingURL=skype_account.js.map -------------------------------------------------------------------------------- /src/message_service.ts: -------------------------------------------------------------------------------- 1 | import * as request from 'request'; 2 | import * as Consts from './consts'; 3 | import SkypeAccount from './skype_account'; 4 | import Utils from './utils'; 5 | import * as http from 'http'; 6 | import {CookieJar} from "request"; 7 | import {EventEmitter} from "./utils"; 8 | 9 | export class MessageService { 10 | private requestWithJar: any; 11 | private eventEmitter: EventEmitter; 12 | 13 | constructor(cookieJar:CookieJar, eventEmitter: EventEmitter) { 14 | this.requestWithJar = request.defaults({jar: cookieJar}); 15 | this.eventEmitter = eventEmitter; 16 | } 17 | 18 | public sendMessage(skypeAccount:SkypeAccount, conversationId:string, message:string, messagetype?:string, contenttype?:string) { 19 | var requestBody = JSON.stringify({ 20 | ///'clientmessageid': Utils.getCurrentTime() + '', //fixme looks like we don't need this?(at least if we don't want to 21 | // have the ability to modify text(content) of the message.) 22 | 'content': message, 23 | 'messagetype': messagetype || 'RichText', 24 | 'contenttype': contenttype || 'text' 25 | }); 26 | this.requestWithJar.post(Consts.SKYPEWEB_HTTPS + skypeAccount.messagesHost + '/v1/users/ME/conversations/' + conversationId + '/messages', { 27 | body: requestBody, 28 | headers: { 29 | 'RegistrationToken': skypeAccount.registrationTokenParams.raw 30 | } 31 | }, (error:any, response:http.IncomingMessage, body:any) => { 32 | if (!error && response.statusCode === 201) { 33 | //fixme? send success callback? 34 | } else { 35 | this.eventEmitter.fire('error', 'Failed to send message.' + 36 | '.\n Error code: ' + response.statusCode + 37 | '.\n Error: ' + error + 38 | '.\n Body: ' + body 39 | ); 40 | } 41 | }); 42 | } 43 | public setTopic(skypeAccount:SkypeAccount, conversationId:string, message:string) { 44 | var requestBody = JSON.stringify({ 45 | 'topic': message 46 | }); 47 | this.requestWithJar.put(Consts.SKYPEWEB_HTTPS + skypeAccount.messagesHost + '/v1/threads/' + conversationId + '/properties?name=topic', { 48 | body: requestBody, 49 | headers: { 50 | 'RegistrationToken': skypeAccount.registrationTokenParams.raw 51 | } 52 | }, (error:any, response:http.IncomingMessage, body:any) => { 53 | if (!error && response.statusCode === 201) { 54 | } else { 55 | this.eventEmitter.fire('error', 'Failed to send message.' + 56 | '.\n Error code: ' + response.statusCode + 57 | '.\n Error: ' + error + 58 | '.\n Body: ' + body 59 | ); 60 | } 61 | }); 62 | } 63 | } 64 | 65 | export default MessageService; 66 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Skyweb 2 | Unofficial Skype API for nodejs via 'Skype (HTTP)' protocol. 3 | 4 | If you want to create a bot, take a look at https://github.com/Microsoft/BotBuilder first.👌 5 | 6 | ## Running example 7 | As username and password you should use your Skype account or your Microsoft account. 8 | ```sh 9 | git clone https://github.com/ShyykoSerhiy/skyweb.git 10 | cd skyweb 11 | npm install 12 | cd dist/demo 13 | node demo.js username password 14 | ``` 15 | After 'Skyweb is initialized now' appears in console any message you receive in your Skype will be automatically replied. 16 | 17 | ## Usage 18 | ### Initializing and login 19 | ```js 20 | Skyweb = require('skyweb'); 21 | var skyweb = new Skyweb.default(); 22 | skyweb.login(username, password).then(function (skypeAccount) { 23 | console.log('Skyweb is initialized now'); 24 | }); 25 | ``` 26 | 27 | ### Keeping track of errors 28 | 29 | Because the whole lib is quite volatile it's may be a good idea to keep track of errors that might 30 | occur while requests being made. This is the place where you might try to relogin or to terminate the process. 31 | 32 | ```js 33 | Skyweb = require('skyweb'); 34 | var skyweb = new Skyweb.default(); 35 | const errorListener = (eventName: string, error: string) => { 36 | console.log(`${errorCount} : Error occured : ${error}`); 37 | errorCount++; 38 | if (errorCount === 10) { 39 | console.log(`Removing error listener`); 40 | skyweb.un('error', errorListener); // Removing error listener 41 | } 42 | }; 43 | skyweb.on('error', errorListener); //Adding error listener 44 | ``` 45 | 46 | ### Getting contacts info 47 | ```js 48 | var skyweb = new Skyweb.default(); 49 | skyweb.login(username, password).then((skypeAccount) => { 50 | console.log('Your contacts : ' + JSON.stringify(skyweb.contactsService.contacts, null, 2)); 51 | }); 52 | ``` 53 | 54 | ### Setting status 55 | ```js 56 | var skyweb = new Skyweb.default(); 57 | skyweb.login(username, password).then((skypeAccount) => { 58 | skyweb.setStatus('Hidden'); //Now everybody thinks I'm sleeping 59 | }); 60 | ``` 61 | Currently supported values are : "Hidden" | "Online" | "Away" | "Busy" 62 | 63 | ### Creating thread(Skype group) 64 | ```js 65 | var skyweb = new Skyweb.default(); 66 | skyweb.login(username, password).then((skypeAccount) => { 67 | skyweb.createThread([{"id":"8:someuserid","role":"User"},{"id":"8:live:someliveuserid","role":"User"},{"id":"8:youruserid","role":"Admin"}]); 68 | }); 69 | ``` 70 | It's probably a good idea to include at least one user with Admin role in new thread(at least you should have Admin role). 71 | 72 | ## What's not working and probably never will. 73 | * [Old P2P group chats](https://github.com/ShyykoSerhiy/skyweb/issues/6). According to [Skype community site ](http://community.skype.com/t5/Skype-for-Web-Beta/Group-chats-missing-on-skype-web/td-p/3884218) only new, Cloud based group chats are shown in SkypeWeb Beta(therefore works in this API). The old P2P group chats are not. 74 | 75 | ## Disclaimer 76 | This project relies on SkypeWeb Skype implementation. If Microsoft Corporation decides to remove Skype 77 | implementation (or change it in any) skyweb might not be in working state. Therefore it's not recommended to use it 78 | in any critical part of production code. In fact it's not recommended to use it in production at all. 79 | 80 | [MIT License](https://github.com/ShyykoSerhiy/skyweb/blob/master/LICENSE.md). 81 | 82 | -------------------------------------------------------------------------------- /dist/src/skyweb.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var skype_account_1 = require("./skype_account"); 4 | var contacts_service_1 = require("./contacts_service"); 5 | var request = require("request"); 6 | var login_1 = require("./login"); 7 | var poll_1 = require("./polling/poll"); 8 | var message_service_1 = require("./message_service"); 9 | var status_service_1 = require("./status_service"); 10 | var request_service_1 = require("./request_service"); 11 | var thread_service_1 = require("./thread_service"); 12 | var es6_promise_1 = require("es6-promise"); 13 | var utils_1 = require("./utils"); 14 | var Skyweb = (function () { 15 | function Skyweb() { 16 | this.cookieJar = request.jar(); 17 | this.eventEmitter = new utils_1.EventEmitter(); 18 | this.contactsService = new contacts_service_1.default(this.cookieJar, this.eventEmitter); 19 | this.messageService = new message_service_1.default(this.cookieJar, this.eventEmitter); 20 | this.requestService = new request_service_1.default(this.cookieJar, this.eventEmitter); 21 | this.statusService = new status_service_1.default(this.cookieJar, this.eventEmitter); 22 | this.requestService = new request_service_1.default(this.cookieJar, this.eventEmitter); 23 | this.threadService = new thread_service_1.default(this.cookieJar, this.eventEmitter); 24 | } 25 | Skyweb.prototype.login = function (username, password) { 26 | var _this = this; 27 | this.skypeAccount = new skype_account_1.default(username, password); 28 | return new login_1.default(this.cookieJar, this.eventEmitter).doLogin(this.skypeAccount).then(function (skypeAccount) { 29 | return new es6_promise_1.Promise(_this.contactsService.loadContacts.bind(_this.contactsService, skypeAccount)); 30 | }).then(function (skypeAccount) { 31 | new poll_1.default(_this.cookieJar, _this.eventEmitter).pollAll(skypeAccount, function (messages) { 32 | if (_this.messagesCallback) { 33 | _this.messagesCallback(messages); 34 | } 35 | }); 36 | return skypeAccount; 37 | }); 38 | }; 39 | Skyweb.prototype.sendMessage = function (conversationId, message, messagetype, contenttype) { 40 | this.messageService.sendMessage(this.skypeAccount, conversationId, message, messagetype, contenttype); 41 | }; 42 | Skyweb.prototype.setTopic = function (conversationId, message) { 43 | this.messageService.setTopic(this.skypeAccount, conversationId, message); 44 | }; 45 | Skyweb.prototype.setStatus = function (status) { 46 | this.statusService.setStatus(this.skypeAccount, status); 47 | }; 48 | Skyweb.prototype.acceptAuthRequest = function (username) { 49 | return this.requestService.accept(this.skypeAccount, username); 50 | }; 51 | Skyweb.prototype.declineAuthRequest = function (username) { 52 | return this.requestService.decline(this.skypeAccount, username); 53 | }; 54 | Skyweb.prototype.createThread = function (members) { 55 | return this.threadService.create(this.skypeAccount, members); 56 | }; 57 | Skyweb.prototype.on = function (eventName, listener) { 58 | this.eventEmitter.on(eventName, listener); 59 | }; 60 | Skyweb.prototype.un = function (eventName, listener) { 61 | this.eventEmitter.un(eventName, listener); 62 | }; 63 | return Skyweb; 64 | }()); 65 | exports.default = Skyweb; 66 | //# sourceMappingURL=skyweb.js.map -------------------------------------------------------------------------------- /src/skyweb.ts: -------------------------------------------------------------------------------- 1 | import SkypeAccount from './skype_account'; 2 | import ContactsService from './contacts_service'; 3 | import * as request from 'request'; 4 | import { CookieJar } from "request"; 5 | import Login from "./login"; 6 | import Poll from "./polling/poll"; 7 | import MessageService from "./message_service"; 8 | import StatusService from "./status_service"; 9 | import AuthRequest from "./polling/auth_request"; 10 | import RequestService from "./request_service"; 11 | import ThreadService from "./thread_service"; 12 | import Status from "./status/status"; 13 | import { Promise } from "es6-promise"; 14 | import { Member } from "./thread_service"; 15 | import { EventEmitter } from "./utils"; 16 | 17 | export default class Skyweb { 18 | public messagesCallback: (messages: Array) => void; 19 | public skypeAccount: SkypeAccount; 20 | public contactsService: ContactsService; 21 | private messageService: MessageService; 22 | private requestService: RequestService; 23 | private statusService: StatusService; 24 | private eventEmitter: EventEmitter; 25 | public threadService: ThreadService; 26 | /** 27 | * CookieJar that is used for this Skyweb instance 28 | */ 29 | private cookieJar: CookieJar; 30 | 31 | constructor() { 32 | this.cookieJar = request.jar(); 33 | this.eventEmitter = new EventEmitter(); 34 | this.contactsService = new ContactsService(this.cookieJar, this.eventEmitter); 35 | this.messageService = new MessageService(this.cookieJar, this.eventEmitter); 36 | this.requestService = new RequestService(this.cookieJar, this.eventEmitter); 37 | this.statusService = new StatusService(this.cookieJar, this.eventEmitter); 38 | this.requestService = new RequestService(this.cookieJar, this.eventEmitter); 39 | this.threadService = new ThreadService(this.cookieJar, this.eventEmitter); 40 | } 41 | 42 | login(username: any, password: any): Promise<{}> { 43 | this.skypeAccount = new SkypeAccount(username, password); 44 | return new Login(this.cookieJar, this.eventEmitter).doLogin(this.skypeAccount).then((skypeAccount: SkypeAccount) => { 45 | return new Promise(this.contactsService.loadContacts.bind(this.contactsService, skypeAccount)); 46 | }).then((skypeAccount: SkypeAccount) => { 47 | new Poll(this.cookieJar, this.eventEmitter).pollAll(skypeAccount, (messages: Array) => { 48 | if (this.messagesCallback) { 49 | this.messagesCallback(messages); 50 | } 51 | }); 52 | return skypeAccount; 53 | }); 54 | } 55 | 56 | sendMessage(conversationId: string, message: string, messagetype?: string, contenttype?: string) { 57 | this.messageService.sendMessage(this.skypeAccount, conversationId, message, messagetype, contenttype); 58 | } 59 | 60 | setTopic(conversationId: string, message: string) { 61 | this.messageService.setTopic(this.skypeAccount, conversationId, message); 62 | } 63 | setStatus(status: Status) { 64 | this.statusService.setStatus(this.skypeAccount, status); 65 | } 66 | 67 | acceptAuthRequest(username: any) { 68 | return this.requestService.accept(this.skypeAccount, username); 69 | } 70 | 71 | declineAuthRequest(username: any) { 72 | return this.requestService.decline(this.skypeAccount, username); 73 | } 74 | 75 | createThread(members: Member[]): Promise { 76 | return this.threadService.create(this.skypeAccount, members); 77 | } 78 | 79 | on(eventName: string, listener: (eventName: string, content: any) => void) { 80 | this.eventEmitter.on(eventName, listener); 81 | } 82 | 83 | un(eventName: string, listener: (eventName: string, content: any) => void) { 84 | this.eventEmitter.un(eventName, listener); 85 | } 86 | } -------------------------------------------------------------------------------- /dist/src/login.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/login.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /dist/src/utils.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var sha256 = require("js-sha256"); 4 | var bigInt = require("big-integer"); 5 | var EventEmitter = (function () { 6 | function EventEmitter() { 7 | this._eventListeners = { 'error': [] }; 8 | } 9 | EventEmitter.prototype.on = function (eventName, listener) { 10 | var listeners = this._eventListeners[eventName]; 11 | if (typeof listeners === 'undefined') { 12 | listeners = []; 13 | this._eventListeners[eventName] = listeners; 14 | } 15 | listeners.push(listener); 16 | }; 17 | EventEmitter.prototype.un = function (eventName, listener) { 18 | var listeners = this._eventListeners[eventName]; 19 | if (!listeners) { 20 | return; 21 | } 22 | var index = listeners.indexOf(listener); 23 | ~index && listeners.splice(index, 1); 24 | !listeners.length && delete this._eventListeners[eventName]; 25 | }; 26 | EventEmitter.prototype.fire = function (eventName, content) { 27 | this._eventListeners[eventName] && this._eventListeners[eventName].forEach(function (listener) { listener(eventName, content); }); 28 | }; 29 | return EventEmitter; 30 | }()); 31 | exports.EventEmitter = EventEmitter; 32 | var Utils = (function () { 33 | function Utils() { 34 | } 35 | Utils.getCurrentTime = function () { 36 | return Math.floor(new Date().getTime()) / 1000; 37 | }; 38 | Utils.getTimezone = function () { 39 | var pad = function (n, c) { 40 | if ((n = n + "").length < c) { 41 | return new Array(++c - n.length).join("0") + n; 42 | } 43 | else { 44 | return n; 45 | } 46 | }; 47 | var sign; 48 | var timezone = new Date().getTimezoneOffset() * (-1); 49 | if (timezone >= 0) { 50 | sign = "+"; 51 | } 52 | else { 53 | sign = "-"; 54 | } 55 | timezone = Math.abs(timezone); 56 | var minutes = timezone % 60; 57 | var hours = (timezone - minutes) / 60; 58 | minutes = pad(minutes, 2); 59 | hours = pad(hours, 2); 60 | return sign + hours + "|" + minutes; 61 | }; 62 | Utils.getMac256Hash = function (challenge, appId, key) { 63 | function padRight(original, totalWidth, ch) { 64 | function stringFromChar(ch, count) { 65 | var s = ch; 66 | for (var i = 1; i < count; i++) { 67 | s += ch; 68 | } 69 | return s; 70 | } 71 | if (original.length < totalWidth) { 72 | ch = ch || ' '; 73 | return original + stringFromChar(ch, totalWidth - original.length); 74 | } 75 | return original.valueOf(); 76 | } 77 | function parseHexInt(s) { 78 | var result = parseInt(s, 16); 79 | if (isNaN(result)) { 80 | return 0; 81 | } 82 | return result; 83 | } 84 | function int32ToHexString(n) { 85 | var hexChars = '0123456789abcdef'; 86 | var hexString = ''; 87 | for (var i = 0; i <= 3; i++) { 88 | hexString += hexChars.charAt((n >> (i * 8 + 4)) & 15); 89 | hexString += hexChars.charAt((n >> (i * 8)) & 15); 90 | } 91 | return hexString; 92 | } 93 | function int64Xor(a, b) { 94 | var sA = a.toString(2); 95 | var sB = b.toString(2); 96 | var sC = ''; 97 | var sD = ''; 98 | var diff = Math.abs(sA.length - sB.length); 99 | var i; 100 | for (i = 0; i < diff; i++) { 101 | sD += '0'; 102 | } 103 | if (sA.length < sB.length) { 104 | sD += sA; 105 | sA = sD; 106 | } 107 | else if (sB.length < sA.length) { 108 | sD += sB; 109 | sB = sD; 110 | } 111 | for (i = 0; i < sA.length; i++) { 112 | sC += (sA.charAt(i) === sB.charAt(i)) ? '0' : '1'; 113 | } 114 | return parseInt(sC.toString(), 2); 115 | } 116 | function cS64_C(pdwData, pInHash, pOutHash) { 117 | var MODULUS = 2147483647; 118 | if ((pdwData.length < 2) || ((pdwData.length & 1) === 1)) { 119 | return false; 120 | } 121 | var ulCS64_a = pInHash[0] & MODULUS; 122 | var ulCS64_b = pInHash[1] & MODULUS; 123 | var ulCS64_c = pInHash[2] & MODULUS; 124 | var ulCS64_d = pInHash[3] & MODULUS; 125 | var ulCS64_e = 242854337; 126 | var CS64_a = bigInt(ulCS64_a.toString()); 127 | var CS64_b = bigInt(ulCS64_b.toString()); 128 | var CS64_c = bigInt(ulCS64_c.toString()); 129 | var CS64_d = bigInt(ulCS64_d.toString()); 130 | var CS64_e = bigInt(ulCS64_e.toString()); 131 | var pos = 0; 132 | var mod = bigInt(MODULUS.toString()); 133 | var qwDatum = bigInt('0'); 134 | var qwMAC = bigInt('0'); 135 | var qwSum = bigInt('0'); 136 | for (var i = 0; i < pdwData.length / 2; i++) { 137 | qwDatum = bigInt(pdwData[pos++].toString()); 138 | qwDatum.multiply(CS64_e); 139 | qwDatum.mod(mod); 140 | qwMAC.add(qwDatum); 141 | qwMAC.multiply(CS64_a); 142 | qwMAC.add(CS64_b); 143 | qwMAC.mod(mod); 144 | qwSum.add(qwMAC); 145 | qwMAC.add(bigInt(pdwData[pos++].toString())); 146 | qwMAC.multiply(CS64_c); 147 | qwMAC.add(CS64_d); 148 | qwMAC.mod(mod); 149 | qwSum.add(qwMAC); 150 | } 151 | qwMAC.add(CS64_b); 152 | qwMAC.mod(mod); 153 | qwSum.add(CS64_d); 154 | qwSum.mod(mod); 155 | pOutHash[0] = parseInt(qwMAC.toString(10), 10); 156 | pOutHash[1] = parseInt(qwSum.toString(10), 10); 157 | return true; 158 | } 159 | var clearText = challenge + appId; 160 | var remaining = 8 - (clearText.length % 8); 161 | if (remaining !== 8) { 162 | clearText = padRight(clearText, clearText.length + remaining, '0'); 163 | } 164 | var cchClearText = clearText.length / 4; 165 | var pClearText = []; 166 | var i; 167 | var pos; 168 | for (i = 0, pos = 0; i < cchClearText; i++) { 169 | pClearText.splice(i, 0, 0); 170 | pClearText[i] = pClearText[i] + clearText.charCodeAt(pos++) * 1; 171 | pClearText[i] = pClearText[i] + clearText.charCodeAt(pos++) * 256; 172 | pClearText[i] = pClearText[i] + clearText.charCodeAt(pos++) * 65536; 173 | pClearText[i] = pClearText[i] + clearText.charCodeAt(pos++) * 16777216; 174 | } 175 | var sha256Hash = new Array(4); 176 | var hash = sha256.sha256(challenge + key).toUpperCase(); 177 | for (i = 0, pos = 0; i < sha256Hash.length; i++) { 178 | sha256Hash[i] = 0; 179 | sha256Hash[i] += parseHexInt(hash.substr(pos, 2)) * 1; 180 | pos += 2; 181 | sha256Hash[i] += parseHexInt(hash.substr(pos, 2)) * 256; 182 | pos += 2; 183 | sha256Hash[i] += parseHexInt(hash.substr(pos, 2)) * 65536; 184 | pos += 2; 185 | sha256Hash[i] += parseHexInt(hash.substr(pos, 2)) * 16777216; 186 | pos += 2; 187 | } 188 | var macHash = new Array(2); 189 | cS64_C(pClearText, sha256Hash, macHash); 190 | var a = int64Xor(sha256Hash[0], macHash[0]); 191 | var b = int64Xor(sha256Hash[1], macHash[1]); 192 | var c = int64Xor(sha256Hash[2], macHash[0]); 193 | var d = int64Xor(sha256Hash[3], macHash[1]); 194 | return int32ToHexString(a) + int32ToHexString(b) + int32ToHexString(c) + int32ToHexString(d); 195 | }; 196 | return Utils; 197 | }()); 198 | exports.Utils = Utils; 199 | exports.default = Utils; 200 | //# sourceMappingURL=utils.js.map -------------------------------------------------------------------------------- /dist/src/utils.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":";;AAAA,kCAAoC;AACpC,oCAAsC;AAEtC;IAMI;QACI,IAAI,CAAC,eAAe,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IAC3C,CAAC;IAEM,yBAAE,GAAT,UAAU,SAAiB,EAAE,QAAmD;QAC5E,IAAI,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;QAChD,EAAE,CAAC,CAAC,OAAO,SAAS,KAAK,WAAW,CAAC,CAAC,CAAC;YACnC,SAAS,GAAG,EAAE,CAAC;YACf,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC;QAChD,CAAC;QACD,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC7B,CAAC;IAEM,yBAAE,GAAT,UAAU,SAAiB,EAAE,QAAmD;QAC5E,IAAI,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;QAChD,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA,CAAC;YACZ,MAAM,CAAC;QACX,CAAC;QACD,IAAM,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC1C,CAAC,KAAK,IAAI,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QACrC,CAAC,SAAS,CAAC,MAAM,IAAI,OAAO,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;IAChE,CAAC;IAEM,2BAAI,GAAX,UAAY,SAAiB,EAAE,OAAY;QACvC,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,UAAC,QAAQ,IAAO,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA,CAAC,CAAC,CAAC,CAAC;IAC/H,CAAC;IACL,mBAAC;AAAD,CAAC,AAhCD,IAgCC;AAhCY,oCAAY;AAkCzB;IAAA;IAyLA,CAAC;IAxLU,oBAAc,GAArB;QACI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC;IACnD,CAAC;IAEM,iBAAW,GAAlB;QACI,IAAI,GAAG,GAAG,UAAU,CAAM,EAAE,CAAM;YAC9B,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;gBAC1B,MAAM,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACnD,CAAC;YAAC,IAAI,CAAC,CAAC;gBACJ,MAAM,CAAC,CAAC,CAAC;YACb,CAAC;QACL,CAAC,CAAC;QACF,IAAI,IAAS,CAAC;QACd,IAAI,QAAQ,GAAG,IAAI,IAAI,EAAE,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACrD,EAAE,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC;YAChB,IAAI,GAAG,GAAG,CAAC;QACf,CAAC;QAAC,IAAI,CAAC,CAAC;YACJ,IAAI,GAAG,GAAG,CAAC;QACf,CAAC;QAED,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC9B,IAAI,OAAO,GAAG,QAAQ,GAAG,EAAE,CAAC;QAC5B,IAAI,KAAK,GAAG,CAAC,QAAQ,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;QACtC,OAAO,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAC1B,KAAK,GAAG,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAEtB,MAAM,CAAC,IAAI,GAAG,KAAK,GAAG,GAAG,GAAG,OAAO,CAAC;IACxC,CAAC;IAEM,mBAAa,GAApB,UAAqB,SAAc,EAAE,KAAU,EAAE,GAAQ;QACrD,kBAAkB,QAAa,EAAE,UAAe,EAAE,EAAO;YACrD,wBAAwB,EAAO,EAAE,KAAU;gBACvC,IAAI,CAAC,GAAG,EAAE,CAAC;gBACX,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC7B,CAAC,IAAI,EAAE,CAAC;gBACZ,CAAC;gBACD,MAAM,CAAC,CAAC,CAAC;YACb,CAAC;YAED,EAAE,CAAC,CAAC,QAAQ,CAAC,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC;gBAC/B,EAAE,GAAG,EAAE,IAAI,GAAG,CAAC;gBACf,MAAM,CAAC,QAAQ,GAAG,cAAc,CAAC,EAAE,EAAE,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;YACvE,CAAC;YACD,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;QAC9B,CAAC;QAED,qBAAqB,CAAS;YAC1B,IAAI,MAAM,GAAG,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC7B,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;gBAChB,MAAM,CAAC,CAAC,CAAC;YACb,CAAC;YACD,MAAM,CAAC,MAAM,CAAC;QAClB,CAAC;QAED,0BAA0B,CAAS;YAC/B,IAAI,QAAQ,GAAG,kBAAkB,CAAC;YAClC,IAAI,SAAS,GAAG,EAAE,CAAC;YACnB,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC1B,SAAS,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;gBACtD,SAAS,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YACtD,CAAC;YAED,MAAM,CAAC,SAAS,CAAC;QACrB,CAAC;QAED,kBAAkB,CAAS,EAAE,CAAS;YAClC,IAAI,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YACvB,IAAI,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YACvB,IAAI,EAAE,GAAG,EAAE,CAAC;YACZ,IAAI,EAAE,GAAG,EAAE,CAAC;YACZ,IAAI,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC;YAC3C,IAAI,CAAM,CAAC;YAEX,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;gBACxB,EAAE,IAAI,GAAG,CAAC;YACd,CAAC;YAED,EAAE,CAAC,CAAC,EAAE,CAAC,MAAM,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;gBACxB,EAAE,IAAI,EAAE,CAAC;gBACT,EAAE,GAAG,EAAE,CAAC;YACZ,CAAC;YACD,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,MAAM,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;gBAC7B,EAAE,IAAI,EAAE,CAAC;gBACT,EAAE,GAAG,EAAE,CAAC;YACZ,CAAC;YAED,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC7B,EAAE,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;YACtD,CAAC;YAED,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC;QACtC,CAAC;QAED,gBAAgB,OAAsB,EAAE,OAAsB,EAAE,QAAuB;YACnF,IAAI,OAAO,GAAG,UAAU,CAAC;YACzB,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBACvD,MAAM,CAAC,KAAK,CAAC;YACjB,CAAC;YAED,IAAI,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;YACpC,IAAI,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;YACpC,IAAI,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;YACpC,IAAI,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;YACpC,IAAI,QAAQ,GAAG,SAAS,CAAC;YAEzB,IAAI,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;YACzC,IAAI,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;YACzC,IAAI,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;YACzC,IAAI,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;YACzC,IAAI,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;YAEzC,IAAI,GAAG,GAAG,CAAC,CAAC;YACZ,IAAI,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;YACrC,IAAI,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;YAC1B,IAAI,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;YACxB,IAAI,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;YAExB,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC1C,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAC5C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;gBACzB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBACjB,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBACnB,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;gBACvB,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBAClB,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBACf,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;gBACjB,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;gBAC7C,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;gBACvB,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBAClB,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBACf,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACrB,CAAC;YAED,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAClB,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACf,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAClB,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACf,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;YAC/C,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;YAE/C,MAAM,CAAC,IAAI,CAAC;QAChB,CAAC;QAED,IAAI,SAAS,GAAG,SAAS,GAAG,KAAK,CAAC;QAClC,IAAI,SAAS,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC3C,EAAE,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC;YAClB,SAAS,GAAG,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,EAAE,GAAG,CAAC,CAAC;QACvE,CAAC;QAED,IAAI,YAAY,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;QACxC,IAAI,UAAU,GAAU,EAAE,CAAC;QAC3B,IAAI,CAAM,CAAC;QACX,IAAI,GAAQ,CAAC;QACb,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YAC3B,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;YAChE,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC;YAClE,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,GAAG,KAAK,CAAC;YACpE,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,GAAG,QAAQ,CAAC;QAC3E,CAAC;QAED,IAAI,UAAU,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC;QAC9B,IAAI,IAAI,GAAW,MAAM,CAAC,MAAM,CAAC,SAAS,GAAG,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;QAChE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC9C,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YAClB,UAAU,CAAC,CAAC,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YACtD,GAAG,IAAI,CAAC,CAAC;YACT,UAAU,CAAC,CAAC,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;YACxD,GAAG,IAAI,CAAC,CAAC;YACT,UAAU,CAAC,CAAC,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;YAC1D,GAAG,IAAI,CAAC,CAAC;YACT,UAAU,CAAC,CAAC,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;YAC7D,GAAG,IAAI,CAAC,CAAC;QACb,CAAC;QAED,IAAI,OAAO,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC;QAC3B,MAAM,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;QACxC,IAAI,CAAC,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5C,IAAI,CAAC,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5C,IAAI,CAAC,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5C,IAAI,CAAC,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QAE5C,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC;IACjG,CAAC;IACL,YAAC;AAAD,CAAC,AAzLD,IAyLC;AAzLY,sBAAK;AA2LlB,kBAAe,KAAK,CAAC"} -------------------------------------------------------------------------------- /src/utils.ts: -------------------------------------------------------------------------------- 1 | import * as sha256 from "js-sha256"; 2 | import * as bigInt from "big-integer"; 3 | 4 | export class EventEmitter { 5 | private _eventListeners: { 6 | 'error': ((error: 'error', reason: string) => void)[], 7 | [key: string]: ((eventName: string, data: any) => void)[]; 8 | }; 9 | 10 | public constructor() { 11 | this._eventListeners = { 'error': [] }; 12 | } 13 | 14 | public on(eventName: string, listener: (eventName: string, content: any) => void) { 15 | let listeners = this._eventListeners[eventName]; 16 | if (typeof listeners === 'undefined') { 17 | listeners = []; 18 | this._eventListeners[eventName] = listeners; 19 | } 20 | listeners.push(listener); 21 | } 22 | 23 | public un(eventName: string, listener: (eventName: string, content: any) => void) { 24 | let listeners = this._eventListeners[eventName]; 25 | if (!listeners){ 26 | return; 27 | } 28 | const index = listeners.indexOf(listener); 29 | ~index && listeners.splice(index, 1); 30 | !listeners.length && delete this._eventListeners[eventName]; 31 | } 32 | 33 | public fire(eventName: string, content: any) { 34 | this._eventListeners[eventName] && this._eventListeners[eventName].forEach((listener) => { listener(eventName, content) }); 35 | } 36 | } 37 | 38 | export class Utils { 39 | static getCurrentTime() { 40 | return Math.floor(new Date().getTime()) / 1000; 41 | } 42 | 43 | static getTimezone() { 44 | var pad = function (n: any, c: any) { 45 | if ((n = n + "").length < c) { 46 | return new Array(++c - n.length).join("0") + n; 47 | } else { 48 | return n; 49 | } 50 | }; 51 | var sign: any; 52 | var timezone = new Date().getTimezoneOffset() * (-1); 53 | if (timezone >= 0) { 54 | sign = "+"; 55 | } else { 56 | sign = "-"; 57 | } 58 | 59 | timezone = Math.abs(timezone); 60 | var minutes = timezone % 60; 61 | var hours = (timezone - minutes) / 60; 62 | minutes = pad(minutes, 2); 63 | hours = pad(hours, 2); 64 | 65 | return sign + hours + "|" + minutes; 66 | } 67 | 68 | static getMac256Hash(challenge: any, appId: any, key: any) { 69 | function padRight(original: any, totalWidth: any, ch: any) { 70 | function stringFromChar(ch: any, count: any) { 71 | var s = ch; 72 | for (var i = 1; i < count; i++) { 73 | s += ch; 74 | } 75 | return s; 76 | } 77 | 78 | if (original.length < totalWidth) { 79 | ch = ch || ' '; 80 | return original + stringFromChar(ch, totalWidth - original.length); 81 | } 82 | return original.valueOf(); 83 | } 84 | 85 | function parseHexInt(s: string): number { 86 | var result = parseInt(s, 16); 87 | if (isNaN(result)) { 88 | return 0; 89 | } 90 | return result; 91 | } 92 | 93 | function int32ToHexString(n: number): string { 94 | var hexChars = '0123456789abcdef'; 95 | var hexString = ''; 96 | for (var i = 0; i <= 3; i++) { 97 | hexString += hexChars.charAt((n >> (i * 8 + 4)) & 15); 98 | hexString += hexChars.charAt((n >> (i * 8)) & 15); 99 | } 100 | 101 | return hexString; 102 | } 103 | 104 | function int64Xor(a: number, b: number): number { 105 | var sA = a.toString(2); 106 | var sB = b.toString(2); 107 | var sC = ''; 108 | var sD = ''; 109 | var diff = Math.abs(sA.length - sB.length); 110 | var i: any; 111 | 112 | for (i = 0; i < diff; i++) { 113 | sD += '0'; 114 | } 115 | 116 | if (sA.length < sB.length) { 117 | sD += sA; 118 | sA = sD; 119 | } 120 | else if (sB.length < sA.length) { 121 | sD += sB; 122 | sB = sD; 123 | } 124 | 125 | for (i = 0; i < sA.length; i++) { 126 | sC += (sA.charAt(i) === sB.charAt(i)) ? '0' : '1'; 127 | } 128 | 129 | return parseInt(sC.toString(), 2); 130 | } 131 | 132 | function cS64_C(pdwData: Array, pInHash: Array, pOutHash: Array): boolean { 133 | var MODULUS = 2147483647; 134 | if ((pdwData.length < 2) || ((pdwData.length & 1) === 1)) { 135 | return false; 136 | } 137 | 138 | var ulCS64_a = pInHash[0] & MODULUS; 139 | var ulCS64_b = pInHash[1] & MODULUS; 140 | var ulCS64_c = pInHash[2] & MODULUS; 141 | var ulCS64_d = pInHash[3] & MODULUS; 142 | var ulCS64_e = 242854337; 143 | 144 | var CS64_a = bigInt(ulCS64_a.toString());//decRadix === 1000???? 145 | var CS64_b = bigInt(ulCS64_b.toString()); 146 | var CS64_c = bigInt(ulCS64_c.toString()); 147 | var CS64_d = bigInt(ulCS64_d.toString()); 148 | var CS64_e = bigInt(ulCS64_e.toString()); 149 | 150 | var pos = 0; 151 | var mod = bigInt(MODULUS.toString()); 152 | var qwDatum = bigInt('0'); 153 | var qwMAC = bigInt('0'); 154 | var qwSum = bigInt('0'); 155 | 156 | for (var i = 0; i < pdwData.length / 2; i++) { 157 | qwDatum = bigInt(pdwData[pos++].toString()); 158 | qwDatum.multiply(CS64_e); 159 | qwDatum.mod(mod); 160 | qwMAC.add(qwDatum); 161 | qwMAC.multiply(CS64_a); 162 | qwMAC.add(CS64_b); 163 | qwMAC.mod(mod); 164 | qwSum.add(qwMAC); 165 | qwMAC.add(bigInt(pdwData[pos++].toString())); 166 | qwMAC.multiply(CS64_c); 167 | qwMAC.add(CS64_d); 168 | qwMAC.mod(mod); 169 | qwSum.add(qwMAC); 170 | } 171 | 172 | qwMAC.add(CS64_b); 173 | qwMAC.mod(mod); 174 | qwSum.add(CS64_d); 175 | qwSum.mod(mod); 176 | pOutHash[0] = parseInt(qwMAC.toString(10), 10); 177 | pOutHash[1] = parseInt(qwSum.toString(10), 10); 178 | 179 | return true; 180 | } 181 | 182 | var clearText = challenge + appId; 183 | var remaining = 8 - (clearText.length % 8); 184 | if (remaining !== 8) { 185 | clearText = padRight(clearText, clearText.length + remaining, '0'); 186 | } 187 | 188 | var cchClearText = clearText.length / 4; 189 | var pClearText: any[] = []; 190 | var i: any; 191 | var pos: any; 192 | for (i = 0, pos = 0; i < cchClearText; i++) { 193 | pClearText.splice(i, 0, 0); 194 | pClearText[i] = pClearText[i] + clearText.charCodeAt(pos++) * 1; 195 | pClearText[i] = pClearText[i] + clearText.charCodeAt(pos++) * 256; 196 | pClearText[i] = pClearText[i] + clearText.charCodeAt(pos++) * 65536; 197 | pClearText[i] = pClearText[i] + clearText.charCodeAt(pos++) * 16777216; 198 | } 199 | 200 | var sha256Hash = new Array(4); 201 | var hash: string = sha256.sha256(challenge + key).toUpperCase(); 202 | for (i = 0, pos = 0; i < sha256Hash.length; i++) { 203 | sha256Hash[i] = 0; 204 | sha256Hash[i] += parseHexInt(hash.substr(pos, 2)) * 1; 205 | pos += 2; 206 | sha256Hash[i] += parseHexInt(hash.substr(pos, 2)) * 256; 207 | pos += 2; 208 | sha256Hash[i] += parseHexInt(hash.substr(pos, 2)) * 65536; 209 | pos += 2; 210 | sha256Hash[i] += parseHexInt(hash.substr(pos, 2)) * 16777216; 211 | pos += 2; 212 | } 213 | 214 | var macHash = new Array(2); 215 | cS64_C(pClearText, sha256Hash, macHash); 216 | var a = int64Xor(sha256Hash[0], macHash[0]); 217 | var b = int64Xor(sha256Hash[1], macHash[1]); 218 | var c = int64Xor(sha256Hash[2], macHash[0]); 219 | var d = int64Xor(sha256Hash[3], macHash[1]); 220 | 221 | return int32ToHexString(a) + int32ToHexString(b) + int32ToHexString(c) + int32ToHexString(d); 222 | } 223 | } 224 | 225 | export default Utils; 226 | -------------------------------------------------------------------------------- /dist/src/login.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var request = require("request"); 4 | var cheerio = require("cheerio"); 5 | var utils_1 = require("./utils"); 6 | var Consts = require("./consts"); 7 | var url = require("url"); 8 | var es6_promise_1 = require("es6-promise"); 9 | var rejectWithError = function (reject, error, eventEmitter) { 10 | eventEmitter.fire('error', error); 11 | reject(error); 12 | }; 13 | var Login = (function () { 14 | function Login(cookieJar, eventEmitter) { 15 | this.cookieJar = cookieJar; 16 | this.requestWithJar = request.defaults({ jar: cookieJar }); 17 | this.eventEmitter = eventEmitter; 18 | } 19 | Login.prototype.doLogin = function (skypeAccount) { 20 | var _this = this; 21 | var functions = [new es6_promise_1.Promise(this.sendLoginRequestOauth.bind(this, skypeAccount)).then(function (t) { 22 | return _this.promiseSkypeToken(skypeAccount, t); 23 | }), this.getRegistrationToken, this.subscribeToResources, this.createStatusEndpoint, this.getSelfDisplayName]; 24 | return (functions.reduce(function (previousValue, currentValue) { 25 | return previousValue.then(function (skypeAccount) { 26 | return new es6_promise_1.Promise(currentValue.bind(_this, skypeAccount)); 27 | }); 28 | })); 29 | }; 30 | Login.prototype.sendLoginRequestOauth = function (skypeAccount, resolve, reject) { 31 | var _this = this; 32 | this.requestWithJar.get(Consts.SKYPEWEB_LOGIN_OAUTH_URL, function (error, response, body) { 33 | if (!error && response.statusCode == 200) { 34 | var ppft = / 0) { 126 | params[current.substring(0, index)] = current.substring(index + 1); 127 | } 128 | } 129 | return params; 130 | }, { 131 | raw: registrationTokenHeader 132 | }); 133 | if (!registrationTokenParams.registrationToken || !registrationTokenParams.expires || !registrationTokenParams.endpointId) { 134 | rejectWithError(reject, 'Failed to find registrationToken or expires or endpointId.', _this.eventEmitter); 135 | return; 136 | } 137 | registrationTokenParams.expires = parseInt(registrationTokenParams.expires); 138 | skypeAccount.registrationTokenParams = registrationTokenParams; 139 | resolve(skypeAccount); 140 | } 141 | else { 142 | rejectWithError(reject, "Failed to get registrationToken. " + error + " " + JSON.stringify(response), _this.eventEmitter); 143 | } 144 | }); 145 | }; 146 | Login.prototype.subscribeToResources = function (skypeAccount, resolve, reject) { 147 | var _this = this; 148 | var interestedResources = [ 149 | '/v1/threads/ALL', 150 | '/v1/users/ME/contacts/ALL', 151 | '/v1/users/ME/conversations/ALL/messages', 152 | '/v1/users/ME/conversations/ALL/properties' 153 | ]; 154 | var requestBody = JSON.stringify({ 155 | interestedResources: interestedResources, 156 | template: 'raw', 157 | channelType: 'httpLongPoll' 158 | }); 159 | this.requestWithJar.post(Consts.SKYPEWEB_HTTPS + skypeAccount.messagesHost + '/v1/users/ME/endpoints/SELF/subscriptions', { 160 | body: requestBody, 161 | headers: { 162 | 'RegistrationToken': skypeAccount.registrationTokenParams.raw 163 | } 164 | }, function (error, response, body) { 165 | if (!error && response.statusCode === 201) { 166 | resolve(skypeAccount); 167 | } 168 | else { 169 | rejectWithError(reject, "Failed to subscribe to resources. " + error + " " + response.statusCode, _this.eventEmitter); 170 | } 171 | }); 172 | }; 173 | Login.prototype.createStatusEndpoint = function (skypeAccount, resolve, reject) { 174 | var _this = this; 175 | if (!skypeAccount.registrationTokenParams.endpointId) { 176 | resolve(skypeAccount); 177 | return; 178 | } 179 | var requestBody = JSON.stringify({ 180 | "id": "messagingService", 181 | "type": "EndpointPresenceDoc", 182 | "selfLink": "uri", 183 | "privateInfo": { "epname": "skype" }, 184 | "publicInfo": { 185 | "capabilities": "video|audio", 186 | "type": 1, 187 | "skypeNameVersion": Consts.SKYPEWEB_CLIENTINFO_NAME, 188 | "nodeInfo": "xx", 189 | "version": Consts.SKYPEWEB_CLIENTINFO_VERSION + '//' + Consts.SKYPEWEB_CLIENTINFO_NAME 190 | } 191 | }); 192 | this.requestWithJar.put(Consts.SKYPEWEB_HTTPS + skypeAccount.messagesHost + 193 | '/v1/users/ME/endpoints/' + skypeAccount.registrationTokenParams.endpointId + '/presenceDocs/messagingService', { 194 | body: requestBody, 195 | headers: { 196 | 'RegistrationToken': skypeAccount.registrationTokenParams.raw 197 | } 198 | }, function (error, response, body) { 199 | if (!error && response.statusCode === 200) { 200 | resolve(skypeAccount); 201 | } 202 | else { 203 | rejectWithError(reject, 'Failed to create endpoint for status.' + 204 | '.\n Error code: ' + response.statusCode + 205 | '.\n Error: ' + error + 206 | '.\n Body: ' + body, _this.eventEmitter); 207 | } 208 | }); 209 | }; 210 | Login.prototype.getSelfDisplayName = function (skypeAccout, resolve, reject) { 211 | this.requestWithJar.get(Consts.SKYPEWEB_HTTPS + Consts.SKYPEWEB_API_SKYPE_HOST + Consts.SKYPEWEB_SELF_DISPLAYNAME_URL, { 212 | headers: { 213 | 'X-Skypetoken': skypeAccout.skypeToken 214 | } 215 | }, function (error, response, body) { 216 | if (!error && response.statusCode == 200) { 217 | skypeAccout.selfInfo = JSON.parse(body); 218 | resolve(skypeAccout); 219 | } 220 | else { 221 | rejectWithError(reject, 'Failed to get selfInfo.' + 222 | '.\n Error code: ' + response.statusCode + 223 | '.\n Error: ' + error + 224 | '.\n Body: ' + body, this.eventEmitter); 225 | } 226 | }); 227 | }; 228 | return Login; 229 | }()); 230 | exports.Login = Login; 231 | exports.default = Login; 232 | //# sourceMappingURL=login.js.map -------------------------------------------------------------------------------- /src/login.ts: -------------------------------------------------------------------------------- 1 | import * as request from 'request'; 2 | import * as cheerio from 'cheerio'; 3 | import Utils from './utils'; 4 | import SkypeAccount from './skype_account'; 5 | import * as Consts from './consts'; 6 | import * as http from 'http'; 7 | import * as url from 'url'; 8 | import {CookieJar} from "request"; 9 | import {Promise} from "es6-promise"; 10 | import {EventEmitter} from "./utils"; 11 | 12 | const rejectWithError = (reject:(reason?:any)=>void, error: string, eventEmitter:EventEmitter) => { 13 | eventEmitter.fire('error', error); 14 | reject(error); 15 | }; 16 | 17 | export class Login { 18 | private requestWithJar: any; 19 | private cookieJar: CookieJar; 20 | private eventEmitter: EventEmitter; 21 | 22 | constructor(cookieJar:CookieJar, eventEmitter: EventEmitter) { 23 | this.cookieJar = cookieJar; 24 | this.requestWithJar = request.defaults({jar: cookieJar}); 25 | this.eventEmitter = eventEmitter; 26 | } 27 | 28 | public doLogin(skypeAccount: SkypeAccount) { 29 | var functions = [new Promise(this.sendLoginRequestOauth.bind(this, skypeAccount)).then((t) => { 30 | return this.promiseSkypeToken(skypeAccount, t); 31 | }), this.getRegistrationToken, this.subscribeToResources, this.createStatusEndpoint, this.getSelfDisplayName]; 32 | 33 | return >(functions.reduce((previousValue: Promise, currentValue: any) => { 34 | return previousValue.then((skypeAccount: SkypeAccount) => { 35 | return new Promise(currentValue.bind(this, skypeAccount)); 36 | }); 37 | })); 38 | } 39 | 40 | private sendLoginRequestOauth(skypeAccount:SkypeAccount, resolve: any, reject: any) { 41 | this.requestWithJar.get(Consts.SKYPEWEB_LOGIN_OAUTH_URL, (error: Error, response: any, body: any) => { 42 | if (!error && response.statusCode == 200) { 43 | //we'll need those values to do successful auth 44 | //sFTTag: '', 45 | var ppft = / { 62 | if (!error && response.statusCode == 200) { 63 | var $ = cheerio.load(body); 64 | //we need this magic t 65 | var t = $('input[name="t"]').val(); 66 | if (!t) { 67 | rejectWithError(reject, 'Failed to find t inside.', this.eventEmitter); 68 | } 69 | 70 | resolve(t); 71 | } else { 72 | rejectWithError(reject, 'Failed to get t', this.eventEmitter); 73 | } 74 | }); 75 | } else { 76 | rejectWithError(reject, 'Failed while trying to get ppft', this.eventEmitter); 77 | } 78 | }); 79 | } 80 | 81 | private promiseSkypeToken(skypeAccount:SkypeAccount, magicT: string):Promise { 82 | return new Promise((resolve, reject) => { 83 | var postParams = { 84 | url: Consts.SKYPEWEB_LOGIN_MICROSOFT_URL, 85 | form: { 86 | t: magicT, //*friendship* t is magic 87 | site_name: 'lw.skype.com', 88 | oauthPartner: 999, 89 | client_id: 578134, 90 | redirect_uri: 'https://web.skype.com' 91 | } 92 | }; 93 | this.requestWithJar.post(postParams, (error: Error, response: any, body: any) => { 94 | if (!error && response.statusCode == 200) { 95 | var $ = cheerio.load(body); 96 | skypeAccount.skypeToken = $('input[name="skypetoken"]').val(); 97 | skypeAccount.skypeTokenExpiresIn = parseInt($('input[name="expires_in"]').val());//86400 by default 98 | if (skypeAccount.skypeToken && skypeAccount.skypeTokenExpiresIn) { 99 | resolve(skypeAccount); 100 | } else { 101 | rejectWithError(reject, 'Failed to get skypetoken. Username or password is incorrect OR you\'ve' + 102 | ' hit a CAPTCHA wall.' + $('.message_error').text(), this.eventEmitter); 103 | } 104 | } else { 105 | rejectWithError(reject, `Failed to get skypetocken ${error} ${body} ${response.statusCode}`, this.eventEmitter); 106 | } 107 | }); 108 | }) 109 | } 110 | 111 | private getRegistrationToken(skypeAccount:SkypeAccount, resolve: any, reject: any) { 112 | var currentTime = Utils.getCurrentTime(); 113 | var lockAndKeyResponse = Utils.getMac256Hash(currentTime, Consts.SKYPEWEB_LOCKANDKEY_APPID, Consts.SKYPEWEB_LOCKANDKEY_SECRET); 114 | this.requestWithJar.post(Consts.SKYPEWEB_HTTPS + skypeAccount.messagesHost + '/v1/users/ME/endpoints', { 115 | headers: { 116 | 'LockAndKey': 'appId=' + Consts.SKYPEWEB_LOCKANDKEY_APPID + '; time=' + currentTime + '; lockAndKeyResponse=' + lockAndKeyResponse, 117 | 'ClientInfo': 'os=Windows; osVer=10; proc=Win64; lcid=en-us; deviceType=1; country=n/a; clientName=' + Consts.SKYPEWEB_CLIENTINFO_NAME + '; clientVer=' + Consts.SKYPEWEB_CLIENTINFO_VERSION, 118 | 'Authentication': 'skypetoken=' + skypeAccount.skypeToken 119 | }, 120 | body: JSON.stringify({ endpointFeatures: "Agent" }) //this means *war* that this client can work with bots (aka agents). 121 | }, (error:any, response:http.IncomingMessage, body:any) => { 122 | //now lets try retrieve registration token 123 | if (!error && response.statusCode === 201 || response.statusCode === 301) { 124 | var locationHeader = response.headers['location']; 125 | //expecting something like this 'registrationToken=someSting; expires=someNumber; endpointId={someString}' 126 | var registrationTokenHeader = response.headers['set-registrationtoken']; 127 | var location = url.parse(locationHeader); 128 | if (location.host !== skypeAccount.messagesHost) { //mainly when 301, but sometimes when 201 129 | skypeAccount.messagesHost = location.host; 130 | //looks like messagesHost has changed? 131 | this.getRegistrationToken(skypeAccount, resolve, reject); 132 | return; 133 | } 134 | 135 | var registrationTokenParams = (registrationTokenHeader as string).split(/\s*;\s*/).reduce((params: any, current:string) => { 136 | if (current.indexOf('registrationToken') === 0) { 137 | params['registrationToken'] = current; 138 | } else { 139 | var index = current.indexOf('='); 140 | if (index > 0) { 141 | params[current.substring(0, index)] = current.substring(index + 1); 142 | } 143 | } 144 | return params; 145 | }, { 146 | raw: registrationTokenHeader 147 | }); 148 | if (!registrationTokenParams.registrationToken || !registrationTokenParams.expires || !registrationTokenParams.endpointId) { 149 | rejectWithError(reject, 'Failed to find registrationToken or expires or endpointId.', this.eventEmitter); 150 | return; 151 | } 152 | registrationTokenParams.expires = parseInt(registrationTokenParams.expires); 153 | 154 | skypeAccount.registrationTokenParams = registrationTokenParams; 155 | 156 | //fixme add endpoint and expires! 157 | resolve(skypeAccount) 158 | 159 | } else { 160 | rejectWithError(reject, `Failed to get registrationToken. ${error} ${JSON.stringify(response)}`, this.eventEmitter); 161 | } 162 | }); 163 | } 164 | 165 | private subscribeToResources(skypeAccount:SkypeAccount, resolve: any, reject: any) { 166 | var interestedResources = [ 167 | '/v1/threads/ALL', 168 | '/v1/users/ME/contacts/ALL', 169 | '/v1/users/ME/conversations/ALL/messages', 170 | '/v1/users/ME/conversations/ALL/properties' 171 | ]; 172 | var requestBody = JSON.stringify({ 173 | interestedResources: interestedResources, 174 | template: 'raw', 175 | channelType: 'httpLongPoll'//todo web sockets maybe ? 176 | }); 177 | 178 | this.requestWithJar.post(Consts.SKYPEWEB_HTTPS + skypeAccount.messagesHost + '/v1/users/ME/endpoints/SELF/subscriptions', { 179 | body: requestBody, 180 | headers: { 181 | 'RegistrationToken': skypeAccount.registrationTokenParams.raw 182 | } 183 | }, (error:any, response:http.IncomingMessage, body:any) => { 184 | if (!error && response.statusCode === 201) { 185 | resolve(skypeAccount); 186 | } else { 187 | rejectWithError(reject, `Failed to subscribe to resources. ${error} ${response.statusCode}`, this.eventEmitter); 188 | } 189 | }); 190 | } 191 | 192 | private createStatusEndpoint(skypeAccount:SkypeAccount, resolve: any, reject: any) { 193 | if (!skypeAccount.registrationTokenParams.endpointId){ 194 | //there is no need in this case to create endpoint? 195 | resolve(skypeAccount); 196 | return; 197 | } 198 | //a little bit more of skype madness 199 | var requestBody = JSON.stringify({ //this is exact json that is needed to register endpoint for setting of status. 200 | "id": "messagingService", 201 | "type": "EndpointPresenceDoc", 202 | "selfLink": "uri", 203 | "privateInfo": {"epname": "skype"}, 204 | "publicInfo": { 205 | "capabilities": "video|audio", 206 | "type": 1, 207 | "skypeNameVersion": Consts.SKYPEWEB_CLIENTINFO_NAME, 208 | "nodeInfo": "xx", 209 | "version": Consts.SKYPEWEB_CLIENTINFO_VERSION + '//' + Consts.SKYPEWEB_CLIENTINFO_NAME 210 | } 211 | }); 212 | 213 | this.requestWithJar.put(Consts.SKYPEWEB_HTTPS + skypeAccount.messagesHost + 214 | '/v1/users/ME/endpoints/' + skypeAccount.registrationTokenParams.endpointId + '/presenceDocs/messagingService', { 215 | body: requestBody, 216 | headers: { 217 | 'RegistrationToken': skypeAccount.registrationTokenParams.raw 218 | } 219 | }, (error:any, response:http.IncomingMessage, body:any) => { 220 | if (!error && response.statusCode === 200) { 221 | resolve(skypeAccount); 222 | } else { 223 | rejectWithError(reject, 'Failed to create endpoint for status.' + 224 | '.\n Error code: ' + response.statusCode + 225 | '.\n Error: ' + error + 226 | '.\n Body: ' + body, this.eventEmitter); 227 | } 228 | }); 229 | } 230 | 231 | private getSelfDisplayName(skypeAccout: SkypeAccount, resolve: any, reject: any) { 232 | this.requestWithJar.get(Consts.SKYPEWEB_HTTPS + Consts.SKYPEWEB_API_SKYPE_HOST + Consts.SKYPEWEB_SELF_DISPLAYNAME_URL, { 233 | headers: { 234 | 'X-Skypetoken': skypeAccout.skypeToken 235 | } 236 | }, function (error: any, response: http.IncomingMessage, body: any) { 237 | if (!error && response.statusCode == 200) { 238 | skypeAccout.selfInfo = JSON.parse(body); 239 | resolve(skypeAccout); 240 | } else { 241 | rejectWithError(reject, 'Failed to get selfInfo.' + 242 | '.\n Error code: ' + response.statusCode + 243 | '.\n Error: ' + error + 244 | '.\n Body: ' + body, this.eventEmitter); 245 | } 246 | }); 247 | } 248 | } 249 | 250 | export default Login; 251 | --------------------------------------------------------------------------------