電池充電器を新調した

今まで電池の充電にはずっと古いもの、SANYOブランドのENELOOP充電器を使っていたのですが、充電に時間がかかるのと、電池の充電に失敗することがあったので、電池が悪いのか充電器が悪いのかよく分かりませんでした。
そろそろ買い換えた方がいいだろうと、急速対応と診断機能付きのこの製品を選択しました。
といっても、最低限の機能のものと、この多機能のものしか選択肢がありませんが。
早速使ってみたところ、体感でわかるほど充電完了が速いのと、充電開始時と終了時に状態も診断してくれた結果1本の寿命が判明したので、12年頑張ってくれた感謝とともに廃棄することになりました。
これでストレスなく使い回せるようになりましたとさ、でめたし、でめたし。

テキストをクリップボードへコピーするJavaScript

UIを考える上で、コピペのための機能が欲しくなったので用意しました。
検索すると色々出てくるのですが、使い勝手が悪いというかなんというか。
実用に堪えるものがなかったので自作しました。
クラス名co2cl (copy to clipboard)を付与した要素を対象に動作します。
動作時にカーソルが一瞬変わります。
エラー補足できなさそうなので判定はありません。
非SSL用コードです。

HTML部

<span class="co2cl">テキスト</span>
<form><input type="text" class="co2cl" value="インプット"></form>

JvaScript部

$(function(){ //console.log(co2cl);
	co2cl.load();
});

var co2cl = {
	version: '2023-12-07',
	//-------- LOAD
	load: function(){
		var target = $('.co2cl'); //console.log(target);
		target.each(function(i, elm) { //console.log(i, elm);
			// コピー用ボタン
			var html = ''
				+'<button'
					+' type="button"'
					+' class="co2cl_btn"'
					+' onclick="co2cl.run(this)"'
				+'>'
					+'copy'
				+'</button>';
			$(elm).after(html);
		});
	},
	//-------- RUN
	run: function(caller){ //console.log(target);
		var target = $(caller.previousElementSibling); //console.log(target);
		var tagName = target.get(0).tagName; //console.log(tagName);
		// フォーム部品とそれ以外で取得先が異なる
		var value = (tagName == 'INPUT' || tagName == 'TEXTAREA')
				? target.val()
				: target.text(); //console.log(value);
		// コピペ用フォーム
		var html = ''
			+'<form>'
				+'<textarea'
					+' id="co2cl_temp"'
					+' class="co2cl"'
					+' style="position:absolute;left:-9999px"'
				+'>'
				+'</textarea>'
			+'</form>';
		$('BODY').append(html);
		var temp = $('#co2cl_temp'); //console.log(temp);
		temp.html(value);
		temp.select();
		document.execCommand('copy');
		$(temp).remove();
		//---- カーソル変更
		$(caller).css('cursor','wait');
		setTimeout(function(){$(caller).css('cursor','pointer');}, 200);
	}
};

Gmailにメールを送りたい

現在 2023-11-15 における話です。
前置きですが、普段使いのドメインでは一応簡単な対策を済ませてあります。
Gmail同士であれば届くので、なんとなく後回しにしていたのですが、徐々に色々と情報が上がってきたみたいなので、今頃なんとかしようかなと。
自分のGmailには届くのに、他人のGmailには届かないなどのよく分からない挙動をしていたのもあって、検証方法を確立できなかったのもありますが。
今回の記事は、放置していたドメインを使用したものです。

結構前になります、Gmailがなりすましメール対策とした施策により、独自ドメインでメールを送っても届かないことがある問題が発生します。
何もしない状態でGmailにメールを送ると以下のエラーが返ってきます。
送信元はcoreserver v1、情報の一部は「*」でマスクしています。

Hi. This is the qmail-send program at ***.coreserver.jp.
I'm afraid I wasn't able to deliver your message to the following addresses.
This is a permanent error; I've given up. Sorry it didn't work out.

