Skip to content

Commit

Permalink
send messages using a bot, passed unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
TheodoreKrypton committed Jan 27, 2024
1 parent 49b45e1 commit d2fa77e
Show file tree
Hide file tree
Showing 24 changed files with 549 additions and 246 deletions.
8 changes: 7 additions & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,13 @@
"singleQuote": true,
"semi": true,
"plugins": ["@trivago/prettier-plugin-sort-imports"],
"importOrder": ["^telegram", "^[^(telegram|\\.|src/)]", "^src/", "^[\\.]"],
"importOrder": [
"^telegram",
"^telegraf",
"^[^(telegram|telegraf|\\.|src/)]",
"^src/",
"^[\\.]"
],
"importOrderSeparation": true,
"importOrderSortSpecifiers": true
}
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,17 +82,22 @@ Tested WebDAV Clients:

## Step by Step Guide to Set up config

> For feature development purpose, any configuration is **unstable** at the current stage. You may need to reconfigure following any update.
### Automatically:

A config file will be auto-generated when you run the program for the first time. Just follow the instructions to create a Telegram app and a private channel to store the files.

### Manually:

#### First step
#### Preparation

1. Duplicate the `example-config.yaml` file and name it `config.yaml`
2. Go to [Here](https://my.telegram.org/apps), login with your phone number and create a Telegram app.
3. Copy the `api_id` and `api_hash` from the Telegram app page (step 2) to the config file (`telegram -> api_id / api_hash`)

#### Set up account details

1. Go to [Here](https://my.telegram.org/apps), login with your phone number and create a Telegram app.
2. Copy the `api_id` and `api_hash` from the Telegram app page (step 2) to the config file (`telegram -> api_id / api_hash`)

#### Set up the channel to store files

Expand Down
9 changes: 7 additions & 2 deletions src/api/client/directory-api.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import { TelegramClient } from 'telegram';

import { Telegram } from 'telegraf';

import { DirectoryIsNotEmptyError } from 'src/errors/path';
import { TGFSDirectory } from 'src/model/directory';
import { validateName } from 'src/utils/validate-name';

import { MetaDataApi } from './metadata-api';

export class DirectoryApi extends MetaDataApi {
constructor(protected readonly client: TelegramClient) {
super(client);
constructor(
protected readonly account: TelegramClient,
protected readonly bot: Telegram,
) {
super(account, bot);
}

protected async createRootDirectory() {
Expand Down
69 changes: 37 additions & 32 deletions src/api/client/file-api.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import fs from 'fs';

import { TelegramClient } from 'telegram';
import { FileLike } from 'telegram/define';

import fs from 'fs';
import { Telegram } from 'telegraf';

import { TGFSDirectory, TGFSFileRef } from 'src/model/directory';
import { TGFSFileVersion } from 'src/model/file';
Expand All @@ -10,65 +11,69 @@ import { validateName } from 'src/utils/validate-name';
import { DirectoryApi } from './directory-api';

export class FileApi extends DirectoryApi {
constructor(protected readonly client: TelegramClient) {
super(client);
constructor(
protected readonly account: TelegramClient,
protected readonly bot: Telegram,
) {
super(account, bot);
}

private async createFile(
name: string,
where: TGFSDirectory,
fileContent?: FileLike,
fileContent?: string | Buffer,
) {
validateName(name);

const fdMsg = await this.createFileDesc(name, fileContent);
const tgfsFileRef = where.createFileRef(name, fdMsg);
const id = await this.createFileDesc(name, fileContent);
const fr = where.createFileRef(name, id);

await this.syncMetadata();

return tgfsFileRef;
return fr;
}

private async updateFile(
tgfsFileRef: TGFSFileRef,
file?: FileLike,
fr: TGFSFileRef,
file?: string | Buffer,
versionId?: string,
) {
const fd = await this.getFileDesc(tgfsFileRef, false);
const fd = await this.getFileDesc(fr, false);

if (file) {
const uploadFileMsg = await this.sendFile(file);
const id = await this.sendFile(file);

if (!versionId) {
fd.addVersionFromFileMessage(uploadFileMsg);
fd.addVersionFromFileMessageId(id);
} else {
const tgfsFileVersion = fd.getVersion(versionId);
tgfsFileVersion.messageId = uploadFileMsg.id;
fd.updateVersion(tgfsFileVersion);
const fv = fd.getVersion(versionId);
fv.messageId = id;

fd.updateVersion(fv);
}
} else {
if (!versionId) {
fd.addEmptyVersion();
} else {
const tgfsFileVersion = fd.getVersion(versionId);
tgfsFileVersion.messageId = TGFSFileVersion.EMPTY_FILE;
fd.updateVersion(tgfsFileVersion);
const fv = fd.getVersion(versionId);
fv.setInvalid();
fd.updateVersion(fv);
}
}

await this.updateFileDesc(tgfsFileRef, fd);
await this.updateFileDesc(fr, fd);

return tgfsFileRef;
return fr;
}

public async deleteFile(tgfsFileRef: TGFSFileRef, version?: string) {
public async deleteFile(fr: TGFSFileRef, version?: string) {
if (!version) {
tgfsFileRef.delete();
fr.delete();
await this.syncMetadata();
} else {
const fd = await this.getFileDesc(tgfsFileRef, false);
const fd = await this.getFileDesc(fr, false);
fd.deleteVersion(version);
await this.updateFileDesc(tgfsFileRef, fd);
await this.updateFileDesc(fr, fd);
}
}

Expand All @@ -78,7 +83,7 @@ export class FileApi extends DirectoryApi {
under: TGFSDirectory;
versionId?: string;
},
file?: FileLike,
file?: string | Buffer,
) {
const fr = where.under.findFiles([where.name])[0];
if (fr) {
Expand All @@ -101,28 +106,28 @@ export class FileApi extends DirectoryApi {
}

public async downloadLatestVersion(
fileRef: TGFSFileRef,
fr: TGFSFileRef,
asName: string,
outputFile?: string | fs.WriteStream,
): Promise<Buffer> {
const fileDesc = await this.getFileDesc(fileRef);
const fd = await this.getFileDesc(fr);
let res = Buffer.from('');
if (fileDesc.isEmptyFile()) {
if (fd.isEmptyFile()) {
this.writeContent(res, outputFile);
} else {
const version = fileDesc.getLatest();
const version = fd.getLatest();
return await this.downloadFileVersion(version, asName, outputFile);
}
return res;
}

public async downloadFileVersion(
fileVersion: TGFSFileVersion,
fv: TGFSFileVersion,
asName: string,
outputFile?: string | fs.WriteStream,
): Promise<Buffer> {
const res = await this.downloadFile({
messageId: fileVersion.messageId,
messageId: fv.messageId,
name: asName,
});
if (outputFile) {
Expand Down
36 changes: 23 additions & 13 deletions src/api/client/file-desc-api.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,29 @@
import { Api, TelegramClient } from 'telegram';
import { FileLike } from 'telegram/define';
import { TelegramClient } from 'telegram';

import { Telegram } from 'telegraf';

import { TGFSFileRef } from 'src/model/directory';
import { TGFSFile } from 'src/model/file';

import { MessageApi } from './message-api';

export class FileDescApi extends MessageApi {
constructor(protected readonly client: TelegramClient) {
super(client);
constructor(
protected readonly account: TelegramClient,
protected readonly bot: Telegram,
) {
super(account, bot);
}

public async createFileDesc(
name: string,
fileContent?: FileLike,
): Promise<Api.Message> {
fileContent?: string | Buffer,
): Promise<number> {
const tgfsFile = new TGFSFile(name);

if (fileContent) {
const uploadFileMsg = await this.sendFile(fileContent);
tgfsFile.addVersionFromFileMessage(uploadFileMsg);
const id = await this.sendFile(fileContent);
tgfsFile.addVersionFromFileMessageId(id);
} else {
tgfsFile.addEmptyVersion();
}
Expand All @@ -32,6 +36,7 @@ export class FileDescApi extends MessageApi {
withVersionInfo: boolean = true,
): Promise<TGFSFile> {
const message = (await this.getMessagesByIds([fileRef.getMessageId()]))[0];

const fileDesc = TGFSFile.fromObject(JSON.parse(message.text));

if (withVersionInfo) {
Expand All @@ -47,16 +52,21 @@ export class FileDescApi extends MessageApi {

nonEmptyVersions.forEach((version, i) => {
const fileMessage = fileMessages[i];
version.size = Number(fileMessage.document.size);
if (fileMessage) {
version.size = Number(fileMessage.document.size);
} else {
version.setInvalid();
}
});
}

return fileDesc;
}

public async updateFileDesc(fr: TGFSFileRef, fd: TGFSFile) {
return await this.editMessage(fr.getMessageId(), {
text: JSON.stringify(fd.toObject()),
});
public async updateFileDesc(fr: TGFSFileRef, fd: TGFSFile): Promise<number> {
return await this.editMessageText(
fr.getMessageId(),
JSON.stringify(fd.toObject()),
);
}
}
9 changes: 7 additions & 2 deletions src/api/client/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import { TelegramClient } from 'telegram';

import { Telegram } from 'telegraf';

import { FileApi } from './file-api';

export class Client extends FileApi {
constructor(protected readonly client: TelegramClient) {
super(client);
constructor(
protected readonly account: TelegramClient,
protected readonly bot: Telegram,
) {
super(account, bot);
}

public async init() {
Expand Down
Loading

0 comments on commit d2fa77e

Please sign in to comment.