Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ First stable (GA) release.

## Libraries — `Line.OpenApi.*`

### Unreleased

#### Added

- **LINE notification messages (template)** — upstream spec sync to [`line/line-openapi@fa5577c9`](https://github.com/line/line-openapi/commit/fa5577c9ea874d2dbd8fadc85a4cb3a1b29d8cbe). Generated `Line.OpenApi.Messaging` client gains `POST /v2/bot/message/pnp/templated/push` (`client.Api.V2.Bot.Message.Pnp.Templated.Push`) and `GET /v2/bot/message/delivery/pnp/templated` (`client.Api.V2.Bot.Message.Delivery.Pnp.Templated`), with the models `PnpTemplatedMessageRequest`, `PnpTemplatedMessageBody`, `PnpTemplatedEmphasizedItem`, `PnpTemplatedItem` and `PnpTemplatedButton`. `PnpMessagesRequest` gains the optional `customAggregationUnits`. Additive only; no hand-written API changes.

### 1.0.0 - 2026-08-12

First stable (GA) release of the client libraries.
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG_ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ dev トンネルの再起動時に LINE Developers コンソールへ URL を貼

## ライブラリ — `Line.OpenApi.*`

### Unreleased

#### 追加

- **LINE 通知メッセージ(テンプレート)** — 上流仕様 [`line/line-openapi@fa5577c9`](https://github.com/line/line-openapi/commit/fa5577c9ea874d2dbd8fadc85a4cb3a1b29d8cbe) への追従。生成クライアント `Line.OpenApi.Messaging` に `POST /v2/bot/message/pnp/templated/push`(`client.Api.V2.Bot.Message.Pnp.Templated.Push`)と `GET /v2/bot/message/delivery/pnp/templated`(`client.Api.V2.Bot.Message.Delivery.Pnp.Templated`)、モデル `PnpTemplatedMessageRequest`・`PnpTemplatedMessageBody`・`PnpTemplatedEmphasizedItem`・`PnpTemplatedItem`・`PnpTemplatedButton` を追加。`PnpMessagesRequest` に任意プロパティ `customAggregationUnits` を追加。追加のみで手書き API の変更なし。

### 1.0.0 - 2026-08-12

クライアントライブラリの初の安定版(GA)リリース。
Expand Down
4 changes: 4 additions & 0 deletions docs/coverage-roadmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ line-openapi リポジトリの OpenAPI spec は **9 本**。うち **8 本を
1. 画像アップロード `setRichMenuImage` は spec 上 `*/*`(binary)だが LINE は `Content-Type: image/png`/`image/jpeg` を必須とする。生成コードは content-type を明示せず落とし穴になる(form-urlencoded の `StatelessJwtAssertionTokenSource` と同種)→ 手書きヘルパが要る。
2. 利用シーン用の便利ファサード(`LiffClient` 相当)が無く、生の生成ビルダーは辿りにくい。

### LINE 通知メッセージ(PNP)は生成物のみで公開(2026-10-07 追記)

電話番号宛ての LINE 通知メッセージ(パートナー契約前提)は、従来の push/送信数取得に加え、上流 `fa5577c9`(spec-sync・PR #11)で**テンプレート版**(`/v2/bot/message/pnp/templated/push`・`/v2/bot/message/delivery/pnp/templated`)が追加された。いずれも `MessagingClient.Api` の生成ビルダー経由で利用可能で、手書きファサード・CLI/MCP・AI ツールへの露出は**未着手(候補)**。露出する場合の注意: `to` はソルト無し SHA256 ハッシュで元の電話番号に戻せる(ログ・例外に出さない)、`X-Line-Delivery-Tag` は型付き引数にならず `requestConfiguration.Headers` で付ける。

## 第1部: 未取り込みの OpenAPI spec(残 1 本=module-attach のみ)

> **更新(2026-07-15):** カバレッジ拡充で **insight / manage-audience / module / shop の 4 本を取り込み完了**(`Line.OpenApi.Insight` / `.ManageAudience` / `.Module` / `.Shop`。ラウンド 1=易 3 本、ラウンド 2=manage-audience。記録は `docs/reviews/2026-07-15-coverage-round{1,2}-review.md`)。**module-attach のみ見送り**(下表・パートナー限定 1 op でコスト対効果最低)。
Expand Down
52 changes: 52 additions & 0 deletions docs/reviews/2026-10-07-spec-sync-fa5577c9-review.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# 2026-10-07 spec-sync 上流追従(line-openapi @ fa5577c9)レビュー記録

## 概要

週次 spec-sync(2026-10-05 cron・run [37309200951](https://github.com/pierre3/line-openapi-dotnet/actions/runs/37309200951))が上流ドリフトを検知し Issue #10 を起票。再生成・build・test・ブランチ push までは成功したが、**draft PR 作成が失敗**した。

- 原因: リポジトリ設定 "Allow GitHub Actions to create and approve pull requests" がオフ(`GitHub Actions is not permitted to create or approve pull requests`)。spec-sync 稼働後、実ドリフトが出たのは今回が初めてで、初めて顕在化した。**設定はオンに変更済み(人)**。
- PR は push 済みブランチ `spec-sync/update-fa5577c9` から手動で作成 → **PR #11**(`Closes #10`)。

## 上流差分(`de8bd9e` → `fa5577c9`、上流コミット日 2026-09-29)

`messaging-api.yml` のみ変化。他 7 本の取り込み spec と見送りの `module-attach.yml` は不変。**追加のみ(非破壊)**。

- 新規 op: `POST /v2/bot/message/pnp/templated/push`(`pushTemplatedMessagesByPhone`、任意ヘッダ `X-Line-Delivery-Tag`、202/422)、`GET /v2/bot/message/delivery/pnp/templated`(`getPNPTemplatedMessageStatistics`、`NumberOfMessagesResponse`)
- 新規モデル: `PnpTemplatedMessageRequest` / `PnpTemplatedMessageBody` / `PnpTemplatedEmphasizedItem` / `PnpTemplatedItem` / `PnpTemplatedButton`
- 既存 `PnpMessagesRequest` に任意プロパティ `customAggregationUnits` を追加
- 生成物の変化は `Generated/Api` のみ。`Generated/Blob` は `kiota-lock.json` の descriptionHash だけ(spec 全体ハッシュのため当然)

## 検証

- ローカル build(Release)エラー 0、`dotnet test` 全 422 件合格(lib 264 / Tools 131 / AI 26 / Webhook Isolation 1)
- `verify-spec-manifest.ps1` 8 本 ok
- PR #11 の CI(build-test / extension-test / pack-verify)pass

## 4 役ゲート結果(すべて PASS・BLOCKING なし)

- **spec-reviewer = PASS**: YAML 妥当。R1 = 新 op は op 単位 `servers` 無し=`api.line.me`、Blob 側への混入なし(include/exclude `**/content` 不変)。R2 = 改名・衝突なし。manifest のハッシュは LF 正規化 spec と一致。
- **code-reviewer = PASS**: 手書きコード・公開 API snapshot 影響なし。新 op は `MessagingClient.Api` 経由で到達可能。既存 PNP にも手書きラッパ・CLI/MCP/AI 露出はないため、合わせて追加するものは無い(パートナー限定機能でもあり今回は露出しない)。
- **security-reviewer = PASS**: 新 op は `api.line.me` 固定・AllowedHosts 内・data 系混入なし・R1 順序影響なし。`X-Line-Delivery-Tag` は非機密の相関 ID。
- **test-arch-reviewer = PASS**: op 単位のホストテストは不要(全 op が `{+baseurl}` 共通で既存 `MessagingHostRoutingTests` が構造的に担保)。

## 本 PR で対応した指摘

- **refDate 据え置きバグ(spec / test-arch が独立に検出・再現確認済み)**: `scripts/generate.ps1` が `commit.committer.date.Substring(0,10)` を呼んでいたが、pwsh 7 の `ConvertFrom-Json` / `Invoke-RestMethod` は ISO 日付を `DateTime` に自動変換するため例外 → `catch` が警告にするだけで `refDate` が**黙って旧値のまま**残っていた。`DateTime` なら UTC 日付へ整形、文字列なら従来どおりに修正。manifest の `refDate` を `2026-07-28` → `2026-09-29` に手修正。
- **CHANGELOG**(code): ライブラリ系統に `Unreleased` 節を英日で追加(次のライブラリリースは minor 相当)。

## 非ブロッキング follow-up(次サイクル)

1. **spec-sync の push 不具合(test-arch・中)**: checkout は bot ブランチの追跡 ref を持たないため、同名ブランチが既存(PR マージ前に翌週 cron が同じドリフトを再検知/run の再実行)だと `--force-with-lease` が `stale info` で拒否される。pwsh はネイティブコマンドの非 0 終了で止まらないため、**run は緑のまま黙って失敗**する。方針: `git ls-remote --exit-code --heads` で既存なら push をスキップし PR 作成/更新のみ(SHA 命名で内容は決定的・レビュアー fixup 保護)、スキップを PR 本文に明記、`$PSNativeCommandUseErrorActionPreference = $true` で無言失敗を排除。
2. **build/test 失敗が run 結果に出ない(test-arch・中)**: `continue-on-error` のため。PR 作成後の最終ステップで outcome が success 以外なら `exit 1`。
3. **Issue と PR 結果の非連動(test-arch・低)**: PR 番号・run URL・build/test 結果を追跡 Issue にコメント。失敗時は `if: failure()` で run URL を残す。
4. **spec 駆動の R1 ガードテスト(test-arch・中)**: `servers` が api-data のパス集合と Blob 生成フィルタ(`**/content`)の一致集合が等しいことを spec から検証(`manage-audience.yml` の `**/upload/byFile` も同型)。`/content` で終わらない data 系 op が上流に足された場合の黙った誤ルーティングを防ぐ。
5. **`ci.yml` に `permissions:` 未指定(security・中)**: 今回の設定オンで PR 作成/承認が可能になったため明示 `contents: read` を推奨。ただしリポジトリ既定は `default_workflow_permissions: read` を API で確認済みで、現状の実リスクは低い。main のブランチ保護で bot 承認だけではマージ条件を満たさないことも確認推奨。
6. **GITHUB_TOKEN で作った PR では `ci.yml` が起動しない(security・低)**: 今後自動作成される spec-sync PR には CI 結果が付かない。マージ前に close/reopen 等で CI を走らせる運用、または App token 化を検討。
7. **ドキュメント注意喚起(security・低)**: PNP を概念記事で扱う/ファサード化する場合、`to` はソルト無しのハッシュで元の電話番号に戻せる(ログや例外に出さない)、パートナー契約前提、`X-Line-Delivery-Tag` は `requestConfiguration.Headers` で付ける、を明記。
8. **露出判断の追跡(test-arch・低)**: PNP テンプレート送信の CLI/MCP 露出は `docs/coverage-roadmap.md` に候補として記録。

既知 follow-up(security L1: 特権ジョブ内の build/test)は未解決のまま継続。

## 判定

4 役 PASS。マージの go/no-go は人。
176 changes: 176 additions & 0 deletions openapi/messaging-api.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1739,6 +1739,40 @@ paths:
schema:
"$ref": "#/components/schemas/ErrorResponse"

"/v2/bot/message/pnp/templated/push":
post:
externalDocs:
url: https://developers.line.biz/en/reference/line-notification-messages/#send-line-notification-message-template
tags:
- messaging-api
operationId: pushTemplatedMessagesByPhone
description: "Send LINE notification message (template)"
parameters:
- name: X-Line-Delivery-Tag
in: header
required: false
schema:
type: string
minLength: 16
maxLength: 100
description: "String returned in the delivery.data property of the delivery completion event via Webhook."
requestBody:
content:
application/json:
schema:
"$ref": "#/components/schemas/PnpTemplatedMessageRequest"
required: true
responses:
"202":
description: "Accepted"
"422":
description: |+
Failed to send the LINE notification message. For example, there is no LINE user associated with the specified phone number, the phone number is outside the LINE notification message service area, the user has refused to receive LINE notification messages, or the user hasn't agreed to LINE's Privacy Policy.
content:
"application/json":
schema:
"$ref": "#/components/schemas/ErrorResponse"

"/v2/bot/message/delivery/pnp":
get:
externalDocs:
Expand Down Expand Up @@ -1770,6 +1804,37 @@ paths:
status: ready
success: 3

"/v2/bot/message/delivery/pnp/templated":
get:
externalDocs:
url: https://developers.line.biz/en/reference/line-notification-messages/#get-number-of-sent-line-notification-messages-template
tags:
- messaging-api
operationId: getPNPTemplatedMessageStatistics
description: "Get number of sent LINE notification messages (template)"
parameters:
- name: date
in: query
required: true
schema:
type: string
pattern: "^[0-9]{8}$"
description: |+
Date the message was sent

Format: `yyyyMMdd` (Example:`20211231`)
Time zone: UTC+9
responses:
"200":
description: "OK"
content:
"application/json":
schema:
"$ref": "#/components/schemas/NumberOfMessagesResponse"
example:
status: ready
success: 3

# Membership
"/v2/bot/membership/subscription/{userId}":
get:
Expand Down Expand Up @@ -3638,6 +3703,117 @@ components:
description: "Message destination. Specify a phone number that has been normalized to E.164 format and hashed with SHA256."
notificationDisabled:
"$ref": "#/components/schemas/NotificationDisabled"
customAggregationUnits:
type: array
maxItems: 1
description: "Name of aggregation unit. Case-sensitive."
items:
type: string
maxLength: 30
minLength: 1
pattern: "^[a-zA-Z0-9_]{1,30}$"

PnpTemplatedMessageRequest:
externalDocs:
url: https://developers.line.biz/en/reference/line-notification-messages/#send-line-notification-message-template
required:
- to
- templateKey
type: object
properties:
to:
type: string
description: "Message destination. Specify a phone number that has been normalized to E.164 format and hashed with SHA256."
templateKey:
type: string
description: |+
Specify the key of the template you want to send.
For available keys, see https://developers.line.biz/en/docs/partner-docs/line-notification-messages/template/#templates
body:
"$ref": "#/components/schemas/PnpTemplatedMessageBody"
customAggregationUnits:
type: array
maxItems: 1
description: |+
Name of aggregation unit. Case-sensitive.
For more information about assigning a unit name, see https://developers.line.biz/en/docs/messaging-api/unit-based-statistics-aggregation/#assign-names-to-units-when-sending-messages
items:
type: string
maxLength: 30
minLength: 1
pattern: "^[a-zA-Z0-9_]{1,30}$"
PnpTemplatedMessageBody:
externalDocs:
url: https://developers.line.biz/en/reference/line-notification-messages/#send-line-notification-message-template
type: object
description: "The body object of the template you want to send. You can't specify the same item more than once in a single message."
properties:
emphasizedItem:
"$ref": "#/components/schemas/PnpTemplatedEmphasizedItem"
items:
type: array
maxItems: 15
description: "Array of items to include in the message. The `itemKey` must be unique across `emphasizedItem` and `items`."
items:
"$ref": "#/components/schemas/PnpTemplatedItem"
buttons:
type: array
maxItems: 2
description: "Array of buttons to include in the message. The `buttonKey` must be unique."
items:
"$ref": "#/components/schemas/PnpTemplatedButton"
PnpTemplatedEmphasizedItem:
externalDocs:
url: https://developers.line.biz/en/reference/line-notification-messages/#send-line-notification-message-template-items
required:
- itemKey
- content
type: object
description: "Item to emphasize in the message."
properties:
itemKey:
type: string
description: |+
Specify the key of the item you want to include.
For available keys, see https://developers.line.biz/en/docs/partner-docs/line-notification-messages/template/#items
content:
type: string
maxLength: 15
description: "String to be displayed as the value of the item."
PnpTemplatedItem:
externalDocs:
url: https://developers.line.biz/en/reference/line-notification-messages/#send-line-notification-message-template-items
required:
- itemKey
- content
type: object
properties:
itemKey:
type: string
description: |+
Specify the key of the item you want to include.
For available keys, see https://developers.line.biz/en/docs/partner-docs/line-notification-messages/template/#items
content:
type: string
maxLength: 300
description: "String to be displayed as the value of the item."
PnpTemplatedButton:
externalDocs:
url: https://developers.line.biz/en/reference/line-notification-messages/#send-line-notification-message-template-buttons
required:
- buttonKey
- url
type: object
properties:
buttonKey:
type: string
description: |+
Specify the key of the button you want to include.
For available keys, see https://developers.line.biz/en/docs/partner-docs/line-notification-messages/template/#buttons
url:
type: string
maxLength: 1000
description: "URL of the page to be opened when the user presses the button."

# Message objects
Message:
Expand Down
8 changes: 4 additions & 4 deletions openapi/upstream-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@
"$comment": "Provenance anchor for the vendored LINE OpenAPI spec snapshots under openapi/. Records which upstream commit the committed specs correspond to and their LF-normalized content hashes. Consumed by scripts/check-spec-drift.ps1 (drift detection) and scripts/generate.ps1 -Update (pinned re-fetch). Upstream (github.com/line/line-openapi) publishes no tags/releases and its spec info.version fields are static, so the upstream commit SHA is the only reliable version anchor. See docs/LINE-dotnet-client-design.md §9.",
"schemaVersion": 1,
"repository": "line/line-openapi",
"ref": "de8bd9e2872ed9d9800e23b86136695fcd370a0c",
"refDate": "2026-07-28",
"retrievedAt": "2026-08-19",
"ref": "fa5577c9ea874d2dbd8fadc85a4cb3a1b29d8cbe",
"refDate": "2026-09-29",
"retrievedAt": "2026-10-05",
"hashAlgorithm": "sha256",
"hashNormalization": "line endings normalized to LF before hashing",
"ignoredUpstreamFiles": [
"docker-compose.yml"
],
"specs": {
"messaging-api.yml": {
"sha256": "0227978ce1b3133e20da034fc33a9241000619ae4fea2fda7b61983abf79577a",
"sha256": "41033aa8491fc67ab09c4ec322f2aab072ae7b9402297e8c4f042eda0c2dd1fc",
"package": "Line.OpenApi.Messaging",
"imported": true
},
Expand Down
Loading
Loading