Open4
Google Chart APIが廃止したみたいなのでNestJSを使って互換性のあるAPIを自作する
QRコードの動的生成にGoogle Chart APIを使用していたが、2024年4月頃から404を返すようになった。以前から廃止と言われていたけど使えていたので使っていたがついに使えなくなったようだ。
代替サービスに「QR code API」というのがあったが、生成される画像がやや違った。今回はGoogle Chart APIで出てくる画像と、全く同じ画像がほしかったので自作してみる。
import { Storage } from '@google-cloud/storage';
import { Controller, Get, Query, Res } from '@nestjs/common';
import { Response } from 'express';
import * as QRCode from 'qrcode';
import { finished } from 'stream/promises';
export class Options {
text: string = '';
size: number = 512;
}
@Controller(`tool`)
export class QrCodeGenerator {
private readonly storage = new Storage();
@Get('qrcode')
public async action(@Query() options: Options, @Res() res: Response): Promise<void> {
// バリデーション
if (!options.text) {
throw new Error('textを指定してください。');
}
const fileName = `qrcode/${encodeURIComponent(options.text)}_${options.size}.png`;
// GCSにあるか
const bucket = this.storage.bucket(process.env.GCLOUD_STORAGE_BUCKET_FOR_QRCODE);
const blob = bucket.file(fileName);
const exists = await blob.exists();
// なければ作成
if (!exists[0]) {
console.log(`作成します。text: ${options.text}`);
try {
const blobStream = blob.createWriteStream();
// Google Chart APIに合わせる
await QRCode.toFileStream(blobStream, options.text, {
width: options.size,
margin: 5,
errorCorrectionLevel: 'L',
});
await finished(blobStream);
} catch (e) {
console.error(e);
throw new Error('失敗しました。');
}
}
blob.createReadStream().pipe(res);
}
}
これで全く同じ画像ができた。初めてのアクセスの時に作成してキャッシュしている。