Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Features/create telegram bot #2

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"cors": "^2.8.5",
"dotenv": "16.3.1",
"express": "^4.18.2",
"grammy": "^1.31.3",
"matrix-bot-sdk": "^0.7.0",
"openai": "^4.71.0",
"showdown": "^2.1.0",
Expand Down
4 changes: 3 additions & 1 deletion src/adapters/base.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import showdown from "showdown";
import { BaseBot } from "../bots/@base";

export interface BaseAdapterOptions {
Expand All @@ -7,9 +8,10 @@ export interface BaseAdapterOptions {

export abstract class BaseAdapter {
bot: BaseBot;
markdownConverter: showdown.Converter;

constructor(options: BaseAdapterOptions) {
//
this.markdownConverter = new showdown.Converter();
}

connectBot(bot: BaseBot) {
Expand Down
73 changes: 38 additions & 35 deletions src/adapters/matrix.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { AutojoinRoomsMixin, MatrixAuth, MatrixClient } from "matrix-bot-sdk";
import OpenAI from 'openai';
import {
AutojoinRoomsMixin,
MatrixAuth,
MatrixClient
} from "matrix-bot-sdk";

import { VerifiedAccounts } from "../backend/VerifiedAccounts";
import {
MATRIX_BOT_HOME_SERVER_URL,
OPENAI_API_KEY
} from "../config";
import { MATRIX_BOT_HOME_SERVER_URL } from "../config";
import {
getRoomMetadata,
IMDirect,
Expand All @@ -26,7 +26,6 @@ export class MatrixAdapter extends BaseAdapter {
client: MatrixClient;
options: MatrixAdapterOptions;


constructor(options: MatrixAdapterOptions) {
super(options);

Expand Down Expand Up @@ -95,7 +94,6 @@ export class MatrixAdapter extends BaseAdapter {
}

const currentUserId = await this.client.getUserId();

if (event["sender"] === currentUserId) {
return;
}
Expand All @@ -105,36 +103,39 @@ export class MatrixAdapter extends BaseAdapter {
console.info("room.message->event ::", event);
const taggedAccounts: IAccount[] = [];

let users = []
if (event["content"]["formatted_body"]) {
// parse users using regex
const users = event["content"]["formatted_body"].match(
users = event["content"]["formatted_body"].match(
/<a href=".*?">(.*?)<\/a>/g,
);
if (users?.length) {
// map users and extract the name and id that is after /user/@ from the href
for (const user of users) {
const [name] = user
.replace(/<a href=".*?">/, "")
.replace(/<\/a>/, "")
.split("/user/@");

/**
* need to extract @tsvetan:superhero.com
* from <a href="https://chat.superhero.com/#/user/@tsvetan:superhero.com">
*/
const id = user.replace(/<a href=".*?#\/user\//, "").split('">')[0];

const address = VerifiedAccounts.getVerifiedAccountOrUndefined(id)
if (address) {
messageBody = messageBody.replace(name, address);
}

taggedAccounts.push({
name,
id,
address,
});
}

if (users?.length) {
// map users and extract the name and id that is after /user/@ from the href
for (const user of users) {
const [name] = user
.replace(/<a href=".*?">/, "")
.replace(/<\/a>/, "")
.split("/user/@");

/**
* need to extract @tsvetan:superhero.com
* from <a href="https://chat.superhero.com/#/user/@tsvetan:superhero.com">
*/
const id = user.replace(/<a href=".*?#\/user\//, "").split('">')[0];

const address = VerifiedAccounts.getVerifiedAccountOrUndefined(id);

if (address) {
messageBody = messageBody.replace(name, address);
}

taggedAccounts.push({
name,
id,
address,
});
}
}

Expand All @@ -157,19 +158,21 @@ export class MatrixAdapter extends BaseAdapter {
sender,
message,
(reply) => {
this.client.replyHtmlNotice(roomId, event, reply);
const htmlContent = this.markdownConverter.makeHtml(reply);
this.client.replyHtmlNotice(roomId, event, htmlContent);
this.client.setTyping(roomId, false);
return reply;
},
(isTyping) => {
this.client.setTyping(roomId, isTyping);
}
},
);
});

this.client.on("room.join", async (roomId: string, event: IChatEvent) => {
// save meta data
const metaData = await this.getMetaData(roomId);
console.log("room.join event", event);

const reply = await this.bot.onRoomJoin(roomId, event, metaData);
if (reply) {
Expand Down
101 changes: 101 additions & 0 deletions src/adapters/telegram.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { Bot, InlineKeyboard } from "grammy";

import { IMessage, ISender } from "../types";
import { BaseAdapter } from "./base";
import { BaseBot } from "src/bots/@base";

type TelegramAdapterOptions = {
token?: string;
};

export class TelegramAdapter extends BaseAdapter {
client: Bot;
token: TelegramAdapterOptions;

constructor(token: TelegramAdapterOptions) {
super(token);
if (!token) {
throw new Error(
"Telegram bot token is undefined, please set TELEGRAM_BOT_TOKEN",
);
}
this.client = new Bot(token?.token);

if (!token) {
console.warn(
"No access token provided through environment. Please PERMANENTLY store the access token in an the environment variable.",
);
}

this.token = token;
}

connectBot(bot: BaseBot): this {
this.bot = bot;
const commands = [];

Object.values(bot.commands).forEach((command) => {
commands.push({
command: command.name,
description: command.description,
});
});
this.client.api.setMyCommands(commands);
return this;
}

async init({ autoJoin }: { autoJoin?: boolean } = { autoJoin: true }) {
this.client.command("start", async (ctx) => {
await ctx.reply("Welcome!");
});

this.client.on("message", (ctx) => {
const sender: ISender = {
id: ctx.message.from.id.toString(),
name: ctx.message.from.username || ctx.message.from.first_name,
isDirect: true,
};
const message: IMessage = {
chatId: ctx.message.from.id.toString(), // TODO
text: ctx.message.text,
};
console.log("========");
console.log("ctx", ctx);
console.log("========");
// const message = ctx.message;
console.log("message", message);
console.log("========");
if (!this.bot) {
return;
}

this.bot.onMessage(
sender,
message,
(reply) => {
console.log("========== BOT REPLY ==========");
console.log(reply);
ctx.reply(reply, {
parse_mode: "Markdown",
});

return reply;
},
(isTyping) => {
if (isTyping) {
ctx.replyWithChatAction("typing");
}
},
);
});

this.client.start();

console.log("TelegramBot started");
return this.client;
}

sendMessage(text: string, chatId?: string): Promise<void> {
throw new Error("Method not implemented.");
}
}
6 changes: 3 additions & 3 deletions src/backend/Aeternity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class Aex9Token extends BaseContract {

export type VerifiedAccountsMap = Map<string, Encoded.AccountAddress>;

class VerifiedAccounts extends BaseContract {
class AeVerifiedAccounts extends BaseContract {
public async getAllVerifiedAccounts() {
return this.contract
.verified_accounts()
Expand All @@ -91,7 +91,7 @@ class VerifiedAccounts extends BaseContract {

export default class Aeternity {
private static aeSdk: AeSdk;
private static _verifiedAccounts: VerifiedAccounts;
private static _verifiedAccounts: AeVerifiedAccounts;
private static _aex9TokenMap: Map<Encoded.ContractAddress, Aex9Token> =
new Map();

Expand Down Expand Up @@ -184,7 +184,7 @@ export default class Aeternity {
contract.$options.address,
);

this._verifiedAccounts = new VerifiedAccounts(contract);
this._verifiedAccounts = new AeVerifiedAccounts(contract);
return this._verifiedAccounts;
}
}
Loading