Skip to content

Download image #107

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4,250 changes: 2,394 additions & 1,856 deletions package-lock.json

Large diffs are not rendered by default.

26 changes: 24 additions & 2 deletions src/lib/api-uri.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import path from "path";
import url from "url";
import { SKYPEWEB_API_SKYPE_HOST } from "./consts";
import { SKYPEWEB_API_SKYPE_HOST, SKYPEWEB_CONTACTS_HOST } from "./consts";

export const DEFAULT_USER: string = "self";

Expand Down Expand Up @@ -29,11 +29,21 @@ function buildContacts(username: string): string[] {
return buildUser(username).concat("contacts");
}

// /users/:user/invites
function buildInvites(username: string): string[] {
return buildUser(username).concat("invites");
}

// /users/:user/contacts/auth-request/:contact
function buildAuthRequest(username: string, contact: string): string[] {
return buildContacts(username).concat("auth-request", contact);
}

// /users/:user/invites/:contact
function buildInviteRequest(username: string, contact: string): string[] {
return buildInvites(username).concat(contact);
}

// /users/:user/contacts/auth-request/:contact/accept
function buildAuthRequestAccept(username: string, contact: string): string[] {
return buildAuthRequest(username, contact).concat("accept");
Expand All @@ -44,6 +54,10 @@ function buildAuthRequestDecline(username: string, contact: string): string[] {
return buildAuthRequest(username, contact).concat("decline");
}

function buildInviteRequestAccept(username: string, contact: string): string[] {
return buildInviteRequest(username, contact).concat("accept");
}

// /users/:user/displayname
function buildDisplayName(username: string): string[] {
return buildUser(username).concat("displayname");
Expand Down Expand Up @@ -95,10 +109,18 @@ function getOrigin(): string {
return "https://" + SKYPEWEB_API_SKYPE_HOST;
}

function getContact(): string {
return `https://${SKYPEWEB_CONTACTS_HOST}`;
}

function get(p: string) {
return url.resolve(getOrigin(), p);
}

function getC(p: string) {
return url.resolve(getContact(), p);
}

export function displayName(username: string): string {
return get(joinPath(buildDisplayName(username)));
}
Expand All @@ -112,7 +134,7 @@ export function userProfiles(): string {
}

export function authRequestAccept(username: string, contact: string): string {
return get(joinPath(buildAuthRequestAccept(username, contact)));
return getC(joinPath(buildInviteRequestAccept(username, contact)));
}

export function authRequestDecline(username: string, contact: string): string {
Expand Down
6 changes: 6 additions & 0 deletions src/lib/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { declineContactRequest } from "./api/decline-contact-request";
import { getContact } from "./api/get-contact";
import { getConversation } from "./api/get-conversation";
import { getConversations } from "./api/get-conversations";
import { getImage } from "./api/get-image";
import { getJoinUrl } from "./api/get-join-url";
import { sendImage } from "./api/send-image";
import { sendMessage } from "./api/send-message";
Expand All @@ -17,6 +18,7 @@ import { Contact as _Contact } from "./interfaces/api/contact";
import { Context as ApiContext } from "./interfaces/api/context";
import { Conversation } from "./interfaces/api/conversation";
import * as apiEvents from "./interfaces/api/events";
import { FileResource } from "./interfaces/api/resources";
import { HttpIo } from "./interfaces/http-io";
import { AllUsers } from "./interfaces/native-api/conversation";
import { MessagesPoller } from "./polling/messages-poller";
Expand Down Expand Up @@ -99,6 +101,10 @@ export class Api extends events.EventEmitter implements ApiEvents {
return sendImage(this.io, this.context, message, conversationId);
}

async getMedia(resource: FileResource): Promise<api.MediaDownloaded> {
return getImage(this.io, this.context, resource);
}

getState(): ApiContext.Json {
return ApiContext.toJson(this.context);
}
Expand Down
4 changes: 2 additions & 2 deletions src/lib/api/accept-contact-request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ import { Context } from "../interfaces/api/context";
import * as io from "../interfaces/http-io";

export async function acceptContactRequest(io: io.HttpIo, apiContext: Context, contactUsername: string): Promise<void> {
const requestOptions: io.GetOptions = {
const requestOptions: io.PutOptions = {
uri: apiUri.authRequestAccept(apiContext.username, contactUsername),
cookies: apiContext.cookies,
headers: {
"X-Skypetoken": apiContext.skypeToken.value,
},
};
const res: io.Response = await io.put(requestOptions);
if (res.statusCode !== 201) {
if (res.statusCode !== 200) {
return Promise.reject(new Incident("net", "Failed to accept contact"));
}
}
42 changes: 42 additions & 0 deletions src/lib/api/get-image.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { Incident } from "incident";
import { MediaDownloaded } from "../interfaces/api/api";
import { Context } from "../interfaces/api/context";
import { FileResource } from "../interfaces/api/resources";
import * as io from "../interfaces/http-io";

export async function getImage(
io: io.HttpIo,
apiContext: Context,
messageResource: FileResource,
): Promise<MediaDownloaded> {

const originUri: string = messageResource.uri +
(messageResource.type === "RichText/UriObject" ?
"/views/imgpsh_fullsize" :
messageResource.type === "RichText/Media_GenericFile" ?
"/views/original" : "");

if (originUri === messageResource.uri) {
return Promise.reject(new Incident("get-media", "Received wrong type of resource file"));
}

const requestOptions: io.GetOptions = {
uri: originUri,
headers: {
Authorization: "skype_token " + apiContext.skypeToken.value,
},
};

const res: io.Response = await io.getImageContent(requestOptions);

if (res.statusCode !== 200) {
return Promise.reject(new Incident("get-media", "Received wrong return code"));
}

return {
content: res.body,
uri_origin: originUri,
file_size: parseInt(res.headers["content-length"], 10),
original_file_name: messageResource.original_file_name,
};
}
1 change: 1 addition & 0 deletions src/lib/api/send-image.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export async function sendImage(
"Authorization": `skype_token ${apiContext.skypeToken.value}`,
"Content-Type": "application/json",
"Content-Length": bodyNewObjectStr.length.toString(10),
"X-Client-Version": "0/0.0.0.0",
},
};
const resNewObject: io.Response = await io.post(requestOptionsNewObject);
Expand Down
2 changes: 1 addition & 1 deletion src/lib/consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export const SKYPEWEB_LOCKANDKEY_SECRET: string = "Q1P7W2E4J9R8U3S5";
export const SKYPEWEB_CLIENTINFO_NAME: string = "skype.com";
export const SKYPEWEB_CLIENTINFO_VERSION: string = "908/1.30.0.128";
export const SKYPEWEB_API_SKYPE_HOST: string = "api.skype.com";
export const SKYPEWEB_CONTACTS_HOST: string = "contacts.skype.com";
export const SKYPEWEB_CONTACTS_HOST: string = "contacts.skype.com/contacts/v2/";
export const SKYPEWEB_DEFAULT_MESSAGES_HOST: string = "client-s.gateway.messenger.live.com";
// tslint:disable-next-line:max-line-length
export const SKYPEWEB_LOGIN_URL: string = "https://login.skype.com/login?method=skype&client_id=578134&redirect_uri=https%3A%2F%2Fweb.skype.com";
Expand Down
7 changes: 7 additions & 0 deletions src/lib/interfaces/api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,10 @@ export interface FullId extends ParsedId {
typeName: string;
raw: string;
}

export interface MediaDownloaded {
content: string;
uri_origin: string;
file_size?: number;
original_file_name: string;
}
2 changes: 2 additions & 0 deletions src/lib/interfaces/http-io.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,6 @@ export interface HttpIo {
post(options: PostOptions): Promise<Response>;

put(options: PutOptions): Promise<Response>;

getImageContent(options: GetOptions): Promise<Response>;
}
25 changes: 25 additions & 0 deletions src/lib/request-io.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,30 @@ function asRequestOptions(ioOptions: io.GetOptions | io.PostOptions | io.PutOpti
return result;
}

export async function getImageContent(options: io.GetOptions): Promise<io.Response> {
return new Promise<io.Response>((resolve, reject) => {
const requestOptions: request.Options = asRequestOptions(options);
requestOptions.encoding = "base64";

request.get(requestOptions, (error, response, body) => {
if (error) {
return reject(error);
}
if (response.statusCode === undefined) {
return reject(new Error("Missing status code"));
}

const ioResponse: io.Response = {
statusCode: response.statusCode,
body,
headers: response.headers,
};

resolve(ioResponse);
});
});
}

/**
* Send a GET request
*
Expand Down Expand Up @@ -103,4 +127,5 @@ export const requestIo: io.HttpIo = {
get,
post,
put,
getImageContent,
};