generated at
Gyazoの内部API

https://gyazo.com/:image_id.json
応答
OCR及びEXIFは、すでに解析済みならproでなくても取得できるようだ
詳細ページからは取得できないが、APIからなら取得できる
Proをやめても取得できるのはよくない設計な気もするが
types.ts
interface GyazoImage { accessible: boolean; image_id: string; alias_id: string; file_size: number; metadata_is_public: boolean; scale: { width: number; height: number; scale: number; }; type: GyazoType; page_title: string; updated_at: ISOTime | null; exif_captured_at: ISOTime | null; desc: string; draw_src_id: string | null; draw_materials: unknown | null; deletable: boolean; owned: boolean; drawable: boolean; is_pro: boolean; access_policy: "anyone"; cross_origin: "anonymous"; url: IGyazoURL; permalink_url: PermalinkURL; permalink_path: `/${string}`; file_only: boolean; has_files: boolean; attached_files: unknown[]; thumb_url: ThumbURL; poster_thumb_url: ThumbURL; thumb1000: IThumbURL; grid_thumbs: GridThumbs; non_cropped_thumb: { url: ThumbURL; scaled: { url: ThumbURL; size: number; scale: number; }; }; user: User | null; explicit: boolean; categories: string[]; next: { image_id: string; alias_id: string; permalink_url: PermalinkURL; permalink_path: `/${string}`; }; prev: { image_id: string; alias_id: string; permalink_url: PermalinkURL; permalink_path: `/${string}`; }; has_mp4: boolean; mp4_url: `https://i.gyazo.com/${string}.mp4`; download_mp4_url: `https://i.gyazo.com/download/${string}.mp4`; download_gif_url: `https://i.gyazo.com/download/${string}.gif`; is_preview_gif: boolean; has_audio: boolean; has_voice: boolean; boards: unknown[]; external_comments: unknown[]; metadata?: { app: string; title: string; url: string; desc: string; ocr_started: boolean; ocr: { locale: string; description: string; boundingPoly: BoundingPoly; } | { description: ""; }; ocrAnnotations: { description: string; boundingPoly: BoundingPoly; }[] | null; exif: Exif; exif_status: { captured_at: "from_created_at"; ok: true; msg: "ok"; }; exif_normalized: { timezone: "unknown"; } | { timezone: "utc"; latitude: number; longitude: number; time: ISOTime; }; }; }

