From d275848536f47926ac29ae327304d82b7c7ede68 Mon Sep 17 00:00:00 2001 From: HumanoidSandvichDispenser Date: Sat, 14 Oct 2023 11:51:02 -0700 Subject: [PATCH] implemented most message api functions --- README.md | 26 +++++- package-lock.json | 6 +- package.json | 12 ++- src/client.ts | 61 ++---------- src/index.ts | 7 +- src/messages.ts | 34 ------- src/messages/index.ts | 54 +++++++++++ src/messages/types.ts | 209 ++++++++++++++++++++++++++++++++++++++++++ src/module.ts | 2 +- src/types/index.ts | 33 +++++++ 10 files changed, 345 insertions(+), 99 deletions(-) delete mode 100644 src/messages.ts create mode 100644 src/messages/index.ts create mode 100644 src/messages/types.ts create mode 100644 src/types/index.ts diff --git a/README.md b/README.md index 06b7921..4bb911f 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,14 @@ Pretty Easy Wrapper for Two Cans & String API for version 1.68. Typescript module that can also be used in Python, .NET, and Java using -[jsii](https://github.com/aws/jsii). +[jsii](https://github.com/aws/jsii). Requires node to be installed to use the +language bindings. -## Example +## Requirements + +- `node` + +## Python Example ```py from pewcans import Client @@ -15,3 +20,20 @@ res = client.messages.folder_view() for msg in res.messages: print(msg.preview) ``` + +## C# Example + +```cs +public class Program +{ + public static void Main(string[] args) + { + var client = new Pecans.Client("AUTH COOKIE HERE"); + var res = client.Messages.FolderView(); + foreach (var msg in res.Messages) + { + Console.WriteLine(msg.Preview); + } + } +} +``` diff --git a/package-lock.json b/package-lock.json index 33a5b7d..f704999 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,13 +1,13 @@ { - "name": "pewcans", + "name": "pecans", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "pewcans", + "name": "pecans", "version": "1.0.0", - "license": "GPL-3.0", + "license": "GPL-3.0-only", "devDependencies": { "@types/node": "^20.8.4", "jsii": "^5.2.14", diff --git a/package.json b/package.json index e7c14ee..5fe9498 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { - "name": "pewcans", + "name": "pecans", "version": "1.0.0", - "description": "Pretty easy wrapper for Two Cans & String API", + "description": "Pretty easy Two Cans & String API wrapper", "scripts": { "build": "jsii --strict", "dist": "jsii --strict && jsii-pacmak", @@ -29,8 +29,12 @@ }, "targets": { "python": { - "distName": "pewcans", - "module": "pewcans" + "distName": "pecans", + "module": "pecans" + }, + "dotnet": { + "namespace": "Pecans", + "packageId": "Pecans" } } }, diff --git a/src/client.ts b/src/client.ts index 2bd2a8f..e22bfe9 100644 --- a/src/client.ts +++ b/src/client.ts @@ -1,37 +1,5 @@ import { MessagesModule } from "./messages"; - -export interface MethodCall { - readonly fn: string; - readonly payload: { [key: string]: any }; -} - -export interface TCJSONResponse { - readonly ok: boolean; - readonly loginId: string; - readonly responses: TCResponse[]; - readonly profiles: TCProfile[]; - readonly auth: string; - readonly ver: string; -} - -export interface TCResponse { - readonly ok: boolean; - readonly profiles: TCProfile[]; -} - -// TODO: move this to another file - -export interface TCUser { - readonly id?: string; - readonly anon?: boolean; -} - -export interface TCProfile { - readonly id: string; - readonly name: string; - readonly online: number; - readonly avatar: string; -} +import { MethodCall, TCJSONResponse, TCResponse } from "./types"; /** * Client for Two Cans & String API. @@ -64,50 +32,41 @@ export class Client { methodName: string, args: { [key: string]: any } ): Promise { - let methodCall: MethodCall = { + const methodCall: MethodCall = { fn: methodName, payload: args, }; - let body = { + const body = { auth: this.auth, requests: [ methodCall ], }; - let res = await this.fetch(body); - - if (res?.ok) { - let methodRes = res.responses[0]; - return { - ...methodRes, - profiles: res.profiles, - } as T; - } + const res = await this.fetch(body); return { - ok: false, + ok: res?.ok ?? false, + ...res?.responses[0], } as T; } private async fetch(body: any): Promise { - let req = { + const req = { method: "POST", headers: { "Content-Type": "application/json", "Cookie": "twocansandstring_com_auth2=" + this.auth, - "User-Agent": "pewcans", + "User-Agent": "pecans", }, body: JSON.stringify(body), }; - let res = await fetch(Client.BASE_URI, req); + const res = await fetch(Client.BASE_URI, req); if (!res.ok) { return; } - let json: TCJSONResponse = await res.json() as TCJSONResponse; - - return json; + return await res.json() as TCJSONResponse; } } diff --git a/src/index.ts b/src/index.ts index b1d92e6..a3cbd5e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,5 @@ -// hi - -//export * from "./test"; -export * from "./messages"; export * from "./module"; export * from "./client"; +export * as types from "./types"; +export * from "./messages"; +export * as messages from "./messages/types"; diff --git a/src/messages.ts b/src/messages.ts deleted file mode 100644 index e75dd92..0000000 --- a/src/messages.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Module } from "./module"; -import { TCResponse, TCUser } from "./client"; - -export interface FolderViewResponse extends TCResponse { - readonly hasMore: boolean; - readonly hasPrevious: boolean; - readonly messages: MessagePreview[]; -} - -export interface MessagePreview { - readonly id: string; - readonly subject: string; - readonly preview: string; - readonly time: number; - readonly users: TCUser[]; -} - -export class MessagesModule extends Module { - public async folderView(folder = "inbox", page = 1): Promise { - let ret = await this.client.call( - "messages.folderview", - { - folder, - page, - } - ); - - if (!ret) { - throw 0; - } - - return ret; - } -} diff --git a/src/messages/index.ts b/src/messages/index.ts new file mode 100644 index 0000000..aeeadea --- /dev/null +++ b/src/messages/index.ts @@ -0,0 +1,54 @@ +import { Module } from "../module"; +import { TCResponse } from "../types"; +import { FolderListResponse, FolderViewResponse, MessageViewResponse } from "./types"; + +export class MessagesModule extends Module { + public async folderView(folder = "inbox", page = 1) { + return await this.client.call( + "messages.folderview", + { + folder, + page, + } + ); + } + + public async view( + conversationId: string, + includeHeader = true, + markAsRead = true, + page = 1 + ) { + return await this.client.call( + "messages.view", + { + conversationId, + includeHeader, + markAsRead, + page, + }, + ); + } + + public async reply( + conversationId: string, + text: string, + unanonymize = false + ) { + return await this.client.call( + "messages.reply", + { + conversationId, + text, + unanonymize, + }, + ); + } + + public async folderList() { + return await this.client.call( + "messages.folderlist", + { } + ); + } +} diff --git a/src/messages/types.ts b/src/messages/types.ts new file mode 100644 index 0000000..4bd6504 --- /dev/null +++ b/src/messages/types.ts @@ -0,0 +1,209 @@ +import { TCResponse, TCUser } from "../types"; + +export interface FolderViewResponse extends TCResponse { + readonly hasMore: boolean; + readonly hasPrevious: boolean; + readonly messages: MessagePreview[]; +} + +export interface MessageViewResponse extends TCResponse { + readonly messages: Message[]; + readonly header: MessageThreadHeader; +} + +export interface MessagePreview { + readonly id: string; + readonly subject: string; + readonly preview: string; + readonly time: number; + readonly users: TCUser[]; + readonly new?: boolean; +} + +export interface Message { + readonly id: number; + readonly member: number; + readonly time: number; + readonly type: string; + readonly html: string; + readonly new?: boolean; +} + +export interface MessageThreadHeader { + readonly title: string; + readonly members: MessageThreadMember[]; + readonly folder: MessageFolder; +} + +export interface MessageThreadMember { + readonly mid: number; + readonly anon?: boolean; + readonly readTo: number; +} + +export interface MessageFolder { + readonly id: string; + readonly name: string; +} + +export interface FolderListResponse extends TCResponse { + readonly folders: Folder[]; +} + +export interface Folder { + readonly id: string; + readonly name: string; +} + +//interface MessagePreviewRaw { +// readonly id: string; +// readonly subject: string; +// readonly preview: string; +// readonly time: number; +// readonly users: TCUser[]; +// readonly new: boolean; +//} +// +//class MessagePreview { +// id: string; +// subject: string; +// preview: string; +// time: number; +// users: TCUser[]; +// isNew: boolean; +// context: Client; +// +// /** @internal */ +// public constructor(context: Client, msg: MessagePreviewRaw) { +// this.context = context; +// this.id = msg.id; +// this.subject = msg.subject; +// this.preview = msg.preview; +// this.time = msg.time; +// this.users = msg.users; +// this.isNew = msg.new; +// } +// +// public open() { +// return this.context.messages.view(this.id); +// } +//} +// +//interface MessageRaw { +// readonly id: number; +// readonly member: number; +// readonly time: number; +// readonly messageType: string; +// readonly html: string; +// readonly new: boolean; +//} +// +//class Message { +// id: number; +// member: number; +// time: number; +// messageType: string; +// html: string; +// isNew: boolean; +// +// /** @internal */ +// public constructor(msg: MessageRaw) { +// this.id = msg.id; +// this.member = msg.member; +// this.time = msg.time; +// this.messageType = msg.messageType; +// this.html = msg.html; +// this.isNew = msg.new; +// } +//} + +//export class Message { +// id: number; +// member: number; +// time: number; +// messageType: string; +// html: string; +// isNew: boolean; +// +// /** @internal */ +// public constructor(msg: TCMessage) { +// this.id = msg.id; +// this.member = msg.member; +// this.time = msg.time; +// this.messageType = msg.messageType; +// this.html = msg.html; +// this.isNew = msg.isNew; +// } +//} +//interface MessagePreview { +// readonly id: string; +// readonly subject: string; +// readonly preview: string; +// readonly time: number; +// readonly users: TCUser[]; +// readonly new: boolean; +//} +// +////export class MessagePreview { +//// id: string; +//// subject: string; +//// preview: string; +//// time: number; +//// users: TCUser[]; +//// isNew: boolean; +//// +//// /** @internal */ +//// public constructor(msg: TCMessagePreview) { +//// this.id = msg.id; +//// this.subject = msg.subject; +//// this.preview = msg.preview; +//// this.time = msg.time; +//// this.users = msg.users; +//// this.isNew = msg.new; +//// } +////} +// +//interface TCMessage { +// readonly id: number; +// readonly member: number; +// readonly time: number; +// readonly messageType: string; +// readonly html: string; +// readonly isNew: boolean; +//} +// +//export class Message { +// id: number; +// member: number; +// time: number; +// messageType: string; +// html: string; +// isNew: boolean; +// +// /** @internal */ +// public constructor(msg: TCMessage) { +// this.id = msg.id; +// this.member = msg.member; +// this.time = msg.time; +// this.messageType = msg.messageType; +// this.html = msg.html; +// this.isNew = msg.isNew; +// } +//} +// +//export interface MessageThreadHeader { +// readonly title: string; +// readonly members: MessageThreadMember[]; +// readonly folder: MessageFolder; +//} +// +//export interface MessageThreadMember { +// readonly mid: number; +// readonly anon?: boolean; +// readonly readTo: number; +//} +// +//export interface MessageFolder { +// readonly id: string; +// readonly name: string; +//} diff --git a/src/module.ts b/src/module.ts index 986431a..e81bc40 100644 --- a/src/module.ts +++ b/src/module.ts @@ -1,4 +1,4 @@ -import { Client } from "./client"; +import type { Client } from "./client"; export class Module { #client: Client; diff --git a/src/types/index.ts b/src/types/index.ts new file mode 100644 index 0000000..ebce9ee --- /dev/null +++ b/src/types/index.ts @@ -0,0 +1,33 @@ +export interface MethodCall { + readonly fn: string; + readonly payload: { [key: string]: any }; +} + +export interface TCJSONResponse { + readonly ok: boolean; + readonly loginId: string; + readonly responses: TCResponse[]; + readonly profiles?: TCProfile[]; + readonly auth: string; + readonly ver: string; +} + +export interface TCResponse { + readonly ok: boolean; + readonly profiles?: TCProfile[]; +} + +// TODO: move this to another file + +export interface TCUser { + readonly id?: string; + readonly anon?: boolean; +} + +export interface TCProfile { + readonly id: string; + readonly name: string; + readonly online: number; + readonly avatar: string; +} +