EST. 2026 — Notes from real server work SYSADMIN · SECURITY · AI · DIRECTADMIN Issue 01
THE SYSADMIN ALMANAC
Home / Tags / ภาษาไทย
ภาษาไทย

#ภาษาไทย

31 articles
Workflow
Bank Open API QR Payments — From Sandbox to Status Lifecycle
Web

Bank Open API QR Payments — From Sandbox to Status Lifecycle

A static PromptPay QR is easy to build yourself, but nothing tells you whether the customer has paid. This article walks through a bank's Open API sandbox, from requesting a token and issuing a dynamic QR to tracking REQUESTED/PAID/CANCELLED/VOIDED states and the requestDt trap that rejects requests even when the entire payload is correct.

#api#rest-api#payment#qrcode
10 min read·25 Oct
Migrating an Old .aspx Site to a JSON Catalog and Filtering Images
Web

Migrating an Old .aspx Site to a JSON Catalog and Filtering Images

The owner of an old .aspx site asked me to rebuild it, but more than a decade of content was in a database I could no longer access. I collected the pages from the site itself to build a JSON catalog that preserved every legacy_id, then wrote a three-layer image filter to keep stray QR codes from becoming article covers.

#python#web-scraping#crawler#migration
10 min read·23 Oct
Let Clients Pick Photos on a Web Page Without a Login
Web

Let Clients Pick Photos on a Web Page Without a Login

When the person choosing photos for a website is not comfortable with computers, adding registration and login means the work stops at the login screen. This article covers a photo picker with no authentication at all, but with a server endpoint that checks every value against an allowlist strict enough to leave nothing from arbitrary input, plus limits at every layer and a backup before every write.

#php#javascript#web-security#permissions
8 min read·23 Oct
Scripting Government PDF Forms and Making Safer ID Copies
AI

Scripting Government PDF Forms and Making Safer ID Copies

Government PDFs distributed as fillable forms often cannot actually handle Thai text. Subdivided fields let digits run over the borders, and tone marks collide with vowels above the line. This article covers listing field names first, filling the fields and flattening them into page content, drawing Thai text with a font that includes all the vowel marks, and making actual-size ID copies with purpose-specific watermarks.

#pdf#python#document#printing
10 min read·22 Oct
Building a Graph API Page App with Three Required Endpoints
Web

Building a Graph API Page App with Three Required Endpoints

When a backend needs to read and reply to Page messages on its own, the only proper route is to build an app and pass the platform's review. This article covers three endpoints the platform requires but people forget until they fail review, the correct way to verify incoming request signatures, and the steps to exchange a short-lived token for a Page token stored outside the web root.

#api#rest-api#php#web-security
10 min read·22 Oct
A Report Form for a Static Site with No Backend
Web

A Report Form for a Static Site with No Backend

A calculator site made entirely of static files has no server to handle forms, but users still need a way to report mistakes in the formulas. This article covers the one approach I chose—a single worker file that accepts POST requests on one route, verifies Turnstile on the server using the real client IP, accepts images pasted from the clipboard, and sends email from the network edge—along with three traps that cost me an entire night.

#cloudflare#static-site#javascript#web-security
9 min read·21 Oct
Speed Up Screen Recordings While Keeping the Original Clock
AI

Speed Up Screen Recordings While Keeping the Original Clock

How to make a timelapse from a screen recording by speeding up idle sections more than active sections, using split, trim, and setpts, then joining them with concat. The main trap is that drawtext must come before setpts for the clock to follow the original timeline instead of the accelerated one.

#ffmpeg#video-editing#python#automation
9 min read·20 Oct
A Cookie Banner That Loads GTM and GA4 Only After Consent
Web

A Cookie Banner That Loads GTM and GA4 Only After Consent

Most cookie banners look good but block nothing, because GTM and GA4 have already loaded from the first line of the page. This article covers a setup that loads the container only after acceptance, puts GA4 inside GTM to prevent double counting, hides AdSense slots initially, and checks that outgoing requests to those services stay at zero.

#seo#adsense#javascript#playwright
9 min read·18 Oct
Reading ID Cards from the Web with a Localhost Agent
Hardware

Reading ID Cards from the Web with a Localhost Agent

Browsers cannot access smart card readers directly. A workable approach is to write a small agent that opens a port on localhost and let the web page call it. This article covers secure contexts, CORS preflight, port conflicts with other agents, PC/SC in SHARED mode, decoding TIS-620 manually, and the day antivirus flagged the program as a backdoor.

#hardware#cpp#windows#gui
11 min read·16 Oct
Food Factory Drawings: Sheets, Scales, and Paper Sizes
AI

Food Factory Drawings: Sheets, Scales, and Paper Sizes

A food factory application drawing set has 7 items, each with its own scale range, and some numbers to work out before drawing—how wide a plan will fit on A4 or A3 at 1 to 100, and how to split it across sheets without changing the scale if it will not fit.

#drafting#cad#sketchup#3d-modeling
10 min read·4 Oct
From Model to 6-Meter Steel Cutting Layout and Workshop Cut Sheet
AI

