メインコンテンツへ移動

微信公衆プラットフォーム図文メッセージの自動生成

無料2016-03-06#Solution#微信订阅号群发消息#微信公众平台WordPress插件#wechat wordpress plugin#wordpress wechat plugin

WordPressプラグインを自作し、ブログ記事を微信公衆プラットフォームの図文メッセージに自動変換する

ちょっとした雑談

また更新を最後の日まで延ばしてしまいました。先週は書くことが多かったのですが、どうしてもやる気が起きませんでした。Androidのミニゲームで多くの問題に直面し、解決したと思ったらまた新しい問題が見つかりました。バグを修正する過程で不思議なものを見つけました:Mandelbrot Set(海の向こうでも、Android Canvasのパフォーマンス問題に頭を悩ませていた人がいたようです…)。

とても綺麗なGIF画像があるのですが、サイズが大きすぎる(26MB)ので、リンクを置いておきます:http://7xl5fb.com1.z0.glb.clouddn.com/mandelbrot.gif

1. ソリューションの選択

微信公衆プラットフォーム(WeChat Official Account Platform)のエディタが前回の更新(2015-11-20)以降、使い勝手が完全に損なわれてしまいました。綺麗なレイアウトにするには、サードパーティのオンラインエディタに頼るしかないようです。購読アカウントを登録した際、自動同期を検討していましたが、個人アカウントでは認証が下りず、インターフェースも開放されていないため、断念していました。

インターフェースの権限がなく、かつ手軽さを求めるなら、3つの選択肢があります:

  • サードパーティプラットフォームに委託する

  • 非公開インターフェースを使用する(ログインをシミュレートし、その後に…)

  • ブログ記事から図文メッセージを生成する(そして手動でコピー&ペーストする)

委託は予算がないため考慮しません。非公開インターフェースは長く検討しましたが、不安定であることに加え、利用可能なリソースが非常に少なく、実装に時間がかかるため(時は金なり)、諦めました。しかし、役立ちそうなものをいくつか見つけました:

  • WordPressプラグイン wechat\_subscribers

特色:最新記事、ランダム記事、検索結果などの自動返信。永久無料。

アドレス:https://github.com/Soopro/wechat\_subscribers

  • WordPressプラグイン Wechat-Manager

特色:キーワードによる最新記事、週/月/年間の最多コメント記事、検索結果の自動返信。

アドレス:https://github.com/9IPHP/Wechat-Manager

  • Nodeでカプセル化された Wechat API

特色:公式APIよりも使い勝手が良いはずです(Jackson Tian氏によるもので、貢献度70.2%)。

アドレス:https://github.com/node-webot/wechat-api

前述の2つのWPプラグインは強力ですが、図文メッセージの編集問題を解決することはできません。wechat\_subscribers なら可能かもしれませんが、最終的に別のプラグインを見つけたので、試すのをやめました。

おすすめは、非常に目立たない(私がスターを1つ付けたばかりの)WPプラグインです:

  • WP\_wechat\_text\_generator

概要:微信公式アカウントの記事を生成できるWordPressプラグイン。

アドレス:https://github.com/nervouna/WP\_wechat\_text\_generator

2. DIY

私はWPプラグインを書いたことがありません。調べながら修正したので少し時間がかかりましたが、なんとかなりました。ソースコードを手に入れてまず目に入ったのはLicenseです:

 * License: WTFPL
 *
 * DO WHATEVER THE FUCK YOU WANT, PUBLIC LICENSE
 * TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 *
 * 0. You just DO WHATEVER THE FUCK YOU WANT.

面白い作者ですね。興味があれば彼のホームページを覗いてみてください:IGNORE THE BLUEPRINT

具体的な修正プロセスについては多く語りません。あまり誇れることではありませんので(元の作者はPMで、実はjsから気づきました)。2つの厄介な問題に直面しました。

1. Markdown

プラグインが投稿内容を取得した後、explode で行(rows)に分け、'<p>'.row.'</p>' として出力していました。私のブログ記事はMarkdown形式なので、以下のようにプリプロセッサを通す必要があります:

// markdown transform
$wechat_item_content = apply_filters('the_content', $wechat_item_content);

上記のコードは汎用的なもので、Nodeの event.emit('the_content') に相当します。投稿内容を処理しようとするすべてのプラグインの関連関数を呼び出します。例えば、Markdownプラグイン内の:

add_filter('the_content',     'Markdown', 6);
add_filter('the_content',     'balanceTags', 50);

2. カスタムCSS

スタイルは必ず変更する必要があります。プラグインのスタイルはシンプルすぎて、codepre といったプログラマー専用のタグが美化されていません。スタイルの修正はjsで行われており、構造は以下の通りです:

function refineStyle() {
    // h2~h5
    var h2s = post.getElementsByTagName('h2');
    for (var i = h2s.length - 1; i >= 0; i--) {
        // .entry-content h2 { font-size: 18px; padding-left: 13px; margin: 20px 0; }
        h2s[i].style.fontSize = '18px';
        h2s[i].style.margin = '20px 0';
        h2s[i].style.background = '#66b3ff';
        h2s[i].style.padding = '4px 0';
        h2s[i].style.paddingLeft = '13px';
        h2s[i].removeAttribute('class');
    };
    // ...
}

document.addEventListener('DOMContentLoaded', function() {
    refineStyle();
    selectText('wechat-post');
});

こういうことです。実装は見苦しいですが(cssText で整形できます)、手法は巧妙です。PHPで投稿内容を解析してインラインスタイルを埋め込むとなると……考えただけでも恐ろしいです。整形後はこのようになります:

// table
var tables = post.getElementsByTagName('table');
for (var i = tables.length - 1; i >= 0; i--) {
    // .entry-content table, .comment-content table { border-bottom: 1px solid #ededed; color: #757575; font-size: 12px; line-height: 2; margin: 0.8em; margin-top: 0; width: 100%; }

    tables[i].style.cssText = 'border-bottom: 1px solid #ededed; color: #757575; font-size: 12px; line-height: 2; margin: 0.8em; margin-top: 0; width: 100%;';
    tables[i].removeAttribute('class');
    //!!! 注意要去掉w, h
    tables[i].removeAttribute('width');
    tables[i].removeAttribute('height');
};

cssText を使うとかなり楽になり、CSSからインラインスタイルへの変換も容易になります。

3. その他の問題

Chromeで問題が発生しました。記事を生成した後、selectText で記事全体を選択し、直接 Ctrl+C で微信エディタに貼り付けると、生成されたスタイルに問題が生じます。多くのスタイルが失われてしまうのです(注意:オンラインプレビューでは正しく見えますが、スマホに送信してプレビューすると、多くのスタイルが消えていることが分かります)。selectText の具体的な実装は以下の通りです:

function selectText(containerid) {
    var text = document.getElementById(containerid);

    // IE
    if (document.body.createTextRange) {
        var range = document.body.createTextRange();
        range.moveToElementText(text);
        range.select();
    } else {
    // others
        var selection = window.getSelection();
        var range = document.createRange();
        range.selectNodeContents(text);
        selection.removeAllRanges();
        selection.addRange(range);
    }
}

色々調べてみましたが解決策はなく、selectText メソッド自体にも問題はありません。そのため、最終的にはFirefoxの使用を推奨することにしました。

P.S. 実はChromeでも、自動選択された内容を使わずに、マウスで手動で全文を選択してからコピーすれば、正しく反映されます。この2つの違いがどこにあるのかは分かりません。

クリップボードへの自動コピーも検討しましたが、互換性が厄介そうで、特にChromeでは難しいようなので、やめました。

コメント

コメントはまだありません

コメントを書く