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.
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
|
@ -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",
|
||||
|
|
12
package.json
12
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"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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 {
|
||||
#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