From Model to 6-Meter Steel Cutting Layout and Workshop Cut Sheet

Read part lengths from the model, consolidate duplicates, then arrange a first-fit decreasing cutting layout on standard 6-meter stock with a 3-millimeter saw kerf allowance, plus a notch-and-bend option for right-angle corners that reduces joints from 12 to 6

#structural#steel-design#sketchup#ruby
9 min read·3 Oct
Quantity Takeoff from SketchUp Models with Ruby Scripts
AI

Quantity Takeoff from SketchUp Models with Ruby Scripts

A finished model already contains every number a quantity takeoff needs. Give groups readable names from the start, then write a script to grep through them, with two traps to watch for that can double your areas.

#3d-modeling#sketchup#ruby#drafting
9 min read·3 Oct
SketchUp Drawing Sheets with Automatic Labels and Dimensions
AI

SketchUp Drawing Sheets with Automatic Labels and Dimensions

A finished model is not ready for submission yet. What the authorities accept is a set of paper sheets with building numbers, dimension lines, a north arrow, and a scale. This article covers extracting geometry from the model as numbers, rendering a top ortho view as black lines on white, and letting a script place numbers and dimension lines without overlaps, with overrides for individual items.

#3d-modeling#sketchup#ruby#python
10 min read·2 Oct
Mapping a Building by Phone and Finding True North with GNSS
AI

Mapping a Building by Phone and Finding True North with GNSS

ARCore gives room-corner coordinates in meters accurately enough to use, but its world frame has an unknown orientation, so the resulting plan is always rotated by some angle. The fix is to collect pairs of (AR position, GNSS reading) while working, then fit a rotation using weighted 2D Kabsch, with weights based on each fix's accuracy, to find both north and the origin's coordinates.

#gis#geospatial#mapping#android
10 min read·2 Oct
Rebuilding an Off-Scale PDF Plan at Real Dimensions
AI

Rebuilding an Off-Scale PDF Plan at Real Dimensions

Presentation plans are often drawn block by block, with different scales for the x and y axes and different scales again for each room. Calibrating the whole page once and tracing it gets everything wrong. This article covers extracting coordinates from paper into metres by recalculating the scale for every room, counting objects with colour-blob BFS instead of by eye, and drawing them back into a model at their real dimensions.

#3d-modeling#sketchup#python#pdf
10 min read·1 Oct
Shared Neutrals Across Transformers: Why Phase Balancing Is Not Enough
Hardware

Shared Neutrals Across Transformers: Why Phase Balancing Is Not Enough

A case involving two transformers with interconnected neutrals and houses tapped into one side's main feeder, leaving phase A 30-40 A higher even on days off, plus a meter-reading trap that can suggest a 200 A difference if the CT ratio is not verified first, and a repair sequence that must be followed in order.

#hardware#electrical#power#engineering
9 min read·30 Sep
Sizing Main Cables and Breakers by Installation Method
Hardware

Sizing Main Cables and Breakers by Installation Method

Notes on choosing the main cable and breaker for a new 253 A feeder, why the same size CV cable can carry 227 A or 364 A depending on how it is installed, and the option of downsizing to 95 and compensating with operating rules, at the cost of the main breaker tripping if anyone breaks those rules.

#hardware#electrical#power#engineering
10 min read·29 Sep
Diagnosing Feeder Overload from Melted Insulation and Duty Cycles
Hardware

Diagnosing Feeder Overload from Melted Insulation and Duty Cycles

My investigation of a 95 mm² main cable with insulation melting at scattered points even though the system seemed to work normally, from the nameplates of 6 washers and dryers totaling 234.7 kW to a minute-by-minute current model explaining why a 482 A load on a cable rated for 180 A had not caused a visible system failure.

#hardware#electrical#power#engineering
10 min read·28 Sep
A Single-Page PHP and SQLite Document Vault That Keeps Originals
Linux

A Single-Page PHP and SQLite Document Vault That Keeps Originals

A document photo storage app for government submissions, using photos taken on site with a phone. Each upload produces three files—the display image, the original, and saved crop settings—so adjustments can be made later without losing quality, with automatic migration from JSON to SQLite and web server restrictions on folders containing personal data.

#php#sqlite#document#security
9 min read·27 Sep
Printing Dozens of Government Forms from HTML with Correct Margins
Linux

Printing Dozens of Government Forms from HTML with Correct Margins

A government submission document system where users click Print in their browsers and every sheet must fit within its margins, from measuring the actual printable area in millimeters and repeating headers and footers without position fixed, to four image frame types for different documents and automated overflow checks with Playwright instead of inspecting every sheet.

#pdf#php#css#printing
10 min read·26 Sep
News Stuck for Three Days Because the Feed Wasn't Sorted by Date
Linux

News Stuck for Three Days Because the Feed Wasn't Sorted by Date

The news site's homepage showed the same day's stories for three days straight, even though scheduled jobs ran, translations finished, and every step reported success. The causes were an RSS feed sorted by relevance rather than date, string sorting of pubDate that actually sorted by weekday name, and requesting too few stories, leaving nothing after filtering before the rest even got a look.

