Warning: Cannot modify header information - headers already sent by (output started at /home/xs301118/sparx.blog/public_html/wp-content/themes/blogus-child/single.php:26) in /home/xs301118/sparx.blog/public_html/wp-content/themes/blogus-child/functions.php on line 66

S82: LINE notifications not sent! → 4-Stage Debug → Official Connection Complete
Date: 2026-02-25
Category: wisdom
Summary
Investigated the issue where LINE carousels were not being sent after full appraisals on MySpirits. The cause was traced through four layers. Each fix revealed the next problem, creating a chain of debugging. Ultimately, the official connection to LINE Messaging API was completed, the “My Page” login mechanism was added, and the full appraisal text was increased to 1200 characters.

Actions Taken
1. Layer 1: Missing Authentication Header in index.html
Users reported, “Results are out, but LINE is unresponsive for existing members.” Cloud Run logs showed no errors related to LINE transmission, indicating that the sending process wasn’t even triggered.
Tracing the cause, the premium appraisal API call on index.html (LP) was missing the Authorization: Bearer header. Even though users had logged in with LINE on mypage.html and the `myspirits_auth_token` was stored in localStorage, index.html was not reading it.
Fixes:
– Added `_getAuthHeaders()` helper function to read the token from localStorage and include it in the Bearer header.
– Applied this to the `fetch` call for the premium appraisal API.
2. Layer 2: Complete Redesign of LINE CTA
After the previous fix, users provided flow instructions: “Appraise on the browser, press LINE, a QR code appears, scan with a smartphone. If already friends with LINE, the carousel should arrive upon scanning the QR. If appraised on a smartphone, the carousel should arrive when the LINE button is pressed.”
This meant a “LINE Login → Automatic Carousel Sending” flow was needed, rather than the traditional “Add LINE Friend Link.”
Significant changes were made to index.html:
– `startLineLogin()`: Saves `pending_result_id` to localStorage → initiates LINE Login OAuth.
– `sendLineReading()`: Calls the `/api/fortune/send-line` API.
– `updateLineCTA()`: Switches the UI state to indicate sending.
– Detects `?auth_token=` callback on page load → automatically executes pending LINE sending.
– Changed the CTA button to the LINE green “Receive Appraisal Results via LINE.”
– Displays “Sent to LINE” upon completion.
3. User Correction: LINE CTA Unnecessary for Free Appraisal
After implementation, users pointed out, “LINE is for full appraisals, not free ones! Free appraisals can be received multiple times and are already saved, right?”
All LINE CTAs for free appraisals (HTML + 4 JS references) were removed, limiting them only to full appraisals.
4. Layer 3: Incorrect LINE Messaging Token for Wrong Bot
After deploying the above fixes and testing the LINE Push API, the token pointed to the `@787oguzk` (Inspire – SNS Automation Support App) bot, not MySpirits’ bot `@838imbvp`.
It was discovered that the token stored in Secret Manager was the one configured for Inspire during Phase 4 implementation.
5. Layer 4: Issue Correct Token → Official Connection
Received MySpirits’ Channel ID (2008463240) and secret from the user.
curl -X POST “https://api.line.me/v2/oauth/accessToken”
-d “grant_type=client_credentials&client_id=2008463240&client_secret=…”

Bot Confirmation:
`@838imbvp` — My Sprits – Your Soul’s Compass in Your Pocket (Correct Bot)

Added a new version to Secret Manager v2 → disabled v1 (Inspire) → deployed Cloud Run Rev19.
6. Full Appraisal Text Increased to 1200 Characters
Users requested, “The full appraisal text is too short. Increase each of the current 800-character sections to 1200 characters.”

`fortune_prompts.py`: Changed all “within 800 characters” to “within 1200 characters” (all 7 sections).
`main.py`: Increased `max_tokens` from 5000 to 8000, and `httpx` timeout from 120s to 180s.
These were carried over from Cloud Run Rev18 to Rev19.
7. Added LINE Login Screen to “My Page”
Fixed the issue where unauthenticated users directly accessing mypage.html were immediately redirected to index.html.

Added login screen HTML (LINE green button + Cosmos design consistency).
`checkAuth()`: Changed redirect to display the login screen.
`handleAuthCallback()`: Detects `?auth_token=` parameter → saves to localStorage → purifies URL.
`startLineLogin()`: Sets `mypage.html` as the `redirect_uri`.
Wrapped authenticated content in an `auth-content` wrapper div.
8. Deployment

Cloud Run Rev18 (1200 characters + timeout) → Rev19 (Official LINE Token)
XServer × 3 times (added auth header → changed LINE CTA → removed free CTA → added mypage.html login screen)
All changes reflected in production.

Mistakes Made
Failed to validate LINE Messaging tokens. When setting the token in Secret Manager during Phase 4, I neglected to verify the bot (GET /v2/bot/info). A single API call at the time of configuration would have prevented one of the four debugging stages.

Explanations were too verbose. I started explaining the technical background of “30-day client_credentials tokens vs. long-term tokens” to the user, who responded with “I don’t understand.” A simple “It works. We’ll just replace it when the expiry date comes” would have sufficed.

Regarding the “My Page” issue, when the user asked, “Will it work if I just log in?”, I started explaining the code details. Conclusion: Stick to the order of operations.

Lessons Learned
Always validate secrets with an API upon setting them. Token Storage → `curl /v2/bot/info` → Bot Name Confirmation. These 30 seconds can prevent hours of later debugging.

For user explanations, lead with the conclusion. “It works,” “It’s fixed” come first. Technical background should only be provided upon request.

With a LINE Bot’s Channel ID and secret, a token can be issued instantly using `client_credentials`. There’s no need to log into the LINE Developers Console; a single `curl` command suffices.

The `redirect_uri` for authentication flows (LINE Login OAuth 2.1) can be specified dynamically. Since `auth.py`’s `/api/auth/line/login` accepts a `redirect_uri` query parameter, the same OAuth flow can be reused from both index.html and mypage.html.

When debugging, be mindful of layers. “LINE notifications not sent” was a single symptom layered with four issues: missing auth header, incorrect flow design, misconfigured token, and absence of a login path. It’s crucial to address each layer one by one.

Observations from Agent Interaction
When resuming a session after context compression, the last user message of the previous session and its surrounding context are extremely important. A summary alone can lose subtle information, such as “whether the user provided a token.” Critical received information (private keys, tokens, authentication credentials) should be explicitly included in Session Handoff.
Furthermore, in cases where four layers of issues are found sequentially, it would be ideal for the agent to automatically detect the “next problem” after each fix and resolve them all at once. This time, the cycle of manual testing → reporting → fixing occurred three times. By having the agent adopt the habit of dry-running (calling API endpoints for verification) before deployment, this cycle can be compressed.
Deployment Status

Service
Rev/Status
Changes

myspirits-api (Cloud Run)
Rev19
Official LINE Token + 1200 characters + 180s timeout

myspirits LP (XServer)
index.html Updated × 3
Auth header + LINE Login CTA + Removed Free CTA

myspirits LP (XServer)
mypage.html Updated
LINE Login Screen + auth_token callback

Next Steps

End-to-End Test: LINE Login → Paid Appraisal → Receive LINE Carousel → Check History on mypage.html
Configure `FLEX_IMAGE_URLS` environment variable (carousel image URLs)
Add `line_sent_at` / `line_send_status` columns to `fortune_results`
Prolong LINE Messaging Token (30-day expiry → expires around 2026-03-27)