<***@gmail.com>:
mail-remote: /lib64/libcrypto.so.10: no version information available (required by qmail-remote)
qmail-remote: /lib64/libssl.so.10: no version information available (required by qmail-remote)
r74.125.204.26 failed after I sent the message.
Remote host said: 550-5.7.26 This mail has been blocked because the sender is unauthenticated.
550-5.7.26 Gmail requires all senders to authenticate with either SPF or DKIM.
550-5.7.26 
550-5.7.26  Authentication results:
550-5.7.26  DKIM = did not pass
550-5.7.26  SPF [***.***] with ip: [***.***.***.***] = did not pass
550-5.7.26 
550-5.7.26  To mitigate this issue, please visit Gmail's authentication guide
550-5.7.26 for instructions on setting up authentication:
550 5.7.26  https://support.google.com/mail/answer/81126#authentication g8-20020a63fa48000000b005b3b889619asi7663244pgk.606 - gsmtp

--- Below this line is a copy of the message.

(略)

SPF または DKIM がないよと言われました。
まずはSPFを設定してみます。
SPFとは簡単に説明すると、ドメインとIPを紐付ける設定です。
紐づいていないIPからのメールはなりすましとみなされます。
DNSに、TXTレコードを追加します。
検索して共通して出てくるのは、以下のような記述です。

txt @ v=spf1 ip4:***.***.***.*** include:***.*** ~all

DNS浸透を待ってメールを送ります。
チェックツール SPF Surveyor を利用すると大量にエラーを吐いているのですが、意味がよくわかりません。
とりあえずメールを送ってみると無事に届きます。
しっくりこないので、もう少し調べてみました。
サーバー名を変更している場合、ドメインを明示するだけで良いようです。
もしかすると、そのIPに別のドメインが設定されていない、つまり仮想ホストを設定していない場合に限られるかもしれません。

txt @ v=spf1 a:***.*** ~all

これでチェックツールでもpassしました。
もちろん、Gmailにメールを送ることも出来ます。
これでSPFについては安心です。

さて、SPF未設定時のエラーメールには SPF または DKIM がないというエラーがありますが、Gmailとしては SPF と DKIM の両方を設定するよう求めています。
SPFだけでメールが届いたのはたまたまと考えておいたほうが無難です。
このSPFの設定だけでは、届かないGmailアドレスがあります。
もしかすると、アドレスによってメールサーバーが異なり、チェックのレベルが統一されていないだけかもしれません。
または、これまでの利用状況から独自ドメインと自分のGmailが紐づいていて、自分同士のメールは厳格にチェックしないなどホワイトリストに入っているだけなのかもしれません。
時間が経てば届かなくなる可能性があり、今のうちに対応しておいたほうがいいでしょう。

ということで、DKIMを設定します。
と言いたいところですが、先にある通りcoreserver v1はDKIM非対応です。
同じ業者の方がいいだろうということで、coreserver v2の契約を検討中です。
ひとまずここまで。

プリンタサーバ死亡

FujiFilmBI ApeosPro C650のプリンタサーバが死んだので、今日10日の印刷業務は完全に沈黙しました。
明日11日中の復旧も怪しく、設定を復元できるかもわからないので、今週の印刷業務は絶望的です。

ログオン画面が出ません。
起動を始めると、通常は青い窓とクルクルがでて間もなく写真とユーザ選択画面が出るのですが、写真が出たところで先に進みません。
配線を抜き差ししてもダメ、電源ケーブル以外抜いて起動してもダメ、Ctrl+Alt+Delも反応なし。
ただし、シャットダウンと再起動は反応するものの、完全に終了は出来ずにずっと終了していますの画面になるので強制終了。
セーフモードであれば起動できるものの、ソフトウェアが起動しないので何も出来ず。
明日11日にHDDを入れ替えて再セットアップになる予定。
設定とか復元できればいいけど、出来なかったらどうしようorz=3