#python#javascript#rss#automation
10 min read·25 Sep
Generating Thai PDF Quotes with Chromium and the Pitfalls I Hit
Linux

Generating Thai PDF Quotes with Chromium and the Pitfalls I Hit

Building a system to generate PDF quotations from HTML with Chromium for multiple companies in a group and multiple templates, from an Executable doesn't exist error caused by looking for the wrong headless shell, to A4 layout and pagination, sanitizing Thai filenames, and a token-based document numbering system where an accidental slash broke the path.

#pdf#chromium#playwright#python
9 min read·31 Aug
Thai Steel Framing Conventions for Buildable Drawings
AI

Thai Steel Framing Conventions for Buildable Drawings

A steel frame model that looks good on screen but makes a fabricator shake their head usually gets a few conventions wrong—member order, stock sections, stacking instead of interweaving, purlins that must be open C sections, and bearing edges on sloping beams that cause steel to intersect when chosen incorrectly.

#structural#steel-design#sketchup#3d-modeling
9 min read·30 Aug
Import Land Parcel Boundaries from Government Maps into SketchUp
AI

Import Land Parcel Boundaries from Government Maps into SketchUp

A SketchUp model with Add Location has satellite imagery but no parcel boundaries. This article covers fetching boundaries through OGC-standard WFS, where viewparams is required to avoid getting zero features, converting UTM47 coordinates to WGS84, and placing them in the model with latlong_to_point to line up with the imagery.

#gis#sketchup#ruby#wfs
9 min read·28 Aug
WAF Returns 406 for Thai Text in POST: Fixing It Without Root
Security

WAF Returns 406 for Thai Text in POST: Fixing It Without Root

ModSecurity on the host returns 406 for certain Thai sentences in the POST body, preventing forms from saving — but as a hosting tenant, I cannot change the rules myself. This article shows how to isolate the offending text through black-box testing, then work around it with JS encoding on submit + middleware decoding in Laravel.

#modsecurity#waf#laravel#php
9 min read·15 Aug
Bulk Import Legacy .xls Files into Laravel with PhpSpreadsheet
Linux

Bulk Import Legacy .xls Files into Laravel with PhpSpreadsheet

Legacy .xls files with Thai headers encoded in tis-620 have unreadable column names, large files make PhpSpreadsheet exhaust memory and crash, and files users merge themselves contain duplicate rows — use column positions instead of names, add a read filter, and deduplicate with a natural key.

#php#laravel#excel#phpspreadsheet
9 min read·10 Aug
Charset Mismatch Silently Kills JOIN Indexes — an utf8mb4 Mirror
Linux

Charset Mismatch Silently Kills JOIN Indexes — an utf8mb4 Mirror

The old database uses tis620 and the new one uses utf8mb4. JOIN across databases, and every index immediately becomes decorative without a single error — how to prove it with EXPLAIN and build a mirror that converts tis620 to utf8mb4 during the dump, plus the sed trap that silently breaks tables.

#mariadb#mysql#charset#utf8mb4
10 min read·6 Aug
Thai Data Migration Traps: VARCHAR, Idempotency, and OCR Vowels
Linux

Thai Data Migration Traps: VARCHAR, Idempotency, and OCR Vowels

Lessons from importing and migrating hundreds of thousands of Thai data rows — undersized VARCHAR columns silently truncating synthetic keys into collisions, idempotency requiring DELETE before INSERT to stop totals reaching 200%, collation treating su001 and SU001 as equal while storing both, and Thai vowels corrupted by OCR that need a normalization map before insert

#migration#mariadb#mysql#debugging
9 min read·24 Jul
Government ICT Computer Price Criteria + DIY Builds with Scripts
Linux

Government ICT Computer Price Criteria + DIY Builds with Scripts

The December 2568 government ICT reference price criteria clearly define specifications for 20,000 baht office computers and 24,000 baht processing computers. In this article, I read the actual criteria item by item, then write a Python script to pull Advice prices and put together DIY builds to compare how much better the value is than buying prebuilt machines.

#sysadmin#python#automation#hardware
9 min read·22 Jul
~30 Seconds Turns Tiny: Flarum's Litedown Subscript Trap
Linux

~30 Seconds Turns Tiny: Flarum's Litedown Subscript Trap

Write "~30 seconds" in a Flarum post and 30 turns into a tiny subscript — because Flarum's Litedown interprets ~ as a subscript opener. Thai users who use ~ to mean "approximately" run into this regularly. This article explains the cause, workarounds, and database fixes for content stored as s9e XML rather than raw markdown.

#flarum#markdown#debugging#php-fpm
6 min read·18 Jul
Generate PromptPay QR (EMVCo) in Pure Python — No External Libraries
Linux

Generate PromptPay QR (EMVCo) in Pure Python — No External Libraries

Want to generate PromptPay payment QR codes in your own POS/web system without calling a bank API? In this article, I build the EMVCo TLV string + CRC16 myself in pure Python, producing a payload that matches the Thai QR specification and can be scanned for payment by any banking app, along with the pitfalls that stop apps from reading it.

#python#promptpay#api#automation
8 min read·15 Jul