From c70d1ad58b083719113fbdae1763ec2c41438dac Mon Sep 17 00:00:00 2001 From: Grigori Grudinin Date: Thu, 8 Feb 2018 16:45:20 +0300 Subject: [PATCH 1/6] add create-conversation, set-topic, get-join-url --- .gitignore | 1 + src/lib/api.ts | 16 ++++++ src/lib/api/create-conversation.ts | 50 +++++++++++++++++++ src/lib/api/get-join-url.ts | 37 ++++++++++++++ src/lib/api/set-conversation-topic.ts | 38 ++++++++++++++ src/lib/interfaces/native-api/conversation.ts | 17 +++++++ src/lib/messages-uri.ts | 9 ++++ src/lib/utils.ts | 15 +++++- 8 files changed, 182 insertions(+), 1 deletion(-) create mode 100644 src/lib/api/create-conversation.ts create mode 100644 src/lib/api/get-join-url.ts create mode 100644 src/lib/api/set-conversation-topic.ts diff --git a/.gitignore b/.gitignore index 4ed15a2..10638a1 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ # JetBrains products (Webstorm, IntelliJ IDEA, ...) .idea/ *.iml +.vscode ############################################################################### # Build # diff --git a/src/lib/api.ts b/src/lib/api.ts index 62d0136..732bb35 100644 --- a/src/lib/api.ts +++ b/src/lib/api.ts @@ -6,6 +6,9 @@ import { getConversation } from "./api/get-conversation"; import { getConversations } from "./api/get-conversations"; import { sendImage } from "./api/send-image"; import { sendMessage } from "./api/send-message"; +import { setConversationTopic } from "./api/set-conversation-topic"; +import { getJoinUrl } from "./api/get-join-url"; +import { createConversation } from "./api/create-conversation"; import { setStatus } from "./api/set-status"; import { ContactsInterface, ContactsService } from "./contacts/contacts"; import * as api from "./interfaces/api/api"; @@ -17,6 +20,7 @@ import { HttpIo } from "./interfaces/http-io"; import { MessagesPoller } from "./polling/messages-poller"; import { Contact } from "./types/contact"; import { Invite } from "./types/invite"; +import { AllUsers } from "./interfaces/native-api/conversation"; export interface ApiEvents extends NodeJS.EventEmitter { @@ -74,6 +78,18 @@ export class Api extends events.EventEmitter implements ApiEvents { return sendMessage(this.io, this.context, message, conversationId); } + async setConversationTopic(conversationId: string, topic: string): Promise { + return setConversationTopic(this.io, this.context, conversationId, topic); + } + + async getJoinUrl(conversationId: string): Promise { + return getJoinUrl(this.io, this.context, conversationId); + } + + async createConversation(allUsers: AllUsers): Promise { + return createConversation(this.io, this.context, allUsers); + } + async sendImage(message: api.NewImage, conversationId: string): Promise { return sendImage(this.io, this.context, message, conversationId); } diff --git a/src/lib/api/create-conversation.ts b/src/lib/api/create-conversation.ts new file mode 100644 index 0000000..9f1125b --- /dev/null +++ b/src/lib/api/create-conversation.ts @@ -0,0 +1,50 @@ +import { Incident } from "incident"; +import { Context } from "../interfaces/api/context"; +import * as io from "../interfaces/http-io"; +import * as messagesUri from "../messages-uri"; +import { getMembers } from "../utils"; + +interface RequestBody { + members: Array; +} + +interface AllUsers { + [type: string]: string[]; +} + +export async function createConversation( + io: io.HttpIo, + apiContext: Context, + allUsers: AllUsers, +): Promise { + + // Each member object consists of an ``id`` (user thread identifier), and role (either ``Admin`` or ``User``). + const members = getMembers(allUsers); + const requestBody: RequestBody = { + members, + }; + + const uri: string = messagesUri.thread(apiContext.registrationToken.host, ''); + + const requestOptions: io.PostOptions = { + uri, + cookies: apiContext.cookies, + body: JSON.stringify(requestBody), + headers: { + 'RegistrationToken': apiContext.registrationToken.raw, + Location: '/', + }, + }; + + const res: io.Response = await io.post(requestOptions); + + if (res.statusCode !== 201) { + return Promise.reject(new Incident("create-conversation", "Received wrong return code")); + } + + const location: string = res.headers.location; + const id: any = location.split('/').pop(); + + // conversation ID + return id; +} diff --git a/src/lib/api/get-join-url.ts b/src/lib/api/get-join-url.ts new file mode 100644 index 0000000..2b2155c --- /dev/null +++ b/src/lib/api/get-join-url.ts @@ -0,0 +1,37 @@ +import { Incident } from "incident"; +import { Context } from "../interfaces/api/context"; +import * as io from "../interfaces/http-io"; +import * as messagesUri from "../messages-uri"; +import { Join } from "../interfaces/native-api/conversation"; + +interface RequestBody { + baseDomain: 'https://join.skype.com/launch/' | string; + threadId: string; +} + +export async function getJoinUrl(io: io.HttpIo, apiContext: Context, conversationId: string): Promise { + const requestBody: RequestBody = { + baseDomain: 'https://join.skype.com/launch/', + threadId: conversationId, + }; + + const uri: string = 'https://api.scheduler.skype.com/threads'; + + const requestOptions: io.PostOptions = { + uri, + cookies: apiContext.cookies, + body: JSON.stringify(requestBody), + headers: { + 'X-Skypetoken': apiContext.skypeToken.value, + 'Content-Type': 'application/json', + }, + }; + + const res = await io.post(requestOptions); + if (res.statusCode !== 200) { + return Promise.reject(new Incident("get-join-url", "Received wrong return code")); + } + const body: Join = JSON.parse(res.body); + + return body.JoinUrl; +} diff --git a/src/lib/api/set-conversation-topic.ts b/src/lib/api/set-conversation-topic.ts new file mode 100644 index 0000000..3aeca3f --- /dev/null +++ b/src/lib/api/set-conversation-topic.ts @@ -0,0 +1,38 @@ +import { Incident } from "incident"; +import { Context } from "../interfaces/api/context"; +import * as io from "../interfaces/http-io"; +import * as messagesUri from "../messages-uri"; + +interface RequestBody { + topic: string; +} + +export async function setConversationTopic( + io: io.HttpIo, + apiContext: Context, + conversationId: string, + topic: string, +): Promise { + + const requestBody: RequestBody = { + topic, + }; + + const uri: string = messagesUri.properties(apiContext.registrationToken.host, conversationId); + + const requestOptions: io.PutOptions = { + uri, + cookies: apiContext.cookies, + body: JSON.stringify(requestBody), + queryString: {name: 'topic'}, + headers: { + 'RegistrationToken': apiContext.registrationToken.raw, + 'Content-type': 'application/json', + }, + }; + const res: io.Response = await io.put(requestOptions); + + if (res.statusCode !== 200) { + return Promise.reject(new Incident("set-conversation-topic", "Received wrong return code")); + } +} diff --git a/src/lib/interfaces/native-api/conversation.ts b/src/lib/interfaces/native-api/conversation.ts index cfebc89..c148275 100644 --- a/src/lib/interfaces/native-api/conversation.ts +++ b/src/lib/interfaces/native-api/conversation.ts @@ -8,6 +8,14 @@ export interface ThreadProperties { version?: string; } +// https://github.com/OllieTerrance/SkPy.docs/blob/master/protocol/chat.rst#join-urls +export interface Join { + Blob: string, + Id: string, + JoinUrl: string, + ThreadId: string, +} + export interface Conversation { // https://{host}/v1/threads/{19:threadId} or // https://{host}/v1/users/ME/contacts/{8:contactId} targetLink: string; @@ -43,6 +51,15 @@ export interface ThreadMember { friendlyName: string; } +export interface AllUsers { + [type: string]: string[]; +} + +export interface Members { + id: string; + role: 'Admin' | 'User' | string; +} + export interface Thread { // "19:..." id: string; diff --git a/src/lib/messages-uri.ts b/src/lib/messages-uri.ts index 9295512..5ef5325 100644 --- a/src/lib/messages-uri.ts +++ b/src/lib/messages-uri.ts @@ -31,6 +31,11 @@ function buildThread(thread: string): string[] { return buildThreads().concat(thread); } +// /v1/threads/{thread}/properties +function buildProperties(thread: string): string[] { + return buildThread(thread).concat('properties'); +} + // /v1/users function buildUsers(): string[] { return buildV1().concat("users"); @@ -137,6 +142,10 @@ export function thread(host: string, threadId: string): string { return get(host, joinPath(buildThread(threadId))); } +export function properties(host: string, threadId: string): string { + return get(host, joinPath(buildProperties(threadId))); +} + export function users(host: string): string { return get(host, joinPath(buildUsers())); } diff --git a/src/lib/utils.ts b/src/lib/utils.ts index a6804c4..7a5c107 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -1,5 +1,5 @@ import _ from "lodash"; - +import { Members, AllUsers } from "./interfaces/native-api/conversation"; /** * Returns the number of seconds since epoch. * @@ -98,3 +98,16 @@ export function parseHeaderParams(params: string): Map { return result; } + + + +export function getMembers(allUsers: AllUsers): Array { + return Object.keys(allUsers).reduce( + (acc: Array, key: string) => { + const role = key === 'admins' ? 'Admin' : 'User'; + const parsedGroup = allUsers[key].map((id: string) => ({id, role})); + + return [...acc, ...parsedGroup]; + }, []); +}; + From 0fba1467262b147a58f9975055e806326be381b1 Mon Sep 17 00:00:00 2001 From: Grigori Grudinin Date: Thu, 8 Feb 2018 16:45:56 +0300 Subject: [PATCH 2/6] add create-conversation, set-topic, get-join-url --- src/lib/messages-uri.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/messages-uri.ts b/src/lib/messages-uri.ts index 5ef5325..593923c 100644 --- a/src/lib/messages-uri.ts +++ b/src/lib/messages-uri.ts @@ -28,7 +28,7 @@ function buildThreads(): string[] { // /v1/threads/{thread} function buildThread(thread: string): string[] { - return buildThreads().concat(thread); + return thread === '' ? buildThreads() : buildThreads().concat(thread); } // /v1/threads/{thread}/properties From d212c6b3ff484b07e1853e927c0fa592edc429a3 Mon Sep 17 00:00:00 2001 From: Grigori Grudinin Date: Fri, 9 Feb 2018 11:55:40 +0300 Subject: [PATCH 3/6] fix AllUsers interface bug, lint OK --- src/lib/api.ts | 6 +++--- src/lib/api/create-conversation.ts | 17 +++++++---------- src/lib/api/get-join-url.ts | 14 +++++++------- src/lib/api/set-conversation-topic.ts | 6 +++--- src/lib/interfaces/native-api/conversation.ts | 10 +++++----- src/lib/messages-uri.ts | 4 ++-- src/lib/utils.ts | 15 ++++++--------- 7 files changed, 33 insertions(+), 39 deletions(-) diff --git a/src/lib/api.ts b/src/lib/api.ts index 732bb35..2301a8a 100644 --- a/src/lib/api.ts +++ b/src/lib/api.ts @@ -1,14 +1,14 @@ import events from "events"; import { acceptContactRequest } from "./api/accept-contact-request"; +import { createConversation } from "./api/create-conversation"; 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 { getJoinUrl } from "./api/get-join-url"; import { sendImage } from "./api/send-image"; import { sendMessage } from "./api/send-message"; import { setConversationTopic } from "./api/set-conversation-topic"; -import { getJoinUrl } from "./api/get-join-url"; -import { createConversation } from "./api/create-conversation"; import { setStatus } from "./api/set-status"; import { ContactsInterface, ContactsService } from "./contacts/contacts"; import * as api from "./interfaces/api/api"; @@ -17,10 +17,10 @@ import { Context as ApiContext } from "./interfaces/api/context"; import { Conversation } from "./interfaces/api/conversation"; import * as apiEvents from "./interfaces/api/events"; import { HttpIo } from "./interfaces/http-io"; +import { AllUsers } from "./interfaces/native-api/conversation"; import { MessagesPoller } from "./polling/messages-poller"; import { Contact } from "./types/contact"; import { Invite } from "./types/invite"; -import { AllUsers } from "./interfaces/native-api/conversation"; export interface ApiEvents extends NodeJS.EventEmitter { diff --git a/src/lib/api/create-conversation.ts b/src/lib/api/create-conversation.ts index 9f1125b..f7ccd35 100644 --- a/src/lib/api/create-conversation.ts +++ b/src/lib/api/create-conversation.ts @@ -1,15 +1,12 @@ import { Incident } from "incident"; import { Context } from "../interfaces/api/context"; import * as io from "../interfaces/http-io"; +import { AllUsers, Members } from "../interfaces/native-api/conversation"; import * as messagesUri from "../messages-uri"; import { getMembers } from "../utils"; interface RequestBody { - members: Array; -} - -interface AllUsers { - [type: string]: string[]; + members: any[]; } export async function createConversation( @@ -19,20 +16,20 @@ export async function createConversation( ): Promise { // Each member object consists of an ``id`` (user thread identifier), and role (either ``Admin`` or ``User``). - const members = getMembers(allUsers); + const members: Members[] = getMembers(allUsers); const requestBody: RequestBody = { members, }; - const uri: string = messagesUri.thread(apiContext.registrationToken.host, ''); + const uri: string = messagesUri.thread(apiContext.registrationToken.host, ""); const requestOptions: io.PostOptions = { uri, cookies: apiContext.cookies, body: JSON.stringify(requestBody), headers: { - 'RegistrationToken': apiContext.registrationToken.raw, - Location: '/', + RegistrationToken: apiContext.registrationToken.raw, + Location: "/", }, }; @@ -43,7 +40,7 @@ export async function createConversation( } const location: string = res.headers.location; - const id: any = location.split('/').pop(); + const id: any = location.split("/").pop(); // conversation ID return id; diff --git a/src/lib/api/get-join-url.ts b/src/lib/api/get-join-url.ts index 2b2155c..e4291be 100644 --- a/src/lib/api/get-join-url.ts +++ b/src/lib/api/get-join-url.ts @@ -1,33 +1,33 @@ import { Incident } from "incident"; import { Context } from "../interfaces/api/context"; import * as io from "../interfaces/http-io"; -import * as messagesUri from "../messages-uri"; import { Join } from "../interfaces/native-api/conversation"; +import * as messagesUri from "../messages-uri"; interface RequestBody { - baseDomain: 'https://join.skype.com/launch/' | string; + baseDomain: "https://join.skype.com/launch/" | string; threadId: string; } export async function getJoinUrl(io: io.HttpIo, apiContext: Context, conversationId: string): Promise { const requestBody: RequestBody = { - baseDomain: 'https://join.skype.com/launch/', + baseDomain: "https://join.skype.com/launch/", threadId: conversationId, }; - const uri: string = 'https://api.scheduler.skype.com/threads'; + const uri: string = "https://api.scheduler.skype.com/threads"; const requestOptions: io.PostOptions = { uri, cookies: apiContext.cookies, body: JSON.stringify(requestBody), headers: { - 'X-Skypetoken': apiContext.skypeToken.value, - 'Content-Type': 'application/json', + "X-Skypetoken": apiContext.skypeToken.value, + "Content-Type": "application/json", }, }; - const res = await io.post(requestOptions); + const res: io.Response = await io.post(requestOptions); if (res.statusCode !== 200) { return Promise.reject(new Incident("get-join-url", "Received wrong return code")); } diff --git a/src/lib/api/set-conversation-topic.ts b/src/lib/api/set-conversation-topic.ts index 3aeca3f..cc76c59 100644 --- a/src/lib/api/set-conversation-topic.ts +++ b/src/lib/api/set-conversation-topic.ts @@ -24,10 +24,10 @@ export async function setConversationTopic( uri, cookies: apiContext.cookies, body: JSON.stringify(requestBody), - queryString: {name: 'topic'}, + queryString: {name: "topic"}, headers: { - 'RegistrationToken': apiContext.registrationToken.raw, - 'Content-type': 'application/json', + "RegistrationToken": apiContext.registrationToken.raw, + "Content-type": "application/json", }, }; const res: io.Response = await io.put(requestOptions); diff --git a/src/lib/interfaces/native-api/conversation.ts b/src/lib/interfaces/native-api/conversation.ts index c148275..e8352a2 100644 --- a/src/lib/interfaces/native-api/conversation.ts +++ b/src/lib/interfaces/native-api/conversation.ts @@ -10,10 +10,10 @@ export interface ThreadProperties { // https://github.com/OllieTerrance/SkPy.docs/blob/master/protocol/chat.rst#join-urls export interface Join { - Blob: string, - Id: string, - JoinUrl: string, - ThreadId: string, + Blob: string; + Id: string; + JoinUrl: string; + ThreadId: string; } export interface Conversation { @@ -57,7 +57,7 @@ export interface AllUsers { export interface Members { id: string; - role: 'Admin' | 'User' | string; + role: "Admin" | "User" | string; } export interface Thread { diff --git a/src/lib/messages-uri.ts b/src/lib/messages-uri.ts index 593923c..07aef50 100644 --- a/src/lib/messages-uri.ts +++ b/src/lib/messages-uri.ts @@ -28,12 +28,12 @@ function buildThreads(): string[] { // /v1/threads/{thread} function buildThread(thread: string): string[] { - return thread === '' ? buildThreads() : buildThreads().concat(thread); + return thread === "" ? buildThreads() : buildThreads().concat(thread); } // /v1/threads/{thread}/properties function buildProperties(thread: string): string[] { - return buildThread(thread).concat('properties'); + return buildThread(thread).concat("properties"); } // /v1/users diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 7a5c107..ea9479a 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -1,5 +1,5 @@ import _ from "lodash"; -import { Members, AllUsers } from "./interfaces/native-api/conversation"; +import { AllUsers, Members } from "./interfaces/native-api/conversation"; /** * Returns the number of seconds since epoch. * @@ -99,15 +99,12 @@ export function parseHeaderParams(params: string): Map { return result; } - - -export function getMembers(allUsers: AllUsers): Array { +export function getMembers(allUsers: AllUsers): Members[] { return Object.keys(allUsers).reduce( - (acc: Array, key: string) => { - const role = key === 'admins' ? 'Admin' : 'User'; - const parsedGroup = allUsers[key].map((id: string) => ({id, role})); + (acc: any[], key: string) => { + const role: "Admin" | "User" | string = key === "admins" ? "Admin" : "User"; + const parsedGroup: Members[] = allUsers[key].map((id: string) => ({id, role})); return [...acc, ...parsedGroup]; }, []); -}; - +} From f6126a4cfddb5ea725872133f077bae0ecaa220d Mon Sep 17 00:00:00 2001 From: Grigoriy Grudinin Date: Fri, 9 Feb 2018 23:35:17 +0300 Subject: [PATCH 4/6] addMember added --- package-lock.json | 16 ++++++++-------- src/lib/api.ts | 5 +++++ src/lib/api/add-member.ts | 40 +++++++++++++++++++++++++++++++++++++++ src/lib/messages-uri.ts | 14 ++++++++++++++ 4 files changed, 67 insertions(+), 8 deletions(-) create mode 100644 src/lib/api/add-member.ts diff --git a/package-lock.json b/package-lock.json index 8bca7a7..71bf162 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8571,14 +8571,6 @@ "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", "dev": true }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "requires": { - "safe-buffer": "5.1.1" - } - }, "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", @@ -8590,6 +8582,14 @@ "strip-ansi": "3.0.1" } }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "requires": { + "safe-buffer": "5.1.1" + } + }, "stringstream": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", diff --git a/src/lib/api.ts b/src/lib/api.ts index 2301a8a..0def282 100644 --- a/src/lib/api.ts +++ b/src/lib/api.ts @@ -10,6 +10,7 @@ import { sendImage } from "./api/send-image"; import { sendMessage } from "./api/send-message"; import { setConversationTopic } from "./api/set-conversation-topic"; import { setStatus } from "./api/set-status"; +import { addMemberToConversation } from "./api/add-member"; import { ContactsInterface, ContactsService } from "./contacts/contacts"; import * as api from "./interfaces/api/api"; import { Contact as _Contact } from "./interfaces/api/contact"; @@ -86,6 +87,10 @@ export class Api extends events.EventEmitter implements ApiEvents { return getJoinUrl(this.io, this.context, conversationId); } + async addMemberToConversation(conversationId: string, memberId: string): Promise { + return addMemberToConversation(this.io, this.context, conversationId, memberId); + } + async createConversation(allUsers: AllUsers): Promise { return createConversation(this.io, this.context, allUsers); } diff --git a/src/lib/api/add-member.ts b/src/lib/api/add-member.ts new file mode 100644 index 0000000..eef7a1a --- /dev/null +++ b/src/lib/api/add-member.ts @@ -0,0 +1,40 @@ +import { Incident } from "incident"; +import { Context } from "../interfaces/api/context"; +import * as io from "../interfaces/http-io"; +import { AllUsers, Members } from "../interfaces/native-api/conversation"; +import * as messagesUri from "../messages-uri"; +import { getMembers } from "../utils"; +import { member } from "../messages-uri"; + +interface RequestBody { + role: "User" | "Admin" | string; +} + +export async function addMemberToConversation( + io: io.HttpIo, + apiContext: Context, + memberId: string, + converstionId: string, + role = 'User', +): Promise { + + // `https://{host}}/v1/threads/${converstionId}/members/${memberId}`, + const uri: string = messagesUri.member(apiContext.registrationToken.host, converstionId, memberId); + + const requestBody: RequestBody = { role }; + const requestOptions: io.PutOptions = { + uri, + cookies: apiContext.cookies, + body: JSON.stringify(requestBody), + headers: { + RegistrationToken: apiContext.registrationToken.raw, + 'Content-type': 'application/json', + }, + }; + + const res: io.Response = await io.put(requestOptions); + + if (res.statusCode !== 200) { + return Promise.reject(new Incident("add-member", "Received wrong return code")); + } +} diff --git a/src/lib/messages-uri.ts b/src/lib/messages-uri.ts index 07aef50..b328979 100644 --- a/src/lib/messages-uri.ts +++ b/src/lib/messages-uri.ts @@ -36,6 +36,16 @@ function buildProperties(thread: string): string[] { return buildThread(thread).concat("properties"); } +// /v1/threads/{thread}/members +function buildMembers(thread: string): string[] { + return buildThread(thread).concat("members"); +} + +// /v1/threads/{thread}/members/{member} +function buildMember(thread: string, member: string): string[] { + return buildMembers(thread).concat(member); +} + // /v1/users function buildUsers(): string[] { return buildV1().concat("users"); @@ -142,6 +152,10 @@ export function thread(host: string, threadId: string): string { return get(host, joinPath(buildThread(threadId))); } +export function member(host: string, threadId: string, member: string): string { + return get(host, joinPath(buildMember(threadId, member))); +} + export function properties(host: string, threadId: string): string { return get(host, joinPath(buildProperties(threadId))); } From bf339eb850c023917450ab428135cca1c280137e Mon Sep 17 00:00:00 2001 From: Grigoriy Grudinin Date: Fri, 9 Feb 2018 23:40:15 +0300 Subject: [PATCH 5/6] lint fixes --- src/lib/api.ts | 2 +- src/lib/api/add-member.ts | 9 +++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/lib/api.ts b/src/lib/api.ts index 0def282..850fcbc 100644 --- a/src/lib/api.ts +++ b/src/lib/api.ts @@ -1,5 +1,6 @@ import events from "events"; import { acceptContactRequest } from "./api/accept-contact-request"; +import { addMemberToConversation } from "./api/add-member"; import { createConversation } from "./api/create-conversation"; import { declineContactRequest } from "./api/decline-contact-request"; import { getContact } from "./api/get-contact"; @@ -10,7 +11,6 @@ import { sendImage } from "./api/send-image"; import { sendMessage } from "./api/send-message"; import { setConversationTopic } from "./api/set-conversation-topic"; import { setStatus } from "./api/set-status"; -import { addMemberToConversation } from "./api/add-member"; import { ContactsInterface, ContactsService } from "./contacts/contacts"; import * as api from "./interfaces/api/api"; import { Contact as _Contact } from "./interfaces/api/contact"; diff --git a/src/lib/api/add-member.ts b/src/lib/api/add-member.ts index eef7a1a..e159419 100644 --- a/src/lib/api/add-member.ts +++ b/src/lib/api/add-member.ts @@ -1,10 +1,7 @@ import { Incident } from "incident"; import { Context } from "../interfaces/api/context"; import * as io from "../interfaces/http-io"; -import { AllUsers, Members } from "../interfaces/native-api/conversation"; import * as messagesUri from "../messages-uri"; -import { getMembers } from "../utils"; -import { member } from "../messages-uri"; interface RequestBody { role: "User" | "Admin" | string; @@ -15,7 +12,7 @@ export async function addMemberToConversation( apiContext: Context, memberId: string, converstionId: string, - role = 'User', + role = "User", ): Promise { // `https://{host}}/v1/threads/${converstionId}/members/${memberId}`, @@ -27,8 +24,8 @@ export async function addMemberToConversation( cookies: apiContext.cookies, body: JSON.stringify(requestBody), headers: { - RegistrationToken: apiContext.registrationToken.raw, - 'Content-type': 'application/json', + "RegistrationToken": apiContext.registrationToken.raw, + "Content-type": "application/json", }, }; From c8a442a05526f8af020d1ca56a091abf02600c92 Mon Sep 17 00:00:00 2001 From: Charles Samborski Date: Wed, 14 Feb 2018 01:09:20 +0100 Subject: [PATCH 6/6] Minor fixes to createConversation - Use `messagesUri.threads` instead of passing empty threadId to `messagesUri.thread`. - Check for existence of location header and conversation id. --- src/lib/api/create-conversation.ts | 16 +++++++++++----- src/lib/messages-uri.ts | 6 +++++- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/lib/api/create-conversation.ts b/src/lib/api/create-conversation.ts index f7ccd35..0b21e91 100644 --- a/src/lib/api/create-conversation.ts +++ b/src/lib/api/create-conversation.ts @@ -21,7 +21,7 @@ export async function createConversation( members, }; - const uri: string = messagesUri.thread(apiContext.registrationToken.host, ""); + const uri: string = messagesUri.threads(apiContext.registrationToken.host); const requestOptions: io.PostOptions = { uri, @@ -36,12 +36,18 @@ export async function createConversation( const res: io.Response = await io.post(requestOptions); if (res.statusCode !== 201) { - return Promise.reject(new Incident("create-conversation", "Received wrong return code")); + throw new Incident("create-conversation", "Received wrong return code"); } - const location: string = res.headers.location; - const id: any = location.split("/").pop(); - + const location: string | undefined = res.headers.location; + if (location === undefined) { + throw new Incident("create-conversation", "Missing `Location` response header"); + } + // TODO: Parse URL properly / more reliable checks + const id: string | undefined = location.split("/").pop(); + if (id === undefined) { + throw new Incident("create-conversation", "Unable to read conversation ID"); + } // conversation ID return id; } diff --git a/src/lib/messages-uri.ts b/src/lib/messages-uri.ts index b328979..6218dcc 100644 --- a/src/lib/messages-uri.ts +++ b/src/lib/messages-uri.ts @@ -28,7 +28,7 @@ function buildThreads(): string[] { // /v1/threads/{thread} function buildThread(thread: string): string[] { - return thread === "" ? buildThreads() : buildThreads().concat(thread); + return buildThreads().concat(thread); } // /v1/threads/{thread}/properties @@ -148,6 +148,10 @@ function get(host: string, p: string) { return url.resolve(getOrigin(host), p); } +export function threads(host: string): string { + return get(host, joinPath(buildThreads())); +} + export function thread(host: string, threadId: string): string { return get(host, joinPath(buildThread(threadId))); }