implemented most message api functions

master
John Montagu, the 4th Earl of Sandvich 2023-10-14 11:51:02 -07:00
parent bcf00e1cd7
commit d275848536
Signed by: sandvich
GPG Key ID: 9A39BE37E602B22D
10 changed files with 345 additions and 99 deletions

View File

@ -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);
}
}
}
```

6
package-lock.json generated
View File

@ -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",

View File

@ -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"
}
}
},

View File

@ -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<T>
{
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<TCJSONResponse | undefined> {
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;
}
}

View File

@ -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";

View File

@ -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<FolderViewResponse> {
let ret = await this.client.call<FolderViewResponse>(
"messages.folderview",
{
folder,
page,
}
);
if (!ret) {
throw 0;
}
return ret;
}
}

View File

@ -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<FolderViewResponse>(
"messages.folderview",
{
folder,
page,
}
);
}
public async view(
conversationId: string,
includeHeader = true,
markAsRead = true,
page = 1
) {
return await this.client.call<MessageViewResponse>(
"messages.view",
{
conversationId,
includeHeader,
markAsRead,
page,
},
);
}
public async reply(
conversationId: string,
text: string,
unanonymize = false
) {
return await this.client.call<TCResponse>(
"messages.reply",
{
conversationId,
text,
unanonymize,
},
);
}
public async folderList() {
return await this.client.call<FolderListResponse>(
"messages.folderlist",
{ }
);
}
}

View File

@ -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;
//}

View File

@ -1,4 +1,4 @@
import { Client } from "./client";
import type { Client } from "./client";
export class Module {
#client: Client;

33
src/types/index.ts 100644
View File

@ -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;
}