implemented most message api functions
parent
bcf00e1cd7
commit
d275848536
26
README.md
26
README.md
|
@ -3,9 +3,14 @@
|
||||||
Pretty Easy Wrapper for Two Cans & String API for version 1.68.
|
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
|
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
|
```py
|
||||||
from pewcans import Client
|
from pewcans import Client
|
||||||
|
@ -15,3 +20,20 @@ res = client.messages.folder_view()
|
||||||
for msg in res.messages:
|
for msg in res.messages:
|
||||||
print(msg.preview)
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
{
|
{
|
||||||
"name": "pewcans",
|
"name": "pecans",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "pewcans",
|
"name": "pecans",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0-only",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^20.8.4",
|
"@types/node": "^20.8.4",
|
||||||
"jsii": "^5.2.14",
|
"jsii": "^5.2.14",
|
||||||
|
|
12
package.json
12
package.json
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "pewcans",
|
"name": "pecans",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Pretty easy wrapper for Two Cans & String API",
|
"description": "Pretty easy Two Cans & String API wrapper",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "jsii --strict",
|
"build": "jsii --strict",
|
||||||
"dist": "jsii --strict && jsii-pacmak",
|
"dist": "jsii --strict && jsii-pacmak",
|
||||||
|
@ -29,8 +29,12 @@
|
||||||
},
|
},
|
||||||
"targets": {
|
"targets": {
|
||||||
"python": {
|
"python": {
|
||||||
"distName": "pewcans",
|
"distName": "pecans",
|
||||||
"module": "pewcans"
|
"module": "pecans"
|
||||||
|
},
|
||||||
|
"dotnet": {
|
||||||
|
"namespace": "Pecans",
|
||||||
|
"packageId": "Pecans"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,37 +1,5 @@
|
||||||
import { MessagesModule } from "./messages";
|
import { MessagesModule } from "./messages";
|
||||||
|
import { MethodCall, TCJSONResponse, TCResponse } from "./types";
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Client for Two Cans & String API.
|
* Client for Two Cans & String API.
|
||||||
|
@ -64,50 +32,41 @@ export class Client {
|
||||||
methodName: string, args: { [key: string]: any }
|
methodName: string, args: { [key: string]: any }
|
||||||
): Promise<T>
|
): Promise<T>
|
||||||
{
|
{
|
||||||
let methodCall: MethodCall = {
|
const methodCall: MethodCall = {
|
||||||
fn: methodName,
|
fn: methodName,
|
||||||
payload: args,
|
payload: args,
|
||||||
};
|
};
|
||||||
|
|
||||||
let body = {
|
const body = {
|
||||||
auth: this.auth,
|
auth: this.auth,
|
||||||
requests: [ methodCall ],
|
requests: [ methodCall ],
|
||||||
};
|
};
|
||||||
|
|
||||||
let res = await this.fetch(body);
|
const res = await this.fetch(body);
|
||||||
|
|
||||||
if (res?.ok) {
|
|
||||||
let methodRes = res.responses[0];
|
|
||||||
return {
|
|
||||||
...methodRes,
|
|
||||||
profiles: res.profiles,
|
|
||||||
} as T;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
ok: false,
|
ok: res?.ok ?? false,
|
||||||
|
...res?.responses[0],
|
||||||
} as T;
|
} as T;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async fetch(body: any): Promise<TCJSONResponse | undefined> {
|
private async fetch(body: any): Promise<TCJSONResponse | undefined> {
|
||||||
let req = {
|
const req = {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"Cookie": "twocansandstring_com_auth2=" + this.auth,
|
"Cookie": "twocansandstring_com_auth2=" + this.auth,
|
||||||
"User-Agent": "pewcans",
|
"User-Agent": "pecans",
|
||||||
},
|
},
|
||||||
body: JSON.stringify(body),
|
body: JSON.stringify(body),
|
||||||
};
|
};
|
||||||
|
|
||||||
let res = await fetch(Client.BASE_URI, req);
|
const res = await fetch(Client.BASE_URI, req);
|
||||||
|
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let json: TCJSONResponse = await res.json() as TCJSONResponse;
|
return await res.json() as TCJSONResponse;
|
||||||
|
|
||||||
return json;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
// hi
|
|
||||||
|
|
||||||
//export * from "./test";
|
|
||||||
export * from "./messages";
|
|
||||||
export * from "./module";
|
export * from "./module";
|
||||||
export * from "./client";
|
export * from "./client";
|
||||||
|
export * as types from "./types";
|
||||||
|
export * from "./messages";
|
||||||
|
export * as messages from "./messages/types";
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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",
|
||||||
|
{ }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
//}
|
|
@ -1,4 +1,4 @@
|
||||||
import { Client } from "./client";
|
import type { Client } from "./client";
|
||||||
|
|
||||||
export class Module {
|
export class Module {
|
||||||
#client: Client;
|
#client: Client;
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue