| 1123 | } |
| 1124 | |
| 1125 | func uploadFileToIM(ctx context.Context, runtime *common.RuntimeContext, filePath, fileType, duration, param string) (string, error) { |
| 1126 | if info, err := runtime.FileIO().Stat(filePath); err == nil && info.Size() > maxFileUploadSize { |
| 1127 | return "", errs.NewValidationError(errs.SubtypeInvalidArgument, "file size %s exceeds limit (max 100MB)", common.FormatSize(info.Size())).WithParam(param) |
| 1128 | } |
| 1129 | |
| 1130 | f, err := runtime.FileIO().Open(filePath) |
| 1131 | if err != nil { |
| 1132 | return "", withIMValidationParam(common.WrapInputStatErrorTyped(err), param) |
| 1133 | } |
| 1134 | defer f.Close() |
| 1135 | |
| 1136 | fd := larkcore.NewFormdata() |
| 1137 | fd.AddField("file_type", fileType) |
| 1138 | fd.AddField("file_name", filepath.Base(filePath)) |
| 1139 | if duration != "" { |
| 1140 | fd.AddField("duration", duration) |
| 1141 | } |
| 1142 | fd.AddFile("file", f) |
| 1143 | |
| 1144 | apiResp, err := runtime.DoAPI(&larkcore.ApiReq{ |
| 1145 | HttpMethod: http.MethodPost, |
| 1146 | ApiPath: "/open-apis/im/v1/files", |
| 1147 | Body: fd, |
| 1148 | }, larkcore.WithFileUpload()) |
| 1149 | if err != nil { |
| 1150 | return "", err |
| 1151 | } |
| 1152 | |
| 1153 | data, err := runtime.ClassifyAPIResponse(apiResp) |
| 1154 | if err != nil { |
| 1155 | return "", err |
| 1156 | } |
| 1157 | fileKey, _ := data["file_key"].(string) |
| 1158 | if fileKey == "" { |
| 1159 | return "", errs.NewInternalError(errs.SubtypeInvalidResponse, "file_key missing from a successful upload response") |
| 1160 | } |
| 1161 | return fileKey, nil |
| 1162 | } |
| 1163 | |
| 1164 | // uploadImageFromReader uploads an image from an io.Reader (no local file needed). |
| 1165 | func uploadImageFromReader(ctx context.Context, runtime *common.RuntimeContext, r io.Reader, imageType string) (string, error) { |