/api/internal
internal となっているが、robots.txtではとくに制限されていないので、勝手に使っても問題なさそう
認証
Gyazo_sessionをcookieにわたす
ログアウトすれば無効になるみたい?
自動でログイン画面にredirectする
htmlファイル中に含まれている認証情報使っている?
<meta>CSRF tokenが含まれている
https://gyazo.com/api/internal/images
画像一覧を取得
URL paramerters
page (number)
per (number)
一度に取得する画像の最大数
timestamp (number)
なにこれ
応答
Image[]
PATCH https://gyazo.com/api/internal/images/:image_id
parameters
bodyにJSONとして送る
access_policy
"anyone" : password解除
"passphrase" : passwordかける
passphrase
access_policy: "passphase" のときのみ必要
password
https://gyazo.com/api/internal/search_histories
検索履歴を取得する
URL parameters
page (number)
paging
応答
SearchHistory[]
thumb 系が常にあるかは調べてない
types.ts
interface SearchHistory { id: string; title: string; pinned: boolean; image: { alias_id: string; image_id: string; thumb_url: ThumbURL; thumb_url_2x: ThumbURL; thumb_url_webp: ThumbWebpURL; thumb_url_webp_2x: ThumbWebpURL; file_only: boolean; has_files: boolean; file_types: string | null; // nullしか観測していない file_names: string | null; // nullしか観測していない cross_origin: "anonymous"; }; };
https://gyazo.com/api/internal/search_result
検索する
URL parameters
必須
per (number)
受け取る検索結果の最大数
10か30が使われる?
query (string)
検索文字列
これを抜かすと500 internal errorが発生する
page (number)
offset
exclude_linked_images (boolean)
普通は true
不明
渡さなくてもエラーにならない
timestamp (number)
応答
内部でkuromoji.jsを使っているのか?
2024-11-10 11:16:31 今は不明
EXIFとサムネURL周りのpropertiesはoptionalかも
ヒット箇所は返されないようだ
types.ts
interface SearchResults { captures: Image[]; number_of_captures: number; query: string; engine: "Elasticsearch"; index: `image-${number}`, /** `false`のみ? */ start_indexing: boolean; conditions: { must: Query[]; must_not: Query[]; } }
condition Elastic SearchElasticsearch Query DSLに準拠しているようだ
ts
type Query = { /** 複数条件当てはまるときは、その分だけQueryが返される */ match_phrase: { everything: string; } | { url: string } | { title: string } | { app: string } | { type: string }; } | { /** * lteがuntil, gteがsince * * month:2021-01にしたら、gteに"2021-01-01||+1M"が入った。 * date:2021-01-01だと、gteに"2021-01-01||+1d"が入った。 * * 詳細なformatはhttps://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-range-query.html に準拠しているようだ */ range: { date: { lte: `${number}-${number}-${number}`; } | { gte: `${number}-${number}-${number}`; }; }; };
関連するコード
js
32159: (e, t, a) => { a.d(t, { g: () => c }); var s = a(96540) , i = a(23041) , r = a(72737) , n = a(13930) , o = a(34710); const d = e => (0, n.C6)()(e).then((e => ({ ...e, captures: e.captures.map((e => (0, r.xZ)(e))) }))) , c = ({query: e, perPage: t, excludeLinkedImages: a=!1}) => { const {data: r, size: n, setSize: c} = (0, i.Ay)(( (s, i) => { if (!e) return null; if (0 < s && i.numberOfCaptures <= s * t) return null; const r = new URLSearchParams; return r.append("query", e), r.append("per", t.toString()), r.append("page", (s + 1).toString()), r.append("exclude_linked_images", a.toString()), `/api/internal/search_result?${r}` } ), d, { use: [(0, o.Cb)("images/update")], revalidateFirstPage: !1 }) , l = (0, s.useCallback)(( () => { c(n + 1) } ), [c, n]); return { images: r?.flatMap(( ({captures: e}) => e)), loading: !r, loadNext: l, startIndexing: !!r?.[0]?.startIndexing, numberOfResults: r?.[0]?.numberOfCaptures } } }
n.C6=t=>w("GET", t)
w.js
async function w(t, e, r=null, n=!1, i={}) { const {disableCsrf: o, ...s} = i; let a = e.startsWith("/") ? location.origin + e : e; const c = m(e); if (y(t, r) && Object.keys(r).length > 0) { const t = new URLSearchParams; Object.entries(r).forEach(( ([e,r]) => { null != r && (Array.isArray(r) ? r.forEach((r => t.append(`${e}[]`, r.toString()))) : t.append(e, r.toString())) } )), a = a + "?" + t.toString() } const u = await fetch(a, { method: t, ..."GET" === t || null === r ? {} : { body: JSON.stringify(r) }, ...g(t, o, c), ...s }); return b(u, c, n) }
https://gyazo.com/api/internal/images/:image_id/similar_images
関連画像
応答
Image[]
free userだと空配列が返ってくる
https://gyazo.com/api/internal/images/:image_id/close_date_images
前後にuploadされた画像
応答
types.ts
interface CloseDateImages { before: Image[]; after: Image[]; }
https://gyazo.com/api/internal/images/:image_id/similar_metadata_images
各属性の関連画像
応答
free userだと空配列が返ってくる
types.ts
type SimilarMetadata = { [K in "title" | "app" | "url" | "ocr"]: { keyword: string; images: Image[]; }; };
https://gyazo.com/api/internal/images/:image_id/near_images
近くの場所で撮影された画像
応答
types.ts
type NearImages = { message: "no location"; count: 0; images: []; } | { message: "ok"; count: number; images: Image[]; };
https://gyazo.com/api/internal/boards/visits
https://gyazo.com/api/internal/images_summary
応答
なにこれ
types.ts
interface ImagesSummary { monthly_counts: Record<number, Record<number, number>>; }
https://gyazo.com/api/internal/boards/visits/images
画像の閲覧履歴を取得する
URL parameters
limit
取得する画像の最大数
cursor
paging用のID
応答
types.ts
interface VisitedImages { cursor: string; images: }

#2024-11-10 10:59:08
#2022-03-30 16:31:45
#2022-03-28 09:14:36
#2022-03-11 10:05:44
#2022-02-26 23:09:44