見出し画像

LINEスタンプのタグ編集効率化ブックマークレット番外編【まとめて登録式】

こんにちは、毎度rorosukeです。

この私、LINEスタンプ(特にLINEアニメスタンプ)のタグ編集が面倒であることに気づき、これを自動化するための方策を考えてきました。

その初回が、次の記事です。

ここでは、私が最初に考えた方法を紹介しています。具体的には、

  • AIに画像を見せてタグ候補を選んでもらう

  • 選んでもらったタグ候補を、ブックマークレットというプログラムで一発登録する

という方法です(詳しくは記事をお読みください)。

その後、APIという仕組みを使って全自動化を目指してみたのですが、APIは基本的に有料なので、少しハードルが高いのです。

「まあ、他にやりようがないから仕方ないよねー」

と思っていたのですが、どうやらそうでもなかったようです。



複数画像のタグリストを一気に作る

なんと、AIと、私の作ったブックマークレットをうまく組み合わせて、効率的にタグ登録する方法をChameさんが考案してくれました。

その記事がこちらです。

考え方はシンプルです。

  • 複数画像をまとめてAIに渡し、一気にタグリストを作ってもらう

  • それをブックマークレットで登録していく

この「複数画像をまとめてAIに渡す」という、APIを使わずに、さらに効率化できる方法があったとは目からうろこです。

効率化っていうのは、こういう「小さな気付き」が大事なんですよね。これを積み重ねていくことで、大きな改善につながるのです。

マジ、気づかせてくれてありがとうございます!
とお礼をいいたい気分です。



まとめて登録式ブックマークレットを試作

しかし、そうなるとですね。逆に、私が作ったブックマークレットのオーバーヘッドが気になります。LINEスタンプを1つずつ順番にタグ登録しなければならず、あまり効率がいいとは言えません。

そこで急遽、複数のタグリストを入力し、一気にタグ登録するための「まとめて登録式」を試作してみました。使い方は次の通りです。

1.タグリストを用意します

タグリストの形式は次のようにしてください。

01,おめでとう,お祝い,拍手,合格,桜,春,誕生日,イヌ,やった
02,ぺこり,ありがとう,助かる,嬉しい,花見,感謝,イヌ,春,桜
40,おめでとう,お祝い,拍手,合格,桜,春,誕生日,イヌ,やった
  • 第1カラムにスタンプ番号を2桁で入力します

  • 第2カラム以降に最大9つのタグを並べます

  • すべてカンマ区切り(CSV形式)です

※スタンプ番号は連続している必要はありません(自動でソートされます)。

2.タグ編集画面を表示します

LINEクリエイターズマーケットの「タグの編集」画面を表示します。

タグ編集画面を表示する

3.ブックマークレットを起動します

  1. まとめて登録式ブックマークレット(後に掲載)を起動します。

  2. 次の画面が表示されます。

  3. 中央のテキストエリアにタグリストをペーストし、「一括登録開始」ボタンを押します。

  4. これでタグ登録が開始されます。

  5. 終了したら「閉じる」ボタンを押してください。

タグリストを貼り付けて下のボタンを押す。
サンプルでは3行だけだが、40行あってもOK。

※登録がうまくいかない場合は、「ページ切替待ち時間」の秒数を大きくしてみてください。ブラウザのページ切り替えが遅い環境では、改善される可能性があります。

4.タグ登録を確認する

タグ登録が正しく行われたかどうかを確認してください。

登録されているか確認する。

登録されていれば成功です。タグ登録が効率化されていれば幸いです。

※試作版なので、不具合等があった場合はコメント欄にてご報告願います。


まとめて登録式ブックマークレットのコードはこちらです

お試しください。
コードは1行コードになっていて、めちゃくちゃ長いので、[CTRL]+[A]で全選択するようにしてください。

ブックマークレットコード

