Skip to content

Commit

Permalink
Merge pull request #140 from Agadar/send-files
Browse files Browse the repository at this point in the history
Implement sending files via plugin
  • Loading branch information
Agadar authored Jun 20, 2022
2 parents 7bce5b0 + 8d13233 commit 7d0aad9
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 10 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,5 @@ typings/

*.js
.idea/
.vscode/settings.json
.vscode/settings.json
tmp/
10 changes: 9 additions & 1 deletion src/danktimesbot-controller/danktimesbot-controller-mock.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import TelegramBot from "node-telegram-bot-api";
import TelegramBot, { File } from "node-telegram-bot-api";
import { Chat } from "../chat/chat";
import { CustomEventArguments } from "../plugin-host/plugin-events/event-arguments/custom-event-arguments";
import { AbstractPlugin } from "../plugin-host/plugin/plugin";
Expand Down Expand Up @@ -65,4 +65,12 @@ export class DankTimesBotControllerMock implements IDankTimesBotController {
public onPluginWantsToGetOtherPlugins(callingPlugin: AbstractPlugin): AbstractPlugin[] {
return [];
}

onPluginWantsToRetrieveFile(chatId: number, fileId: string): Promise<string | void> {
return Promise.resolve();
}

onPluginWantsToSendFile(chatId: number, filePath: string, replyToMessageId: number, forceReply: boolean): Promise<void | TelegramBot.Message> {
return Promise.resolve();
}
}
18 changes: 16 additions & 2 deletions src/danktimesbot-controller/danktimesbot-controller.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import moment from "moment";
import TelegramBot from "node-telegram-bot-api";
import TelegramBot, { File } from "node-telegram-bot-api";
import { IChatRegistry } from "../chat-registry/i-chat-registry";
import { Chat } from "../chat/chat";
import { IDankTimeScheduler } from "../dank-time-scheduler/i-dank-time-scheduler";
Expand Down Expand Up @@ -115,10 +115,24 @@ export class DankTimesBotController implements IDankTimesBotController {
/**
* From IPluginListener.
*/
public onPluginWantsToParseScoreInput(input: string): number | null {
public onPluginWantsToParseScoreInput(input: string): number | null {
return this.util.parseScoreInput(input);
}

/**
* From IPluginListener.
*/
onPluginWantsToRetrieveFile(chatId: number, fileId: string): Promise<string | void> {
return this.telegramClient.retrieveFile(chatId, fileId);
}

/**
* From IPluginListener.
*/
onPluginWantsToSendFile(chatId: number, filePath: string, replyToMessageId: number, forceReply: boolean): Promise<void | TelegramBot.Message> {
return this.telegramClient.sendFile(chatId, filePath, replyToMessageId, forceReply);
}

/**
* From IPluginListener.
*/
Expand Down
18 changes: 17 additions & 1 deletion src/plugin-host/plugin/plugin-listener.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import TelegramBot from "node-telegram-bot-api";
import TelegramBot, { File, PhotoSize } from "node-telegram-bot-api";
import { Chat } from "../../chat/chat";
import { CustomEventArguments } from "../plugin-events/event-arguments/custom-event-arguments";
import { AbstractPlugin } from "./plugin";
Expand All @@ -18,13 +18,29 @@ export interface IPluginListener {
onPluginWantsToSendChatMessage(chatId: number, htmlMessage: string,
replyToMessageId: number, forceReply: boolean): Promise<void | TelegramBot.Message>;

/**
* Fired when a plugin wants to send a file / photo to a chat.
* @param chatId Chat to send photo to
* @param filePath Path to the file on disk to send
* @param replyToMessageId Message to respond to
* @param forceReply Whether to force the replied-to or tagged user to reply to this message
*/
onPluginWantsToSendFile(chatId: number, filePath: string, replyToMessageId: number, forceReply: boolean): Promise<void | TelegramBot.Message>;

/**
* Fired when a plugin wants to delete a chat message.
* @param chatId The id of the chat to delete a message in.
* @param messageId The id of the message to delete.
*/
onPluginWantsToDeleteChatMessage(chatId: number, messageId: number): Promise<void | boolean>;

/**
* Fired when a plugin wants to delete a file. This is likely to be a photo.
* @param chatId The id of the chat to retrieve a file from.
* @param fileId Id of the file to retrieve.
*/
onPluginWantsToRetrieveFile(chatId: number, fileId: string): Promise<string | void>;

/**
* Fired when a plugin wants to edit a chat message.
* @param chatId The id of the chat to edit a message in.
Expand Down
24 changes: 22 additions & 2 deletions src/plugin-host/plugin/plugin.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import TelegramBot from "node-telegram-bot-api";
import TelegramBot, { File, PhotoSize } from "node-telegram-bot-api";
import { BotCommand } from "../../bot-commands/bot-command";
import { Chat } from "../../chat/chat";
import { ChatSettingTemplate } from "../../chat/settings/chat-setting-template";
Expand Down Expand Up @@ -173,6 +173,17 @@ export abstract class AbstractPlugin {
return this.listener.onPluginWantsToSendChatMessage(chatId, htmlMessage, replyToMessageId, forceReply);
}

/**
* Sends a file to the Telegram Bot API.
* @param chatId The id of the chat to send a message to.
* @param filePath The path to the file we want to send.
* @param replyToMessageId The (optional) id of the message to reply to.
* @param forceReply Whether to force the replied-to or tagged user to reply to this message.
*/
protected sendFile(chatId: number, filePath: string, replyToMessageId = -1, forceReply = false): Promise<void | TelegramBot.Message> {
return this.listener.onPluginWantsToSendFile(chatId, filePath, replyToMessageId, forceReply);
}

/**
* Deletes a message via the Telegram Bot API.
* @param chatId The id of the chat to delete a message in.
Expand All @@ -182,6 +193,15 @@ export abstract class AbstractPlugin {
return this.listener.onPluginWantsToDeleteChatMessage(chatId, messageId);
}

/**
* Retrieves a file from the Telegram Bot API.
* @param chatId The id of the chat to retrieve a file from.
* @param fileId Id of the file to retrieve.
*/
protected retrieveFile(chatId: number, fileId: string): Promise<string | void> {
return this.listener.onPluginWantsToRetrieveFile(chatId, fileId);
}

/**
* Edits a message via the Telegram Bot API.
* @param chatId The id of the chat to edit a message in.
Expand All @@ -200,7 +220,7 @@ export abstract class AbstractPlugin {
return this.listener.onPluginWantsToGetChat(chatId);
}

/**
/**
* Parses the score input, returning a number if a number could be determined,
* otherwise returns null.
* @param input The string input to cleanse to a number.
Expand Down
18 changes: 17 additions & 1 deletion src/telegram-client/i-telegram-client.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import TelegramBot from "node-telegram-bot-api";
import TelegramBot, { File } from "node-telegram-bot-api";
import { ITelegramClientListener } from "./i-telegram-client-listener";

/**
Expand Down Expand Up @@ -61,4 +61,20 @@ export interface ITelegramClient {
* @return The administrators of the specified chat.
*/
getChatAdministrators(chatId: number): Promise<TelegramBot.ChatMember[]>;

/**
* retrieves a file with given id from a chat.
* @param chatId Id of the chat to retrieve the file from.
* @param fileId Id of the file.
*/
retrieveFile(chatId: number, fileId: string): Promise<string | void>;

/**
* Send a file or photo to a chat.
* @param chatId Id of the chat to send the file to.
* @param filePath Local path to the file on disk.
* @param replyToMessageId The (optional) id of the message to reply to.
* @param forceReply Whether to force the replied-to or tagged user to reply to this message. False by default.
*/
sendFile(chatId: number, filePath: string, replyToMessageId: number, forceReply: boolean): Promise<TelegramBot.Message | void>;
}
10 changes: 9 additions & 1 deletion src/telegram-client/telegram-client-mock.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import TelegramBot from "node-telegram-bot-api";
import TelegramBot, { File } from "node-telegram-bot-api";
import { ITelegramClient } from "./i-telegram-client";
import { ITelegramClientListener } from "./i-telegram-client-listener";

Expand Down Expand Up @@ -45,4 +45,12 @@ export class TelegramClientMock implements ITelegramClient {
},
}]);
}

