Mohammad Shahid commited on
Commit
53d6e0b
·
1 Parent(s): 5edf1f8

added lifetime link suppoert

Browse files
internal/routes/stream.go CHANGED
@@ -123,7 +123,7 @@ func getStreamRoute(ctx *gin.Context) {
123
  ctx.Header("Content-Disposition", fmt.Sprintf("%s; filename=\"%s\"", disposition, file.FileName))
124
 
125
  if r.Method != "HEAD" {
126
- lr, _ := utils.NewTelegramReader(ctx, worker.Client, file.Location, start, end, contentLength)
127
  if _, err := io.CopyN(w, lr, contentLength); err != nil {
128
  log.Error("Error while copying stream", zap.Error(err))
129
  }
 
123
  ctx.Header("Content-Disposition", fmt.Sprintf("%s; filename=\"%s\"", disposition, file.FileName))
124
 
125
  if r.Method != "HEAD" {
126
+ lr, _ := utils.NewTelegramReader(ctx, worker.Client, file.Location, start, end, contentLength, messageID)
127
  if _, err := io.CopyN(w, lr, contentLength); err != nil {
128
  log.Error("Error while copying stream", zap.Error(err))
129
  }
internal/utils/helpers.go CHANGED
@@ -179,3 +179,40 @@ func ForwardMessages(ctx *ext.Context, fromChatId, toChatId int64, messageID int
179
  }
180
  return update.(*tg.Updates), nil
181
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
179
  }
180
  return update.(*tg.Updates), nil
181
  }
182
+
183
+
184
+ // Add this entire function to the end of internal/utils/helpers.go
185
+
186
+ // RefreshFileReference gets a new file reference for a message and updates the cache.
187
+ func RefreshFileReference(ctx context.Context, client *gotgproto.Client, messageID int) (*types.File, error) {
188
+ key := fmt.Sprintf("file:%d:%d", messageID, client.Self.ID)
189
+ log := Logger.Named("RefreshFileReference")
190
+
191
+ log.Debug("Refreshing file reference from Telegram", zap.Int("messageID", messageID), zap.Int64("clientID", client.Self.ID))
192
+
193
+ // Step 1: Get the message again from the API to get a fresh file_reference.
194
+ message, err := GetTGMessage(ctx, client, messageID)
195
+ if err != nil {
196
+ return nil, err
197
+ }
198
+
199
+ // Step 2: Convert the message media into our internal File type.
200
+ file, err := FileFromMedia(message.Media)
201
+ if err != nil {
202
+ return nil, err
203
+ }
204
+
205
+ // Step 3: Update the cache with the new, valid file data.
206
+ err = cache.GetCache().Set(
207
+ key,
208
+ file,
209
+ 3600, // Cache for 1 hour
210
+ )
211
+ if err != nil {
212
+ // If caching fails, we can still proceed, but log the error.
213
+ log.Error("Failed to update cache with new file reference", zap.Error(err))
214
+ }
215
+
216
+ log.Debug("Successfully refreshed file reference and updated cache.", zap.Int("messageID", messageID))
217
+ return file, nil
218
+ }
internal/utils/reader.go CHANGED
@@ -11,6 +11,7 @@ import (
11
  )
12
 
13
  type telegramReader struct {
 
14
  ctx context.Context
15
  log *zap.Logger
16
  client *gotgproto.Client
@@ -36,9 +37,11 @@ func NewTelegramReader(
36
  start int64,
37
  end int64,
38
  contentLength int64,
 
39
  ) (io.ReadCloser, error) {
40
 
41
  r := &telegramReader{
 
42
  ctx: ctx,
43
  log: Logger.Named("telegramReader"),
44
  location: location,
@@ -92,6 +95,30 @@ func (r *telegramReader) chunk(offset int64, limit int64) ([]byte, error) {
92
 
93
  res, err := r.client.API().UploadGetFile(r.ctx, req)
94
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
  if err != nil {
96
  return nil, err
97
  }
 
11
  )
12
 
13
  type telegramReader struct {
14
+ messageID int
15
  ctx context.Context
16
  log *zap.Logger
17
  client *gotgproto.Client
 
37
  start int64,
38
  end int64,
39
  contentLength int64,
40
+ messageID int
41
  ) (io.ReadCloser, error) {
42
 
43
  r := &telegramReader{
44
+ messageID: messageID,
45
  ctx: ctx,
46
  log: Logger.Named("telegramReader"),
47
  location: location,
 
95
 
96
  res, err := r.client.API().UploadGetFile(r.ctx, req)
97
 
98
+ // Check if the file reference has expired.
99
+ if err != nil {
100
+ if tgerr.Is(err, "FILE_REFERENCE_EXPIRED") {
101
+ r.log.Info("File reference expired. Attempting to refresh.", zap.Int("messageID", r.messageID))
102
+
103
+ // Call our new refresh function from helpers.go
104
+ newFile, refreshErr := RefreshFileReference(r.ctx, r.client, r.messageID)
105
+ if refreshErr != nil {
106
+ r.log.Error("Failed to refresh file reference after it expired.", zap.Error(refreshErr))
107
+ // If we can't refresh, return the original "expired" error.
108
+ return nil, err
109
+ }
110
+
111
+ // Refresh was successful! Update the reader's location and the request object.
112
+ r.location = newFile.Location
113
+ req.Location = newFile.Location
114
+ r.log.Info("File reference refreshed successfully. Retrying file download.")
115
+
116
+ // Retry the download with the new, valid reference.
117
+ res, err = r.client.API().UploadGetFile(r.ctx, req)
118
+ }
119
+ }
120
+
121
+ // After the potential retry, check for errors one last time.
122
  if err != nil {
123
  return nil, err
124
  }