javascript:(function(){ var WAIT=function(ms){return new Promise(function(r){setTimeout(r,ms);});}; var $=function(id){return document.getElementById(id);}; var overlay=document.createElement('div'); overlay.style.cssText='position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.55);z-index:10000;display:flex;justify-content:center;align-items:center;font-family:sans-serif;'; var box=document.createElement('div'); box.id='bk-box'; box.style.cssText='background:#fff;border-radius:12px;padding:28px;max-width:640px;width:92%;box-shadow:0 12px 40px rgba(0,0,0,0.35);max-height:92vh;overflow-y:auto;'; box.innerHTML='' +'<h2 style="margin:0 0 8px;color:#333;font-size:17px;">&#x1F4CB; \u4E00\u62EC\u30BF\u30B0\u767B\u9332</h2>' +'<p style="color:#555;font-size:12px;margin:0 0 4px;">\u5F62\u5F0F\uFF081\u884C\uFF1D1\u30B9\u30BF\u30F3\u30D7\u3001\u30BF\u30B0\u306F\u6700\u59279\u500B\uFF09\uFF1A</p>' +'<p style="font-family:monospace;background:#f3f3f3;padding:6px 10px;border-radius:4px;font-size:12px;margin:0 0 10px;">01,\u30BF\u30B0A,\u30BF\u30B0B<br>02,\u30BF\u30B0X,\u30BF\u30B0Y</p>' +'<p style="color:#e53935;font-size:12px;margin:0 0 12px;">\u203B \u30B9\u30BF\u30F3\u30D7\u30BF\u30B0\u7DE8\u96C6\u30DA\u30FC\u30B8\u3067\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044</p>' +'<textarea id="bk-input" style="width:100%;height:200px;border:1px solid #ccc;border-radius:6px;padding:10px;font-size:12px;font-family:monospace;box-sizing:border-box;resize:vertical;" placeholder="01,\u3079\u3053\u308A,\u3042\u308A\u304C\u3068\u3046,\u52A9\u304B\u308B&#10;02,\u304A\u3081\u3067\u3068\u3046,\u304A\u795D\u3044,\u62CD\u624B"></textarea>' +'<div style="display:flex;align-items:center;gap:10px;margin:12px 0 6px;">' +'<label style="font-size:13px;color:#333;white-space:nowrap;">&#x23F1; \u30DA\u30FC\u30B8\u5207\u66FF\u5F85\u3061\u6642\u9593\uFF1A</label>' +'<input id="bk-wait" type="number" min="0.5" max="5" step="0.5" value="0.5" style="width:80px;padding:6px;border:1px solid #ccc;border-radius:5px;font-size:13px;text-align:center;">' +'<span style="font-size:13px;color:#555;">\u79D2</span>' +'</div>' +'<div style="font-size:11px;color:#888;margin-bottom:12px;">\u8868\u793A\u304C\u9045\u3044\u74B0\u5883\u30671\uFF5E2\u79D2\u306B\u5897\u3084\u3057\u3066\u304F\u3060\u3055\u3044</div>' +'<div id="bk-progress" style="margin:10px 0 4px;font-size:13px;color:#555;min-height:20px;"></div>' +'<div id="bk-bar-wrap" style="display:none;background:#eee;border-radius:4px;height:8px;margin-bottom:10px;">' +'<div id="bk-bar" style="background:#4caf50;height:8px;border-radius:4px;width:0%;transition:width 0.3s;"></div>' +'</div>' +'<div style="display:flex;gap:10px;">' +'<button id="bk-start" style="flex:1;background:#4caf50;color:#fff;border:none;padding:13px;border-radius:6px;cursor:pointer;font-weight:bold;font-size:14px;">&#x25B6; \u4E00\u62EC\u767B\u9332\u958B\u59CB</button>' +'<button id="bk-close" style="background:#9e9e9e;color:#fff;border:none;padding:13px 20px;border-radius:6px;cursor:pointer;font-size:13px;">&#x2715; \u9589\u3058\u308B</button>' +'</div>' +'<div id="bk-errors" style="display:none;margin-top:14px;padding:10px;background:#fff3f3;border:1px solid #f44336;border-radius:6px;font-size:12px;color:#c62828;"></div>'; overlay.appendChild(box); document.body.appendChild(overlay); var setStatus=function(msg,color){$('bk-progress').style.color=color||'#555';$('bk-progress').textContent=msg;}; var setBar=function(cur,total){$('bk-bar-wrap').style.display='block';$('bk-bar').style.width=(cur/total*100)+'%';}; $('bk-close').onclick=function(){if(document.body.contains(overlay))document.body.removeChild(overlay);}; overlay.onclick=function(e){if(e.target===overlay&&document.body.contains(overlay))document.body.removeChild(overlay);}; box.onclick=function(e){e.stopPropagation();}; var getCurrentNum=function(){ var span=document.querySelector('button.btn-dropdown .btn-dropdown-text'); if(!span)return null; var n=parseInt(span.textContent.trim(),10); return isNaN(n)?null:n; }; var pressBtn=function(selector,beforeNum,waitMs){ return new Promise(function(resolve){ (async function(){ var btn=document.querySelector(selector); if(!btn||btn.disabled){return resolve(null);} btn.click(); await WAIT(waitMs); for(var t=0;t<12;t++){ var cur=getCurrentNum(); if(cur!==null&&cur!==beforeNum){return resolve(cur);} await WAIT(250); } resolve(null); })(); }); }; var navigateTo=function(num,waitMs){ return new Promise(function(resolve){ (async function(){ var cur=getCurrentNum(); if(cur===null){return resolve({status:'error'});} if(cur===num){return resolve({status:'ok'});} var MAX_STEPS=40; for(var step=0;step<MAX_STEPS;step++){ cur=getCurrentNum(); if(cur===null){return resolve({status:'error'});} if(cur===num){return resolve({status:'ok'});} var btnSel=num>cur?'button.btn-next-image':'button.btn-previous-image'; var newNum=await pressBtn(btnSel,cur,waitMs); if(newNum===null){return resolve({status:'error'});} if(newNum===num){return resolve({status:'ok'});} if(num>cur&&newNum>num){return resolve({status:'skip',current:newNum});} if(num<cur&&newNum<num){return resolve({status:'skip',current:newNum});} } resolve({status:'error'}); })(); }); }; var applyTags=function(tags){ return new Promise(function(resolve){ (async function(){ var allLabels=document.querySelectorAll('label.cm-product-image-tag'); if(allLabels.length===0)return resolve({ok:false,msg:'\u30BF\u30B0\u30A8\u30EA\u30A2\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093'}); for(var i=0;i<allLabels.length;i++){ var cb=allLabels[i].querySelector('input[type="checkbox"]'); if(cb&&cb.checked){allLabels[i].click();await WAIT(40);} } await WAIT(250); var spans=document.querySelectorAll('span.cm-product-image-tag-name-text[data-test="tag-name"]'); var available={}; for(var j=0;j<spans.length;j++)available[spans[j].textContent.trim()]=true; var valid=tags.filter(function(t){return available[t];}).slice(0,9); var invalid=tags.filter(function(t){return!available[t];}); var count=0; for(var k=0;k<valid.length;k++){ for(var m=0;m<spans.length;m++){ if(spans[m].textContent.trim()===valid[k]){ var lbl=spans[m].closest('label.cm-product-image-tag'); if(lbl){ var cbk=lbl.querySelector('input[type="checkbox"]'); if(cbk&&!cbk.checked){lbl.click();count++;await WAIT(45);break;} } } } } var saveSels=['button[data-test="save-btn"]','button[data-test="apply-btn"]','.cm-save-btn button']; for(var s=0;s<saveSels.length;s++){ var btn=document.querySelector(saveSels[s]); if(btn&&!btn.disabled){btn.click();await WAIT(600);break;} } resolve({ok:true,count:count,invalid:invalid}); })(); }); }; $('bk-start').onclick=function(){ (async function(){ var raw=$('bk-input').value.trim(); if(!raw){alert('\u30C7\u30FC\u30BF\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044');return;} var waitSec=parseFloat($('bk-wait').value)||0.5; var waitMs=Math.round(waitSec*1000); var data=[]; var lines=raw.split('\n'); for(var i=0;i<lines.length;i++){ var parts=lines[i].trim().split(',').map(function(p){return p.trim();}).filter(function(p){return p;}); if(parts.length<2)continue; var num=parseInt(parts[0],10); if(isNaN(num)||num<1||num>40)continue; data.push({num:num,tags:parts.slice(1).slice(0,9)}); } if(data.length===0){alert('\u6709\u52B9\u306A\u884C\u304C\u3042\u308A\u307E\u305B\u3093\u3002\n\u5F62\u5F0F: 01,\u30BF\u30B01,\u30BF\u30B02,...');return;} data.sort(function(a,b){return a.num-b.num;}); if(getCurrentNum()===null){ alert('\u30DA\u30FC\u30B8\u756A\u53F7\u304C\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093\u3002\n\u30B9\u30BF\u30F3\u30D7\u30BF\u30B0\u7DE8\u96C6\u30DA\u30FC\u30B8\u3067\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002'); return; } $('bk-start').disabled=true; $('bk-close').disabled=true; $('bk-input').disabled=true; $('bk-wait').disabled=true; var errors=[]; var summary=[]; for(var i=0;i<data.length;i++){ var num=data[i].num; var tags=data[i].tags; var numStr=String(num).padStart(2,'0'); setStatus('\u51E6\u7406\u4E2D '+(i+1)+' / '+data.length+'\uFF1A'+numStr+'\u756A\u306B\u79FB\u52D5\u4E2D... (\u73FE\u5728: '+getCurrentNum()+'\u756A)'); setBar(i,data.length); var nav=await navigateTo(num,waitMs); if(nav.status==='error'){errors.push(numStr+'\u756A: \u30DA\u30FC\u30B8\u9077\u79FB\u306B\u5931\u6557\u3057\u307E\u3057\u305F (\u73FE\u5728: '+getCurrentNum()+'\u756A)');continue;} if(nav.status==='skip'){summary.push(numStr+'\u756A: \u30B9\u30AD\u30C3\u30D7\uFF08\u30DA\u30FC\u30B8\u304C\u5B58\u5728\u3057\u307E\u305B\u3093\uFF09');continue;} var ready=false; for(var t=0;t<12;t++){ if(document.querySelectorAll('label.cm-product-image-tag').length>0){ready=true;break;} await WAIT(250); } if(!ready){errors.push(numStr+'\u756A: \u30BF\u30B0\u30A8\u30EA\u30A2\u304C\u8868\u793A\u3055\u308C\u307E\u305B\u3093\u3067\u3057\u305F\uFF08\u5F85\u3061\u6642\u9593\u3092\u5897\u3084\u3057\u3066\u307F\u3066\u304F\u3060\u3055\u3044\uFF09');continue;} setStatus('\u51E6\u7406\u4E2D '+(i+1)+' / '+data.length+'\uFF1A'+numStr+'\u756A\u306B\u30BF\u30B0\u767B\u9332\u4E2D...'); var result=await applyTags(tags); if(!result.ok){errors.push(numStr+'\u756A: '+result.msg);continue;} var note=result.invalid.length>0?' / \u672A\u5BFE\u5FDC\u30BF\u30B0: '+result.invalid.join(','):''; summary.push(numStr+'\u756A: '+result.count+'\u500B\u767B\u9332'+note); setStatus('\u2713 '+numStr+'\u756A: '+result.count+'\u500B\u767B\u9332'+note,'#388e3c'); await WAIT(300); } setBar(data.length,data.length); setStatus('\u2705 \u5B8C\u4E86\uFF01 '+data.length+'\u4EF6\u51E6\u7406\u3057\u307E\u3057\u305F\u3002','#1b5e20'); $('bk-close').disabled=false; $('bk-close').textContent='\u9589\u3058\u308B'; $('bk-wait').disabled=false; if(errors.length>0){ var errDiv=$('bk-errors'); errDiv.style.display='block'; errDiv.innerHTML='<strong>\u26A0\uFE0F \u30A8\u30E9\u30FC\u4E00\u89A7</strong><br>'+errors.join('<br>'); } console.log('[\u4E00\u62EC\u30BF\u30B0\u767B\u9332] \u7D50\u679C:\n'+summary.join('\n')); })(); }; })();

ダウンロード用

ブックマークレットとして登録する方法は、次の記事の「ブックマークレットでプロンプト準備」をご覧ください。



まとめ:コスパ最高の方法かも

今回のポイントは、

「APIを使わなくても、工夫次第でかなり効率化できる」

という点です。

Chameさんのアイデアを用いれば、作業回数とコストを大幅に削減できるのではないかと思います。

自動化というと“完全自動”を目指しがちですが、

半自動 × 人間の判断

というバランスも、十分に実用的だと感じています。

LINEスタンプ制作をされている方の参考になればうれしいです。

以上!



✨ iPhoneでも使いたい方へ

もしよろしければ、ですが。

「スマホでもこれ使えたら便利なのに…」 と思った方もいるのではないでしょうか。

実は、Safari向けに対応版を作っています。 気になる方はこちらもどうぞ。

いいなと思ったら応援しよう!

ROROSUKE LABO 記事なり、プログラムなりが役に立ったと思った方は、 チップの応援よろしくお願いいたします。 次の開発もがんばろうかな、という気になりますのだ (笑)