プリンタサーバ(コントローラ)
定価176万円
https://www.fujifilm.com/fb/product/publishing/apro_c810/price.html?lnk=pstop

Twitterのアイコンを青い鳥に戻すTampermonkeyスクリプト

Twitterのアイコンが青い鳥からXに変わってしまいました。
どうしても青い鳥が良いという方のために用意しました。

ページ(https://twitter.com/home)の読み込み完了後、3秒後にロゴを書き換えます。
ページが読み込まれてから画面が書き換わるまで時間がかかるようであれば、タイマーの3000を5000など大きく変更してください。
動作確認はPCのみ、ブラウザはChrome・Edge・Vivaldiです。
Firefoxは少し前からTampermonkeyは動かなくなっている感じです。

※ 色の指定が抜けていたので、追加したものが0.2


// ==UserScript==
// @name Twitterのアイコンを青い鳥に戻す
// @namespace http://tampermonkey.net/
// @version 0.2
// @description none
// @author penlabo
// @match https://twitter.com/*
// @grant none
// ==/UserScript==

(function() {
'use strict';
setTimeout(change, 3000);
function change(){
var target = document.querySelector('h1 > a > div');
target.innerHTML = '<svg viewBox="0 0 24 24" style="fill:#1da1f2" aria-hidden="true" class="r-1cvl2hr r-4qtqp9 r-yyyyoo r-16y2uox r-8kz0gk r-dnmrzs r-bnwqim r-1plcrui r-lrvibr r-lrsllp"><g><path d="M23.643 4.937c-.835.37-1.732.62-2.675.733.962-.576 1.7-1.49 2.048-2.578-.9.534-1.897.922-2.958 1.13-.85-.904-2.06-1.47-3.4-1.47-2.572 0-4.658 2.086-4.658 4.66 0 .364.042.718.12 1.06-3.873-.195-7.304-2.05-9.602-4.868-.4.69-.63 1.49-.63 2.342 0 1.616.823 3.043 2.072 3.878-.764-.025-1.482-.234-2.11-.583v.06c0 2.257 1.605 4.14 3.737 4.568-.392.106-.803.162-1.227.162-.3 0-.593-.028-.877-.082.593 1.85 2.313 3.198 4.352 3.234-1.595 1.25-3.604 1.995-5.786 1.995-.376 0-.747-.022-1.112-.065 2.062 1.323 4.51 2.093 7.14 2.093 8.57 0 13.255-7.098 13.255-13.254 0-.2-.005-.402-.014-.602.91-.658 1.7-1.477 2.323-2.41z"></path></g></svg>';
}
})();

更新:クリックポストで「Amazon Pay」の支払手続きをTampermonkeyで自動実行するスクリプト

前の記事から更新しました。
一日使用してみまして、実際の挙動を確認したところで修正を行いました。
ボタンをクリックしてページ変移が始まればTampermonkeyでの処理が終わるかと思っていたのですが、ループが進んでいたので明示的に抜けるように変更しました。

// ==UserScript==
// @name         クリックポスト:一時保存(Amazon Pay)
// @namespace    http://tampermonkey.net/
// @version      2023-05-01
// @description  “内容品”が「/skip」ではないお届け先の“支払手続き”を自動で実行します。
// @author       penlabo
// @match        https://clickpost.jp/packages/list
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
    onload = function (){
        var line = 1;
        while (1) {
            var elmTarget = document.getElementById('AmazonPayCV2Button' + line);
            if (!elmTarget) return false;
            var elmParent = elmTarget.parentNode;
            var elmPrevious = elmParent.previousElementSibling;
            var elmText = elmPrevious.innerText;
            if (elmText != '/skip') {
                elmTarget.click();
                return false;
            }
            elmParent.style.backgroundColor = 'lightgrey';
            line++;
        }
    };
})();

その後の手続きを実行するものも追記しておきます。

