Skip to main content

LINE OA Lookup by Hash

Overview

This is the first endpoint client-web calls on every LIFF page. It converts the hash in the URL — of the form /{hash}/... — into a lineLiffId so the web app can call liff.init(), and returns the public OA information the page needs: the OA name, its @-id, and its cover image.

The route was designed with the explicit understanding that it is unauthenticated, so it returns only genuinely safe fields — every one of them already appears on the OA's public LINE page. No credential of any kind may be added to this response.

Business Flow

  1. Take :hash from the path and query line_oa with status NOT IN ('delete') AND deleted_date IS NULL. Note that this condition is looser than the one in liff.Service, which requires status='active': an inactive OA can still resolve its hash, but token verification will fail at the next step.
  2. If no row matches, return 400 with the message APP_007 (parity with the source's ErrorResponse.APP_007).
  3. Assemble the response:
    • lineLiffId and formLiffId are read from the jsonb line_login_info. An empty value or a missing key becomes JSON null (parity with value || null).
    • botBasicId is the public @-id, which the form thank-you page needs to build https://line.me/R/ti/p/<id> for the oa_chat action when opened in an external browser.
    • name comes from line_oa_name and is used as the page's document title.
    • imageUrl resolves line_oa.cover — a storage path — into a public URL for use as og:image. An empty path yields null rather than a URL pointing at the bucket root, a path that is already an absolute URL is passed through unchanged, and a missing storage configuration yields null without panicking.

Key Files & Functions

ItemValue
RouteGET /api/line-oa/get-by-hash/:hash
Registerinternal/lineoa/register.goRegister(r, deps)
Handlerinternal/lineoa/handler.go(*Handler).GetByHash
Serviceinternal/lineoa/service.go(*Service).GetByHash, findByHash, resolveCover, emptyToNil
Repositoryinternal/lineoa/repository.goFindByHash, FindActiveByID
Entityinternal/lineoa/entity.goLineOa, LineLoginInfo
ResponseGetByHashResponse with lineLiffId, formLiffId, botBasicId, name, imageUrl

Connections to Other Services

  • The line_oa table, using line_oa_hash, line_oa_name, bot_basic_id, cover, and the jsonb line_login_info.
  • internal/storagex for GetPublicURL, which is allowed to be nil — in that case no image is returned.
  • lineoa.Repository is reused by LIFF Token Verification through FindActiveByID, and by the bulletin and loyalty domains through their own FindOaByHash helpers.
  • The related client-web feature is line-oa-hash-routing, which owns the /{hash}/... URL structure and OA-level OG metadata.