public async retrieveFile(chatId: number, fileId: string): Promise<string | void> {
// Don't do anything, this is a mock.
}

public async sendFile(chatId: number, filePath: string, replyToMessageId: number, forceReply: boolean): Promise<TelegramBot.Message | void> {
// Don't do anything, this is a mock
}
}
28 changes: 27 additions & 1 deletion src/telegram-client/telegram-client.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import TelegramBot from "node-telegram-bot-api";
import fs from "fs";
import TelegramBot, { File, PhotoSize } from "node-telegram-bot-api";
import { ITelegramClient } from "./i-telegram-client";
import { ITelegramClientListener } from "./i-telegram-client-listener";

Expand Down Expand Up @@ -52,6 +53,31 @@ export class TelegramClient implements ITelegramClient {
});
}

public retrieveFile(chatId: number, fileId: string): Promise<string | void> {
if (!fs.existsSync("./tmp/dtb")) {
fs.mkdir("./tmp/dtb", {recursive: true}, err => {
this.listeners.forEach((listener) => listener.onErrorFromApi(chatId, "Could not create file location"));
});
}
return this.bot.downloadFile(fileId, "./tmp/dtb")
.catch((reason: void | TelegramBot.Message) => {
this.listeners.forEach((listener) => listener.onErrorFromApi(chatId, reason));
});
}

public sendFile(chatId: number, filePath: string, replyToMessageId: number, forceReply: boolean): Promise<TelegramBot.Message | void> {
if (!fs.existsSync(filePath)) {
this.listeners.forEach((listener) => listener.onErrorFromApi(chatId, "File does not exist!"));
return new Promise(() => {
return;
});
} else {
return this.bot.sendPhoto(chatId, filePath, {
reply_to_message_id: replyToMessageId,
}).catch((reason: void | TelegramBot.Message) => { this.listeners.forEach((listener) => listener.onErrorFromApi(chatId, reason)); });
}
}

public subscribe(subscriber: ITelegramClientListener): void {
if (this.listeners.indexOf(subscriber) === -1) {
this.listeners.push(subscriber);
Expand Down

0 comments on commit 7d0aad9

Please sign in to comment.