連載最終回です。今回は、ブログのビジュアル差別化である「4コマ漫画サムネイルの自動生成」と、現実的な副業収入を得るための「楽天アフィリエイト連携・自動投稿」の仕組みについて解説します。
1. 4コマ漫画サムネイルの自動生成
よくある自動化ブログでは、フリー素材サイトのAPIから画像を引っ張ってきますが、それはいかにも「量産型AIサイト」という印象を与えてしまいます。本システムでは、記事内容に完全に連動したオリジナルの4コマ漫画をAIで生成します。
記事要約からのプロンプト構築
生成された記事本文(HTML)から余分なタグを排除したテキストを取得し、Geminiに渡して要約させます。そして、ブログごとの画風設定(manga_config)と組み合わせて英語のプロンプトを構築します。
manga_prompt_instruction = f"""
記事タイトル: {extracted_title}
記事の要約: {body_summary}
以下のテンプレートに従い、[TOPIC]部分だけを書き換えて英語のプロンプトを出力せよ:
"A safe-for-work 4-panel Japanese manga comic strip (yonkoma style) about [TOPIC]. Drawn in a {manga_author}. Panel 1: setup scene with two characters ({manga_characters}). Panel 2: rising action with comedic misunderstanding. Panel 3: surprising twist related to [TOPIC]. Panel 4: funny resolution with both characters reacting. Clean lineart, family-friendly, {manga_style}."
"""
これにより、ブログのテーマごとに最適化された4コマ漫画(例:投資ブログならスーツのキャラクターがNISAを優しく解説する4コマ)が、画像生成モデル(DALL-E 3やMidjourney)を通じて自動で描画・挿入されます。
2. 楽天アフィリエイト連携(商品選定アルゴリズム)
ただアフィリエイトリンクを羅列するだけでは誰もクリックしません。本システムでは、記事のタイトルや本文から「読者の検索意図に沿った具体的な商品キーワード」を抽出し、楽天APIを叩いて関連商品を検索します。
# 商品検索 (一部抜粋)
def search_items(self, keyword):
params = {
'applicationId': self.app_id,
'affiliateId': self.affiliate_id,
'keyword': keyword,
'sort': '-reviewCount', # レビュー数順でソートして信頼性を担保
'hits': 5
}
response = requests.get('https://app.rakuten.co.jp/services/api/IchibaItem/Search/20220601', params=params)
return response.json()['Items']
さらに、取得した上位5つの候補をもう一度Geminiに渡し、「この記事の文脈で最も読者が買いそうな商品を2つ選べ」と指示し、最終的な商品を選定します。
選ばれた商品は、独自に定義したCSSを用いて高品質なアフィリエイトブロック(商品画像、太字のタイトル、目を引く赤いCTAボタン)としてHTMLに組み込まれます。
3. はてなブログへの完全自動投稿
すべてが組み上がった記事は、はてなブログのAtomPub APIを経由して自動的に投稿(または下書き保存)されます。
def publish(self, title, content_html, is_draft=True):
# AtomPub XMLの構築
xml_data = f"""<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://www.w3.org/2005/Atom" xmlns:app="http://www.w3.org/2007/app">
<title>{title}</title>
<content type="text/html"><![CDATA[{content_html}]]></content>
<app:control><app:draft>{"yes" if is_draft else "no"}</app:draft></app:control>
</entry>"""
# WSSE認証ヘッダの生成(省略)
headers = {'X-WSSE': wsse_header}
response = requests.post(self.endpoint, data=xml_data, headers=headers)
おわりに
このシステムは現在、24時間365日バックグラウンドで動き続けています。
数年後には、LLMがさらに進化し、誰もがノーコードでこれと同等以上のシステムを簡単に作れる時代が来るでしょう。だからこそ、今のこの黎明期に「AIのハルシネーションをどうねじ伏せるか」「いかにプロンプトで人間らしさを偽装するか」をコードレベルでゴリゴリ実装するのは、AIエンジニアとして最高の「遊び」であり、試行錯誤のプロセスそのものが財産になります。
全3回の連載を最後までお読みいただき、本当にありがとうございました!