파일
`files->list`, `listAll`, `iterate`, `get`, `download`, `listLinks`, `listAllLinks`, `iterateLinks`, `createLink`, `revokeLink`, `revokeAllLinks`, `stats`, `upload`, `delete`, `deleteMany`.
모든 메서드
use OpenEmail\Constants\FileKinds;use OpenEmail\Constants\FileSorts; $largest = $client->files->list(kind: FileKinds::PDF, sort: FileSorts::LARGEST, limit: 1); foreach ($largest as $file) { foreach ($client->files->listAllLinks($file['id']) as $link) { echo $link['url'], ' ', $link['downloads'], PHP_EOL; } file_put_contents(basename($file['filename']), $client->files->download($file['id']));} $stats = $client->files->stats();echo $stats['totals']['files'], ' ', $stats['uploaded']['bytes'], PHP_EOL;메일함이 보관하는 모든 파일로, 보내고 받은 첨부 파일과 업로드한 파일을 포함합니다: 앱의 파일 페이지에 해당합니다. download는 바이트를 문자열로 돌려주며, file_put_contents로 그대로 저장할 수 있습니다. 링크는 파일이 나간 다운로드 링크와 각 링크를 받아 간 횟수이며, stats는 분석 탭입니다.
list, listAll, iterate는 q:, kind:, sort:와 함께 direction:(inbound, outbound, uploaded), address:(대소문자를 구분하지 않고 비교하는 한 주소의 파일), 그리고 since:와 until:(DateTimeInterface 또는 ISO 8601 문자열)을 받습니다. since:는 그 시점을 포함하고 until:은 그 직전에서 멈춥니다. DateTimeInterface는 UTC로 전송되며, 2026-09-01처럼 날짜만 담은 문자열은 UTC 자정으로 읽힙니다.
q:는 파일 이름과 그 유형을 검색합니다. kind:는 image, pdf, audio, video, text 중 하나이고, sort:는 newest(기본값), oldest, largest, name 중 하나입니다. OpenEmail\Constants\FileKinds, FileSorts, FileDirections가 선택지를 정의합니다. list는 OpenEmail\Result\Page 하나를 반환하고, listAll은 모든 파일을 하나의 배열로 반환합니다. iterate는 파일을 하나씩 yield하며 루프가 필요로 할 때만 다음 페이지를 가져오는 Generator를 반환합니다.
읽으려면 files:read, 업로드, 삭제, 링크 게시와 취소에는 files:write가 필요하며, 이는 files:read를 포함합니다. 파일에 자체 스코프가 생기기 전에 만든 키에는 그에 맞는 스코프가 부여되었습니다. 스코프가 없는 키는 403 insufficient_scope로 거부되며, 이는 isScopeMissing()이 true인 PermissionException으로 던져집니다. 특정 주소나 도메인으로 제한된 키는 그곳에 도착한 파일만 보므로, 워크스페이스 전체를 위해 업로드된 파일은 보지 못합니다.
download는 파일 전체를 메모리에 담으므로, 아주 큰 파일은 하나씩 가져오세요. 이름은 파일을 보낸 사람이 정한 것이므로, 예제처럼 쓰기 전에 basename()에 통과시키세요.
공개 링크
use OpenEmail\Constants\FileDirections; $uploads = $client->files->listAll(direction: FileDirections::UPLOADED, since: new \DateTimeImmutable('2026-09-01T00:00:00Z'));$file = $uploads[0] ?? null; if ($file !== null) { $link = $client->files->createLink($file['id'], domain: 'acme.com'); echo $link['url'], PHP_EOL; $client->files->revokeLink($file['id'], $link['id']);}createLink는 로그인 없이 열리는 공개 다운로드 링크로 파일을 게시하고 그 링크를 돌려줍니다. 링크는 domain:에 파일 호스트가 있으면 그곳(예: files.acme.com)에, 없으면 파일이 속한 주소의 파일 호스트에, 그것도 없으면 API 주소에 놓입니다. 메시지로 들어오거나 나간 파일은 먼저 공개 저장소로 복사되며, 프로그램이나 스크립트는 ValidationException으로 던져지는 422 file_unshareable로 거부됩니다.
createLink는 호출할 때마다 새 링크를 만들므로 응답을 놓쳐도 재시도되지 않습니다: 먼저 listLinks로 링크를 찾으세요. revokeLink는 이미 보낸 메일에 있는 것까지 포함해 링크를 영구히 멈추고, revokedAt이 설정된 링크를 돌려줍니다. 같은 링크를 두 번 취소해도 안전하므로 클라이언트는 읽기처럼 재시도합니다. 알 수 없는 링크는 NotFoundException으로 던져지는 404입니다. revokeAllLinks는 한 파일의 모든 링크를 한꺼번에 멈추고, 몇 개인지를 revoked에 알려 줍니다.
업로드와 삭제
$report = "month,sent\n2026-09,1200\n";$upload = $client->files->upload($report, filename: 'report.csv', contentType: 'text/csv'); if ($upload['deletable']) { $client->files->delete($upload['id']);} $logo = $client->files->upload(new \SplFileInfo('logo.svg'));echo $logo['filename'], ' ', $logo['mimeType'], PHP_EOL; $result = $client->files->deleteMany(['file_0c4e7a91d2b84f63a5e19b7d', 'file_6bb640f5b99e47deb758f1f5']); foreach ($result['kept'] as $kept) { echo $kept['filename'], ' ', $kept['reason'], PHP_EOL;}upload는 바이트를 그대로, 100 MB까지, filename:의 이름으로 저장하고 파일을 돌려줍니다. 발송은 이를 emails->send의 attachments에 ['fileId' => $upload['id']]로 첨부합니다. contentType:을 전달하거나 자체 유형을 가진 데이터를 전달하세요. 그 밖의 것은 application/octet-stream으로 저장됩니다. 유형은 filename:에서 추측하지 않으므로, 바이트 문자열을 다른 유형으로 저장하려면 contentType:이 필요합니다. 두 번째 시도는 두 번째 사본을 저장하게 되므로 절대 재시도되지 않습니다.
데이터는 바이트 문자열, SplFileInfo, fopen()으로 연 스트림, 또는 PSR-7 스트림이나 업로드된 파일입니다. SplFileInfo나 파일에 연 스트림에는 두 인자 모두 필요 없습니다: 이름은 파일 자신의 것이고, 유형은 패키지가 아는 확장자(.pdf나 .png 등)에서 가져옵니다. Laravel이나 Symfony의 업로드, 그리고 PSR-7 업로드 파일은 브라우저가 보낸 이름과 유형을 가지고 옵니다. 문자열에는 이름이 없으므로, filename: 없는 문자열은 무엇이든 보내기 전에 InvalidArgumentException을 던집니다.
업로드는 600초, 또는 클라이언트의 timeout이 더 길면 그 시간까지 실행될 수 있으며, timeout:으로 호출 하나에 다른 상한을 정할 수 있습니다. timeout: 0으로 만든 클라이언트는 업로드가 걸리는 만큼 기다립니다.
아무것도 의존하지 않는 업로드된 파일만 삭제할 수 있으며, 파일마다 deletable과 usage가 이를 미리 알려 줍니다. delete는 다른 파일을 409 file_in_use로 거부하며, 이는 ConflictException으로 던져집니다. deleteMany는 id를 최대 100개 받아 삭제할 수 있는 것을 삭제하고, 나머지는 kept에 각각의 이유와 함께, 그리고 missing에 알려 줍니다. 둘 다 재시도되지 않습니다. 응답을 잃은 뒤 두 번째 delete에서 404가 나오면 첫 번째가 성공했다는 뜻이며, 두 번째 deleteMany는 그 파일들을 missing에 알려 줍니다.