1+ import type { Ticket , User } from '@roll-stack/database'
12import type { Context } from 'grammy'
23import { repository } from '@roll-stack/database'
34import { Bot } from 'grammy'
@@ -9,12 +10,12 @@ const { telegram } = useRuntimeConfig()
910let bot : Bot | null = null
1011
1112export async function useCreateWasabiBot ( ) {
12- const botInDb = await repository . telegram . findBot ( telegram . wasabiBotId )
13- if ( ! botInDb ?. token ) {
13+ const token = await getBotToken ( )
14+ if ( ! token ) {
1415 throw new Error ( 'Wasabi bot is not configured' )
1516 }
1617
17- bot = new Bot ( botInDb . token )
18+ bot = new Bot ( token )
1819
1920 bot . on ( 'message:text' , async ( ctx ) => {
2021 if ( ctx . hasCommand ( 'start' ) ) {
@@ -24,6 +25,22 @@ export async function useCreateWasabiBot() {
2425 return handleMessage ( ctx )
2526 } )
2627
28+ bot . on ( 'message:photo' , async ( ctx ) => {
29+ return handlePhoto ( ctx )
30+ } )
31+
32+ bot . on ( 'message:video' , async ( ctx ) => {
33+ return handleVideo ( ctx )
34+ } )
35+
36+ bot . on ( 'message:document' , async ( ctx ) => {
37+ return handleFile ( ctx )
38+ } )
39+
40+ bot . on ( 'message:file' , async ( ctx ) => {
41+ return handleFile ( ctx )
42+ } )
43+
2744 // Somebody invited bot to a group
2845 bot . on ( 'my_chat_member' , async ( ctx ) => {
2946 logger . log ( 'my_chat_member' , ctx . update )
@@ -84,11 +101,102 @@ async function handleMessage(ctx: Context) {
84101 return
85102 }
86103
87- const telegramUser = await repository . telegram . findUserByTelegramIdAndBotId ( ctx . message . from . id . toString ( ) , telegram . wasabiBotId )
88- if ( ! telegramUser ?. user ) {
104+ const data = await getUserAndTicket ( ctx . message . from . id . toString ( ) )
105+ if ( ! data ) {
106+ return
107+ }
108+
109+ await repository . ticket . createMessage ( {
110+ ticketId : data . ticket . id ,
111+ userId : data . user . id ,
112+ text : ctx . message . text ,
113+ } )
114+
115+ logger . log ( 'message' , data . user . id , ctx . message . from . id , ctx . message . text )
116+ ctx . reply ( 'Сообщение передано в службу поддержки.' )
117+ }
118+
119+ async function handlePhoto ( ctx : Context ) {
120+ if ( ! ctx . message ?. photo ?. length ) {
121+ return
122+ }
123+
124+ const data = await getUserAndTicket ( ctx . message . from . id . toString ( ) )
125+ if ( ! data ) {
89126 return
90127 }
91128
129+ const bestQuality = ctx . message . photo . pop ( )
130+ if ( ! bestQuality ) {
131+ return
132+ }
133+
134+ const botToken = await getBotToken ( )
135+ if ( ! botToken ) {
136+ return null
137+ }
138+
139+ const downloadUrl = await getFileDownloadUrl ( { ctx, fileId : bestQuality . file_id , botToken } )
140+
141+ await repository . ticket . createMessage ( {
142+ ticketId : data . ticket . id ,
143+ userId : data . user . id ,
144+ text : JSON . stringify ( { downloadUrl, photo : ctx . message . photo } ) ,
145+ } )
146+
147+ // Save photo?
148+ logger . log ( 'photo' , data . user . id , ctx . message . from . id , ctx . message . text , ctx . message . photo , downloadUrl )
149+ ctx . reply ( 'Фото передано в службу поддержки.' )
150+ }
151+
152+ async function handleVideo ( ctx : Context ) {
153+ if ( ! ctx . message ?. video ) {
154+ return
155+ }
156+
157+ const data = await getUserAndTicket ( ctx . message . from . id . toString ( ) )
158+ if ( ! data ) {
159+ return
160+ }
161+
162+ await repository . ticket . createMessage ( {
163+ ticketId : data . ticket . id ,
164+ userId : data . user . id ,
165+ text : JSON . stringify ( ctx . message . video ) ,
166+ } )
167+
168+ // Save video?
169+ logger . log ( 'video' , data . user . id , ctx . message . from . id , ctx . message . text , ctx . message . video )
170+ ctx . reply ( 'Видео передано в службу поддержки.' )
171+ }
172+
173+ async function handleFile ( ctx : Context ) {
174+ if ( ! ctx . message ?. document ) {
175+ return
176+ }
177+
178+ const data = await getUserAndTicket ( ctx . message . from . id . toString ( ) )
179+ if ( ! data ) {
180+ return
181+ }
182+
183+ await repository . ticket . createMessage ( {
184+ ticketId : data . ticket . id ,
185+ userId : data . user . id ,
186+ text : JSON . stringify ( ctx . message . document ) ,
187+ } )
188+
189+ // Save file?
190+ logger . log ( 'file' , data . user . id , ctx . message . from . id , ctx . message . text , ctx . message . document )
191+ ctx . reply ( 'Файл передан в службу поддержки.' )
192+ }
193+
194+ async function getUserAndTicket ( telegramId : string ) : Promise < { user : User , ticket : Ticket } | null > {
195+ const telegramUser = await repository . telegram . findUserByTelegramIdAndBotId ( telegramId , telegram . wasabiBotId )
196+ if ( ! telegramUser ?. user ) {
197+ return null
198+ }
199+
92200 // Get last ticket
93201 const tickets = await repository . ticket . listOpenedByUser ( telegramUser . user . id )
94202 let ticket = tickets ?. [ 0 ]
@@ -102,17 +210,29 @@ async function handleMessage(ctx: Context) {
102210 } )
103211 }
104212 if ( ! ticket ) {
105- return
213+ return null
106214 }
107215
108- await repository . ticket . createMessage ( {
109- ticketId : ticket . id ,
110- userId : telegramUser . user . id ,
111- text : ctx . message . text ,
112- } )
216+ return { user : telegramUser . user , ticket }
217+ }
113218
114- logger . log ( 'message' , telegramUser . user . id , ctx . message . from . id , ctx . message . text )
115- ctx . reply ( 'Сообщение передано в службу поддержки.' )
219+ async function getFileDownloadUrl ( data : { ctx : Context , fileId : string , botToken : string } ) {
220+ // https://api.telegram.org/file/bot<token>/<file_path>
221+ const file = await data . ctx . api . getFile ( data . fileId )
222+ if ( ! file ) {
223+ return null
224+ }
225+
226+ return `https://api.telegram.org/file/bot${ data . botToken } /${ file . file_path } `
227+ }
228+
229+ async function getBotToken ( ) : Promise < string | null > {
230+ const botInDb = await repository . telegram . findBot ( telegram . wasabiBotId )
231+ if ( ! botInDb ?. token ) {
232+ return null
233+ }
234+
235+ return botInDb . token
116236}
117237
118238export function useWasabiBot ( ) : Bot {
0 commit comments