// ==UserScript==
// @name         クリックポスト:決済(Amazon Pay)
// @namespace    http://tampermonkey.net/
// @version      2023-05-01
// @description  決済を実行します。
// @author       penlabo
// @match        https://payments.amazon.co.jp/checkout?*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
    var target = document.querySelector('#a-autoid-0 > span > input');
    target.click();
})();

// ==UserScript==
// @name         クリックポスト:支払手続き完了(Amazon Pay)
// @namespace    http://tampermonkey.net/
// @version      2023-05-01
// @description  支払手続き完了を実行します。
// @author       penlabo
// @match        https://clickpost.jp/amazon_pay/confirm?*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
    var target = document.querySelector('#payment_complete_message > input');
    target.click();
})();


これで全自動で処理が進みます。

クリックポストで「Amazon Pay」の支払手続きをTampermonkeyで自動実行するスクリプト

日本郵便のクリックポストは、お届け先毎に支払手続きを実行しなければなりません。
さらに、その先で決済を実行する手続きも必要になります。
件数が多くなると、PCに張り付いて作業しなければならず、操作が面倒です。
ということで、この手続きを自動で実行させようということです。
…が、このスクリプトはお届け先の一覧画面から個別の決済画面に飛ぶだけのものです。
決済を実行するものは近いうちに用意します。

なお、このスクリプトは「Amazon Pay」用に用意したもので、「Yahoo!ウォレット」では動作しません。

このスクリプトは、クリックポストのサイト「一時保存」でお届け先を一覧表示した状態で動作するように制限を設けています。
「まとめ申込み」では動作しません。
ところで、クリックポストでは登録したお届け先を任意に削除することができません。
そこで、誤って登録したり保留したいものなど、支払いを実行したくないお届け先は、内容品を「/skip」に変更してください。
これ以外のお届け先について、支払手続きを自動で実行します。
なお、内容品の変更時には一度決済画面を表示することになりますので、決済用のスクリプトは切っておかないと決済が実行されますのでご注意ください。

この画面の場合、1件目の手続きは実行せず、2件目を実行します。
お届け先の一覧が空になるか、内容品が「/skip」のものだけが残った状態で動作を終了します。

余談ですが、他サイトで紹介されている同様のスクリプトでは、お届け先の全てが処理の対象になっているものしかないと思います。
日本郵便側で受付処理を行うまでは決済が確定することはありませんが、発行済として一覧から消えるため処理済みとして扱ってしまう、追跡番号が発行されることで発送通知を誤って送信してしまう、などの問題に繋がる可能性があります。
有用そうな記事が一つ上がると、内容を精査せずパクり記事が量産されるので本当にたちが悪いと感じます。
便利なものほど、実際に挙動を確認したり、実務への影響を考慮して欲しいところです。

コードは分かりやすいように努めました。
コメントや説明がなければ処理を追えない場合は、このスクリプトは使わない方がよいでしょう。

ブラウザで手続きを自動化するには、拡張機能のTampermonkeyを利用します。
おそらくGreasemonkeyでも動作しますが未確認です。
これらの使い方はここでは説明しませんので、他所で確認してください。

以下のコードを保存してください。

// ==UserScript==
// @name         クリックポスト:一時保存(Amazon Pay)
// @namespace    http://tampermonkey.net/
// @version      2023-04-30
// @description  “内容品”が「/skip」ではないお届け先の“支払手続き”を自動で実行します。
// @author       penlabo
// @match        https://clickpost.jp/packages/list
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
    onload = function (){
        var line = 1;
        while (1) {
            var elmTarget = document.getElementById('AmazonPayCV2Button' + line);
            if (!elmTarget) return false;
            var elmParent = elmTarget.parentNode;
            var elmPrevious = elmParent.previousElementSibling;
            var elmText = elmPrevious.innerText;
            if (elmText == '/skip') {
                elmParent.style.backgroundColor = 'lightgrey';
            }
            else {
                elmTarget.click();
            }
            line++;
        }
    };
})();