44 * Consolidates both interactive commands and notification sending capabilities.
55 */
66
7- import { Telegraf , Markup } from 'telegraf' ;
7+ import { Markup } from 'telegraf' ;
88import { WELCOME_MESSAGE , HELP_MESSAGE , DAOS_BUTTON_TEXT , LEARN_MORE_BUTTON_TEXT , MY_WALLETS_BUTTON_TEXT } from '../messages' ;
99import { DAOService } from '../services/dao.service' ;
1010import { WalletService } from '../services/wallet.service' ;
1111import { ExplorerService } from '../services/explorer.service' ;
1212import { EnsResolverService } from '../services/ens-resolver.service' ;
13- import { ContextWithSession } from '../interfaces/bot.interface' ;
13+ import { ContextWithSession , MatchedContext } from '../interfaces/bot.interface' ;
1414import { NotificationPayload } from '../interfaces/notification.interface' ;
15+ import { TelegramClientInterface } from '../interfaces/telegram-client.interface' ;
1516
1617export class TelegramBotService {
17- private bot : Telegraf < ContextWithSession > ;
18+ private telegramClient : TelegramClientInterface ;
1819 private daoService : DAOService ;
1920 private walletService : WalletService ;
2021 private explorerService : ExplorerService ;
2122 private ensResolver : EnsResolverService ;
2223
2324 constructor (
24- bot : Telegraf < ContextWithSession > ,
25+ telegramClient : TelegramClientInterface ,
2526 daoService : DAOService ,
2627 walletService : WalletService ,
2728 explorerService : ExplorerService ,
2829 ensResolver : EnsResolverService
2930 ) {
30- this . bot = bot ;
31+ this . telegramClient = telegramClient ;
3132 this . daoService = daoService ;
3233 this . walletService = walletService ;
3334 this . explorerService = explorerService ;
@@ -48,75 +49,78 @@ export class TelegramBotService {
4849 }
4950
5051 private setupCommands ( ) : void {
51- this . bot . command ( / ^ s t a r t $ / i, async ( ctx ) => {
52- await ctx . reply ( WELCOME_MESSAGE , this . createPersistentKeyboard ( ) ) ;
53- } ) ;
52+ this . telegramClient . setupHandlers ( ( handlers ) => {
53+ handlers . command ( / ^ s t a r t $ / i, async ( ctx ) => {
54+ await ctx . reply ( WELCOME_MESSAGE , this . createPersistentKeyboard ( ) ) ;
55+ } ) ;
5456
55- this . bot . command ( / ^ l e a r n _ m o r e $ / i, async ( ctx ) => {
56- await ctx . reply ( HELP_MESSAGE , {
57- parse_mode : 'HTML' ,
58- ...this . createPersistentKeyboard ( )
57+ handlers . command ( / ^ l e a r n _ m o r e $ / i, async ( ctx ) => {
58+ await ctx . reply ( HELP_MESSAGE , {
59+ parse_mode : 'HTML' ,
60+ ...this . createPersistentKeyboard ( )
61+ } ) ;
5962 } ) ;
60- } ) ;
6163
62- this . bot . command ( / ^ d a o s $ / i, async ( ctx ) => {
63- await this . daoService . initialize ( ctx ) ;
64- } ) ;
64+ handlers . command ( / ^ d a o s $ / i, async ( ctx ) => {
65+ await this . daoService . initialize ( ctx ) ;
66+ } ) ;
6567
66- this . bot . command ( / ^ w a l l e t s $ / i, async ( ctx ) => {
67- await this . walletService . initialize ( ctx ) ;
68- } ) ;
68+ handlers . command ( / ^ w a l l e t s $ / i, async ( ctx ) => {
69+ await this . walletService . initialize ( ctx ) ;
70+ } ) ;
6971
70- this . bot . hears ( DAOS_BUTTON_TEXT , async ( ctx ) => {
71- await this . daoService . initialize ( ctx ) ;
72- } ) ;
72+ handlers . hears ( DAOS_BUTTON_TEXT , async ( ctx ) => {
73+ await this . daoService . initialize ( ctx ) ;
74+ } ) ;
7375
74- this . bot . hears ( MY_WALLETS_BUTTON_TEXT , async ( ctx ) => {
75- await this . walletService . initialize ( ctx ) ;
76- } ) ;
76+ handlers . hears ( MY_WALLETS_BUTTON_TEXT , async ( ctx ) => {
77+ await this . walletService . initialize ( ctx ) ;
78+ } ) ;
7779
78- this . bot . hears ( LEARN_MORE_BUTTON_TEXT , async ( ctx ) => {
79- await ctx . reply ( HELP_MESSAGE , {
80- parse_mode : 'HTML' ,
81- ...this . createPersistentKeyboard ( )
80+ handlers . hears ( LEARN_MORE_BUTTON_TEXT , async ( ctx ) => {
81+ await ctx . reply ( HELP_MESSAGE , {
82+ parse_mode : 'HTML' ,
83+ ...this . createPersistentKeyboard ( )
84+ } ) ;
8285 } ) ;
83- } ) ;
8486
85- this . bot . action ( / ^ d a o _ t o g g l e _ ( \w + ) $ / , async ( ctx ) => {
86- const daoName = ctx . match [ 1 ] ;
87- await this . daoService . toggle ( ctx , daoName ) ;
88- await ctx . answerCbQuery ( ) ;
89- } ) ;
87+ handlers . action ( / ^ d a o _ t o g g l e _ ( \w + ) $ / , async ( ctx ) => {
88+ const matchedCtx = ctx as MatchedContext ;
89+ const daoName = matchedCtx . match [ 1 ] ;
90+ await this . daoService . toggle ( ctx , daoName ) ;
91+ await ctx . answerCbQuery ( ) ;
92+ } ) ;
9093
91- this . bot . action ( / ^ d a o _ c o n f i r m $ / , async ( ctx ) => {
92- await this . daoService . confirm ( ctx ) ;
93- await ctx . answerCbQuery ( ) ;
94- } ) ;
94+ handlers . action ( / ^ d a o _ c o n f i r m $ / , async ( ctx ) => {
95+ await this . daoService . confirm ( ctx ) ;
96+ await ctx . answerCbQuery ( ) ;
97+ } ) ;
9598
96- // Wallet action handlers
97- this . bot . action ( / ^ w a l l e t _ a d d $ / , async ( ctx ) => {
98- await this . walletService . addWallet ( ctx ) ;
99- await ctx . answerCbQuery ( ) ;
100- } ) ;
99+ // Wallet action handlers
100+ handlers . action ( / ^ w a l l e t _ a d d $ / , async ( ctx ) => {
101+ await this . walletService . addWallet ( ctx ) ;
102+ await ctx . answerCbQuery ( ) ;
103+ } ) ;
101104
102- this . bot . action ( / ^ w a l l e t _ r e m o v e $ / , async ( ctx ) => {
103- await this . walletService . removeWallet ( ctx ) ;
104- await ctx . answerCbQuery ( ) ;
105- } ) ;
105+ handlers . action ( / ^ w a l l e t _ r e m o v e $ / , async ( ctx ) => {
106+ await this . walletService . removeWallet ( ctx ) ;
107+ await ctx . answerCbQuery ( ) ;
108+ } ) ;
106109
107- this . bot . action ( / ^ w a l l e t _ t o g g l e _ ( .+ ) $ / , async ( ctx ) => {
108- const address = ctx . match [ 1 ] ;
109- await this . walletService . toggleWalletForRemoval ( ctx , address ) ;
110- await ctx . answerCbQuery ( ) ;
111- } ) ;
110+ handlers . action ( / ^ w a l l e t _ t o g g l e _ ( .+ ) $ / , async ( ctx ) => {
111+ const matchedCtx = ctx as MatchedContext ;
112+ const address = matchedCtx . match [ 1 ] ;
113+ await this . walletService . toggleWalletForRemoval ( ctx , address ) ;
114+ await ctx . answerCbQuery ( ) ;
115+ } ) ;
112116
113- this . bot . action ( / ^ w a l l e t _ c o n f i r m _ r e m o v e $ / , async ( ctx ) => {
114- await this . walletService . confirmRemoval ( ctx ) ;
115- await ctx . answerCbQuery ( ) ;
116- } ) ;
117+ handlers . action ( / ^ w a l l e t _ c o n f i r m _ r e m o v e $ / , async ( ctx ) => {
118+ await this . walletService . confirmRemoval ( ctx ) ;
119+ await ctx . answerCbQuery ( ) ;
120+ } ) ;
117121
118- this . bot . on ( 'message' , async ( ctx , next ) => {
119- if ( 'text' in ctx . message && ! ctx . message . text . startsWith ( '/' ) ) {
122+ handlers . on ( 'message' , async ( ctx , next ) => {
123+ if ( ctx . message && 'text' in ctx . message && ! ctx . message . text . startsWith ( '/' ) ) {
120124 if ( ctx . session ?. awaitingWalletInput ) {
121125 await this . walletService . processWalletInput ( ctx , ctx . message . text ) ;
122126 return ;
@@ -126,16 +130,16 @@ export class TelegramBotService {
126130 this . createPersistentKeyboard ( ) ) ;
127131 }
128132 return next ( ) ;
133+ } ) ;
129134 } ) ;
130135 }
131136
132137 async launch ( ) : Promise < void > {
133- await this . bot . launch ( ) ;
134- console . log ( '🤖 Bot is running...' ) ;
138+ await this . telegramClient . launch ( ) ;
135139 }
136140
137141 public stop ( signal : string ) : void {
138- this . bot . stop ( signal ) ;
142+ this . telegramClient . stop ( signal ) ;
139143 }
140144
141145 /**
@@ -147,12 +151,15 @@ export class TelegramBotService {
147151 public async sendNotification ( payload : NotificationPayload ) : Promise < string > {
148152 let processedMessage = payload . message ;
149153
150- // Process transaction link if transaction metadata is provided
151- if ( payload . metadata ?. transaction ) {
152- const { hash, chainId } = payload . metadata . transaction ;
153- const txUrl = this . explorerService . getTransactionLink ( chainId , hash ) ;
154- const markdownLink = `[Transaction details](${ txUrl } )` ;
155- processedMessage = processedMessage . replace ( '{{txLink}}' , markdownLink ) ;
154+ // Process transaction link placeholder
155+ if ( processedMessage . includes ( '{{txLink}}' ) ) {
156+ const txUrl = payload . metadata ?. transaction
157+ ? this . explorerService . getTransactionLink ( payload . metadata . transaction . chainId , payload . metadata . transaction . hash )
158+ : null ;
159+
160+ processedMessage = txUrl
161+ ? processedMessage . replace ( '{{txLink}}' , `[Transaction details](${ txUrl } )` )
162+ : processedMessage . replace ( '\n\n{{txLink}}' , '' ) ;
156163 }
157164
158165 // Process ENS names if addresses are provided in metadata
@@ -163,10 +170,13 @@ export class TelegramBotService {
163170 }
164171 }
165172
166- const sentMessage = await this . bot . telegram . sendMessage (
173+ const sentMessage = await this . telegramClient . sendMessage (
167174 payload . channelUserId ,
168175 processedMessage ,
169- { parse_mode : 'Markdown' }
176+ {
177+ parse_mode : 'Markdown' ,
178+ disable_web_page_preview : true
179+ }
170180 ) ;
171181 return `${ sentMessage . message_id } ` ;
172182 }
0 commit comments