Agent Skills by ALSEL
汎用EC・マーケティング⭐ リポ 232品質スコア 93/100

google-maps-list-builder

Googleマップから地域ビジネスをカテゴリと地域で抽出し、CSVフォーマットで出力します。メールリスト充実化に活用できます。飲食店、クリニック、ジム、サロン、工事業者など、中小企業向けキャンペーンに最適です。RapidAPI Maps Data APIを使用しています。出力結果は /blitz-list-builder(オーナー連絡先の特定用)または /email-waterfall(既に名前がある場合)に直接連携できます。

description の原文を見る

Scrape Google Maps for local businesses by category and location, output CSV ready for cold email enrichment. Best for SMB campaigns targeting restaurants, clinics, gyms, salons, contractors, etc. Uses RapidAPI Maps Data API. Output feeds directly into /blitz-list-builder (to find owner contacts) or /email-waterfall (if you have names already).

SKILL.md 本文

Google Maps リストビルダー

Google Maps からビジネスリストをスクレイピングするための自己完結型ツール。検索クエリ(例:「ピザレストラン」)と場所(郵便番号、市区町村、または座標)を指定すると、マッチするすべてのビジネスの構造化データが CSV に出力されます。

コールドメールフロー内でのこのツールの位置づけ

Google Maps は企業情報(名前、ドメイン、電話、住所、評価)を提供しますが、人物情報は提供しません。コールドメールを実行するには:

  1. このスキルを実行 → company_domain を含むビジネス CSV を取得
  2. 50件のサンプルで /icp-prompt-builder を実行 — ダウンサーム富化に費用を払う前に不適切な見込み客をフィルタリングするための認定プロンプトを調整
  3. フィルタリングされた CSV で /blitz-list-builder を実行 → 各ビジネスにオーナー/マネージャーを追加
  4. /email-waterfall を実行 → 不足しているメールアドレスを補充
  5. /cold-email-starter-kitsmartlead-add-leads.ts を実行 → Smartlead にアップロード

このスキルは最初のステップにすぎません。

必須ステップ: /icp-prompt-builder で認定

これは必須ステップです。スキップしないでください。

Google Maps は「イリノイ州のピザレストラン」10,000 件を喜んで返しますが、そのほとんどは実際の ICP と一致しない可能性があります(50~200 席のオペレーターのみが必要である場合や、オンライン注文のない場所のみが必要である場合があります)。富化に費用を払う前に、約 50 件の結果をサンプリングして /icp-prompt-builder を実行してください:

  1. AI 認定プロンプトで 10 件の結果を評価
  2. 「これはいけません、チェーン加盟店です」と判定
  3. 調整して、次の 10 件を実行
  4. 2 ラウンド連続で修正がなくなるまで続行
  5. 調整されたプロンプトをスクレイピング残りに適用

必須理由: ダウンストリームのオーナー検索(/blitz-list-builder 経由)とメールウォーターフォールは、連絡先あたり $0.10~$0.30 の費用がかかります。10,000 件のビジネススクレイピングでは、$1K~$3K のコストになります。事前の認定で平均 50~80% のコスト削減になります。

開始前に必要なもの

  1. Node.js 18+npm がインストールされている
  2. RapidAPI アカウント(無料層利用可)と Maps Data API のサブスクリプション:

それだけです。Google Cloud アカウント、OAuth、RapidAPI 以外の請求設定は不要です。

プロジェクトセットアップ

新しいプロジェクトディレクトリを作成して初期化します:

mkdir google-maps-scraper && cd google-maps-scraper
npm init -y
npm install typescript bottleneck
npm install -D @types/node tsx

package.json にスクリプトを追加:

{
  "scripts": {
    "scrape": "tsx src/index.ts"
  }
}

tsconfig.json を作成:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "esModuleInterop": true,
    "strict": true,
    "outDir": "dist",
    "rootDir": "src",
    "skipLibCheck": true
  },
  "include": ["src"]
}

API キーを環境変数として設定:

export RAPIDAPI_KEY=your_key_here

または .env ファイルを作成(.gitignore に .env を追加):

RAPIDAPI_KEY=your_key_here

ファイル構造

google-maps-scraper/
  data/
    us-zip-codes.csv   # 市区町村、州、緯度経度、人口を含む 42,734 件の米国郵便番号
  src/
    index.ts           # CLI エントリーポイント
    client.ts          # レート制限付き RapidAPI Maps Data クライアント
    types.ts           # TypeScript インターフェース
    csv.ts             # CSV エクスポート
    zips.ts            # 郵便番号ローダー(州、市区町村、人口でフィルタリング)

バンドルされた郵便番号データベース

リポジトリには data/us-zip-codes.csv が含まれており、42,734 のエントリを持つ完全な米国郵便番号参照です。列:

zip,primary_city,state,timezone,area_codes,world_region,country,latitude,longitude,irs_estimated_population

これにより、郵便番号を手動でリストアップすることなく、州全体またはメトロエリア全体をスクレイピングできます。src/zips.ts ローダーは、州、市区町村、最小人口でのフィルタリング機能を提供します。

コアファイル

src/types.ts

export interface SearchParams {
  query: string;       // "pizza restaurant", "dentist", "gym"
  lat?: number;        // 中心緯度(「郵便番号のquery」形式を使用する場合はオプション)
  lng?: number;        // 中心経度
  limit?: number;      // 検索ごとの最大結果数(デフォルト 20、最大 20)
  zoom?: number;       // マップズームレベル(デフォルト 13 = 近隣)
  country?: string;    // 国コード(デフォルト "us")
}

export interface Place {
  place_id: string;
  name: string;
  address: string;
  lat: number;
  lng: number;
  rating?: number;
  reviews_count?: number;
  phone?: string;
  website?: string;
  types?: string[];
  category?: string;
}

export interface ScrapeResult {
  query: string;
  location: string;
  total_results: number;
  unique_results: number;
  places: Place[];
  duration_ms: number;
}

src/zips.ts

バンドルされた郵便番号 CSV をロードしフィルタリングします。州、市区町村名、または最小人口でターゲティング可能にします。

import { readFileSync } from 'fs';
import { join, dirname } from 'path';
import { fileURLToPath } from 'url';

export interface ZipEntry {
  zip: string;
  city: string;
  state: string;
  lat: number;
  lng: number;
  population: number;
}

let cache: ZipEntry[] | null = null;

function loadAll(): ZipEntry[] {
  if (cache) return cache;
  const __dirname = dirname(fileURLToPath(import.meta.url));
  const csvPath = join(__dirname, '..', 'data', 'us-zip-codes.csv');
  const raw = readFileSync(csvPath, 'utf-8');
  const lines = raw.trim().split('\n').slice(1); // ヘッダーをスキップ

  cache = lines.map(line => {
    // クォートされたフィールドを処理(area_codes はカンマを含む可能性)
    const parts: string[] = [];
    let current = '';
    let inQuotes = false;
    for (const ch of line) {
      if (ch === '"') { inQuotes = !inQuotes; continue; }
      if (ch === ',' && !inQuotes) { parts.push(current); current = ''; continue; }
      current += ch;
    }
    parts.push(current);

    return {
      zip: parts[0]?.padStart(5, '0') || '',
      city: parts[1] || '',
      state: parts[2] || '',
      lat: parseFloat(parts[7]) || 0,
      lng: parseFloat(parts[8]) || 0,
      population: parseInt(parts[9]) || 0,
    };
  }).filter(z => z.zip.length === 5);

  return cache;
}

/** US 州の郵便番号を取得(2 文字コード、例:"CA", "TX") */
export function getZipsByState(stateCode: string): ZipEntry[] {
  return loadAll().filter(z => z.state.toUpperCase() === stateCode.toUpperCase());
}

/** 市区町村名の郵便番号を取得(大文字小文字を区別しない、部分一致) */
export function getZipsByCity(city: string, state?: string): ZipEntry[] {
  const cityLower = city.toLowerCase();
  return loadAll().filter(z => {
    const cityMatch = z.city.toLowerCase().includes(cityLower);
    const stateMatch = !state || z.state.toUpperCase() === state.toUpperCase();
    return cityMatch && stateMatch;
  });
}

/** 人口がしきい値を超える郵便番号を取得 */
export function getZipsByMinPopulation(minPop: number, state?: string): ZipEntry[] {
  return loadAll().filter(z => {
    const popMatch = z.population >= minPop;
    const stateMatch = !state || z.state.toUpperCase() === state.toUpperCase();
    return popMatch && stateMatch;
  });
}

/** ロードされたすべての郵便番号エントリを取得 */
export function getAllZips(): ZipEntry[] {
  return loadAll();
}

src/client.ts

これはコア API クライアントです。レート制限(2 req/秒)と指数バックオフでの再試行を処理します。

import Bottleneck from 'bottleneck';
import type { SearchParams, Place } from './types.js';

interface RawSearchResponse {
  data?: Array<{
    place_id?: string;
    title?: string;
    name?: string;
    address?: string;
    latitude?: number;
    longitude?: number;
    rating?: number;
    reviews?: number;
    phone?: string;
    website?: string;
    types?: string[];
    type?: string;
    category?: string;
  }>;
  error?: string;
}

interface GeocodingResponse {
  latitude?: number;
  longitude?: number;
  formatted_address?: string;
  error?: string;
}

export class GoogleMapsClient {
  private limiter: Bottleneck;
  private apiKey: string;
  private host = 'maps-data.p.rapidapi.com';
  private maxRetries: number;

  constructor(opts: { apiKey: string; requestsPerSecond?: number; maxRetries?: number }) {
    this.apiKey = opts.apiKey;
    this.maxRetries = opts.maxRetries ?? 3;
    this.limiter = new Bottleneck({
      maxConcurrent: 1,
      minTime: Math.floor(1000 / (opts.requestsPerSecond ?? 2)),
    });
  }

  /** ビジネスを Google Maps で検索 */
  async search(params: SearchParams): Promise<Place[]> {
    const response = await this.request<RawSearchResponse>('searchmaps.php', {
      query: params.query,
      limit: String(params.limit ?? 20),
      country: params.country ?? 'us',
      ...(params.lat != null && { lat: String(params.lat) }),
      ...(params.lng != null && { lng: String(params.lng) }),
      ...(params.zoom != null && { zoom: String(params.zoom) }),
    });

    if (response.error) throw new Error(`Search failed: ${response.error}`);
    return this.transform(response.data || []);
  }

  /** 郵便番号またはアドレスを緯度経度にジオコード */
  async geocode(query: string, country = 'us'): Promise<{ lat: number; lng: number }> {
    const response = await this.request<GeocodingResponse>('geocoding.php', {
      query: `${query}, ${country.toUpperCase()}`,
    });
    if (!response.latitude || !response.longitude) {
      throw new Error(`Could not geocode: ${query}`);
    }
    return { lat: response.latitude, lng: response.longitude };
  }

  private async request<T>(endpoint: string, params: Record<string, string>): Promise<T> {
    return this.limiter.schedule(() => this.requestWithRetry<T>(endpoint, params));
  }

  private async requestWithRetry<T>(
    endpoint: string,
    params: Record<string, string>,
    attempt = 0
  ): Promise<T> {
    const url = new URL(`https://${this.host}/${endpoint}`);
    for (const [k, v] of Object.entries(params)) {
      if (v != null) url.searchParams.set(k, v);
    }

    try {
      const res = await fetch(url.toString(), {
        headers: {
          'X-RapidAPI-Key': this.apiKey,
          'X-RapidAPI-Host': this.host,
        },
      });

      if (!res.ok) {
        const err: any = new Error(`API ${res.status}: ${res.statusText}`);
        err.statusCode = res.status;
        throw err;
      }

      return (await res.json()) as T;
    } catch (err: any) {
      const retryable =
        attempt < this.maxRetries &&
        (err.statusCode === 429 || err.statusCode >= 500 ||
         err.code === 'ECONNRESET' || err.code === 'ETIMEDOUT');

      if (retryable) {
        const delay = 1000 * Math.pow(2, attempt);
        console.log(`  Retry ${attempt + 1}/${this.maxRetries} in ${delay}ms...`);
        await new Promise(r => setTimeout(r, delay));
        return this.requestWithRetry<T>(endpoint, params, attempt + 1);
      }
      throw err;
    }
  }

  private transform(data: NonNullable<RawSearchResponse['data']>): Place[] {
    return data.map(item => ({
      place_id: item.place_id || '',
      name: item.title || item.name || '',
      address: item.address || '',
      lat: item.latitude || 0,
      lng: item.longitude || 0,
      rating: item.rating,
      reviews_count: item.reviews,
      phone: item.phone,
      website: item.website,
      types: item.types || (item.type ? [item.type] : []),
      category: item.category || item.type,
    }));
  }
}

src/csv.ts

import { writeFile, mkdir } from 'fs/promises';
import { dirname } from 'path';
import type { Place } from './types.js';

const HEADERS = [
  'place_id', 'name', 'address', 'phone', 'website',
  'rating', 'reviews_count', 'lat', 'lng', 'category',
];

function escape(val: string | number | undefined | null): string {
  if (val == null) return '';
  const s = String(val);
  return s.includes(',') || s.includes('"') || s.includes('\n')
    ? `"${s.replace(/"/g, '""')}"`
    : s;
}

export async function exportCSV(places: Place[], outputPath: string): Promise<void> {
  await mkdir(dirname(outputPath), { recursive: true });
  const lines = [
    HEADERS.join(','),
    ...places.map(p =>
      HEADERS.map(h => escape(p[h as keyof Place])).join(',')
    ),
  ];
  await writeFile(outputPath, lines.join('\n') + '\n', 'utf-8');
}

src/index.ts

import { GoogleMapsClient } from './client.js';
import { exportCSV } from './csv.js';
import { getZipsByState, getZipsByCity, getZipsByMinPopulation } from './zips.js';
import type { Place } from './types.js';

function dedup(places: Place[]): Place[] {
  const seen = new Set<string>();
  return places.filter(p => {
    if (seen.has(p.place_id)) return false;
    seen.add(p.place_id);
    return true;
  });
}

function getArg(args: string[], prefix: string): string | undefined {
  const match = args.find(a => a.startsWith(prefix));
  return match ? match.split('=').slice(1).join('=') : undefined;
}

async function main() {
  const args = process.argv.slice(2);

  const query = getArg(args, '--query=');
  const zips = getArg(args, '--zips=');
  const cities = getArg(args, '--cities=');
  const state = getArg(args, '--state=');
  const minPop = getArg(args, '--min-pop=');
  const limit = parseInt(getArg(args, '--limit=') || '20', 10);
  const output = getArg(args, '--output=') || './output/results.csv';

  if (!query || (!zips && !cities && !state)) {
    console.log(`
Google Maps Scraper

USAGE:
  npm run scrape -- --query="pizza restaurant" --zips=10014,10013,10012
  npm run scrape -- --query="dentist" --state=TX
  npm run scrape -- --query="dentist" --state=TX --min-pop=10000
  npm run scrape -- --query="gym" --cities="Austin TX,Dallas TX"

OPTIONS:
  --query=QUERY      Business type to search for (required)
  --zips=ZIP,ZIP     Comma-separated zip codes to search
  --cities=CITY,CITY Comma-separated cities to search
  --state=XX         Search all zip codes in a US state (2-letter code)
  --min-pop=N        Filter zips to those with population >= N (use with --state)
  --limit=N          Max results per location (default 20, max 20)
  --output=PATH      Output CSV path (default ./output/results.csv)

ENVIRONMENT:
  RAPIDAPI_KEY       Your RapidAPI key (required)
                     Get one at: https://rapidapi.com/alexanderxbx/api/maps-data

EXAMPLES:
  # All pizza places in California (zips with pop >= 5000)
  npm run scrape -- --query="pizza restaurant" --state=CA --min-pop=5000

  # Dentists in specific NYC zip codes
  npm run scrape -- --query="dentist" --zips=10014,10013,10012

  # Gyms across Texas cities
  npm run scrape -- --query="gym" --cities="Austin TX,Dallas TX,Houston TX"
`);
    process.exit(1);
  }

  const apiKey = process.env.RAPIDAPI_KEY;
  if (!apiKey) {
    console.error('Error: RAPIDAPI_KEY environment variable is required');
    console.error('Get your key at: https://rapidapi.com/alexanderxbx/api/maps-data');
    process.exit(1);
  }

  // すべてのソースからロケーションリストを構築
  const locations: string[] = [];

  if (zips) {
    locations.push(...zips.split(',').map(s => s.trim()));
  }
  if (cities) {
    locations.push(...cities.split(',').map(s => s.trim()));
  }
  if (state) {
    const minPopNum = minPop ? parseInt(minPop, 10) : 0;
    const stateZips = minPopNum > 0
      ? getZipsByMinPopulation(minPopNum, state)
      : getZipsByState(state);
    locations.push(...stateZips.map(z => z.zip));
    console.log(`Loaded ${stateZips.length} zip codes for ${state.toUpperCase()}${minPopNum > 0 ? ` (pop >= ${minPopNum.toLocaleString()})` : ''}`);
  }

  if (locations.length === 0) {
    console.error('No locations to search. Provide --zips, --cities, or --state.');
    process.exit(1);
  }

  console.log(`Scraping "${query}" across ${locations.length} location(s)...\n`);

  const client = new GoogleMapsClient({ apiKey, requestsPerSecond: 2 });
  const allPlaces: Place[] = [];
  const start = Date.now();

  for (let i = 0; i < locations.length; i++) {
    const loc = locations[i];
    console.log(`  [${i + 1}/${locations.length}] Searching: ${query} in ${loc}`);

    try {
      const results = await client.search({
        query: `${query} in ${loc}`,
        limit,
        country: 'us',
      });
      allPlaces.push(...results);
      console.log(`    Found ${results.length} results`);
    } catch (err: any) {
      console.error(`    Error: ${err.message}`);
    }
  }

  // 重複排除
  const unique = dedup(allPlaces);
  console.log(`\nTotal: ${allPlaces.length} results, ${unique.length} unique after dedup`);

  // エクスポート
  await exportCSV(unique, output);
  console.log(`Saved to: ${output}`);

  const duration = ((Date.now() - start) / 1000).toFixed(1);
  console.log(`Done in ${duration}s`);

  // サンプルを出力
  if (unique.length > 0) {
    console.log('\nSample result:');
    const sample = unique[0];
    console.log(`  ${sample.name}`);
    console.log(`  ${sample.address}`);
    if (sample.phone) console.log(`  ${sample.phone}`);
    if (sample.website) console.log(`  ${sample.website}`);
    if (sample.rating) console.log(`  ${sample.rating} stars (${sample.reviews_count} reviews)`);
  }
}

main().catch(err => {
  console.error('Fatal:', err.message);
  process.exit(1);
});

実行方法

ローカル CLI

# 3 つの NYC 郵便番号のピザ場所を検索
npm run scrape -- --query="pizza restaurant" --zips=10014,10013,10012

# テキサス州のすべての歯科医を検索(人口 >= 5000 の郵便番号)
npm run scrape -- --query="dentist" --state=TX --min-pop=5000

# カリフォルニア州のすべてのジム(2,657 個の郵便番号すべて — 時間がかかります)
npm run scrape -- --query="gym" --state=CA

# 特定の市区町村全体で歯科医を検索
npm run scrape -- --query="dentist" --cities="Austin TX,Dallas TX,San Antonio TX"

# カスタム出力ファイル
npm run scrape -- --query="gym" --zips=90210 --output=./data/gyms.csv

プログラマティック使用

import { GoogleMapsClient } from './client.js';

const client = new GoogleMapsClient({
  apiKey: process.env.RAPIDAPI_KEY!,
  requestsPerSecond: 2,
});

// シンプルな検索
const places = await client.search({
  query: 'coffee shop in 94105',
  limit: 20,
});

// 座標を使用した検索
const { lat, lng } = await client.geocode('94105');
const nearby = await client.search({
  query: 'coffee shop',
  lat,
  lng,
  zoom: 14,
  limit: 20,
});

Web アプリとしてデプロイ(オプション)

CLI の代わりに(または加えて)ブラウザ UI が必要な場合は、Express を追加します:

npm install express
npm install -D @types/express

src/server.ts を作成:

import express from 'express';
import { GoogleMapsClient } from './client.js';
import { exportCSV } from './csv.js';
import { tmpdir } from 'os';
import { join } from 'path';
import { readFile, unlink } from 'fs/promises';

const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

const client = new GoogleMapsClient({
  apiKey: process.env.RAPIDAPI_KEY!,
  requestsPerSecond: 2,
});

// シンプルな HTML フォーム
app.get('/', (_req, res) => {
  res.send(`<!DOCTYPE html>
<html><head><title>Google Maps Scraper</title></head>
<body style="font-family:sans-serif;max-width:600px;margin:40px auto;padding:0 20px">
  <h1>Google Maps Scraper</h1>
  <form method="POST" action="/scrape">
    <label>Search query:<br>
      <input name="query" placeholder="pizza restaurant" style="width:100%;padding:8px;margin:4px 0 12px" required>
    </label>
    <label>Locations (comma-separated zips or cities):<br>
      <input name="locations" placeholder="10014, 10013, 10012" style="width:100%;padding:8px;margin:4px 0 12px" required>
    </label>
    <button type="submit" style="padding:10px 24px;cursor:pointer">Scrape</button>
  </form>
</body></html>`);
});

app.post('/scrape', async (req, res) => {
  const { query, locations: locStr } = req.body;
  const locations = locStr.split(',').map((s: string) => s.trim()).filter(Boolean);

  const allPlaces: any[] = [];
  for (const loc of locations) {
    try {
      const results = await client.search({ query: `${query} in ${loc}`, limit: 20 });
      allPlaces.push(...results);
    } catch {}
  }

  // 重複排除
  const seen = new Set<string>();
  const unique = allPlaces.filter(p => { if (seen.has(p.place_id)) return false; seen.add(p.place_id); return true; });

  // CSV をエクスポートしダウンロードとして送信
  const tmpPath = join(tmpdir(), `scrape-${Date.now()}.csv`);
  await exportCSV(unique, tmpPath);
  const csv = await readFile(tmpPath, 'utf-8');
  await unlink(tmpPath);

  res.setHeader('Content-Type', 'text/csv');
  res.setHeader('Content-Disposition', `attachment; filename="maps-scrape-${Date.now()}.csv"`);
  res.send(csv);
});

const port = parseInt(process.env.PORT || '3000', 10);
app.listen(port, () => console.log(`Scraper running at http://localhost:${port}`));

package.json にスクリプトを追加:

{
  "scripts": {
    "scrape": "tsx src/index.ts",
    "serve": "tsx src/server.ts"
  }
}

ローカルで実行: npm run serve して http://localhost:3000 を開く

Railway へのデプロイ

  1. プロジェクトを GitHub リポジトリにプッシュ
  2. https://railway.com にアクセス、新しいプロジェクトを作成、リポジトリを接続
  3. Railway のダッシュボードで環境変数 RAPIDAPI_KEY を設定
  4. スタートコマンドを npx tsx src/server.ts に設定
  5. Railway が process.env.PORT からポート自動検出し、パブリック URL を提供

パスワード保護を追加するには、POST ハンドラで PASSWORD 環境変数をチェックするか、Railway のビルトイン認証機能を使用します。

他のプラットフォームへのデプロイ

これは標準的な Node.js アプリです。どこでも実行できます:

  • Render: GitHub リ

ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ

詳細情報

作者
growthenginenowoslawski
リポジトリ
growthenginenowoslawski/coldoutboundskills
ライセンス
MIT
最終更新
2026/5/4

Source: https://github.com/growthenginenowoslawski/coldoutboundskills / ライセンス: MIT

関連スキル

Anthropic ClaudeEC・マーケティング⭐ リポ 6,400

seo-maps

ローカルSEO向けのマップインテリジェンス機能です。ジオグリッドのランク追跡、APIを通じたGBPプロフィール監査、Google・Tripadvisor・Trustpilotなど複数プラットフォームのレビュー分析、Google・Bing・Apple・OSM間のNAP(名前・住所・電話番号)検証、競合他社の半径マッピング、APIデータからのLocalBusinessスキーマ生成が可能です。3段階の機能レベルで対応でき、無料版(Overpass + Geoapify)、DataForSEO(フル機能)、DataForSEO + Google(最大カバレッジ)から選択できます。「maps」「geo-grid」「rank tracking」「GBP audit」「review velocity」「competitor radius」「maps analysis」「local rank tracking」「Share of Local Voice」「SoLV」などのキーワードで利用できます。

by AgriciDaniel
Anthropic ClaudeEC・マーケティング⭐ リポ 6,400

seo-content-brief

セクションごとの文字数、競合スコアリング、キーワード密度ガイダンス、ページタイプテンプレートを含む競争力のあるSEOコンテンツブリーフを生成します。新規ページのブリーフと既存ページの改善ブリーフの両方に対応しています。ユーザーが「コンテンツブリーフ」「ブリーフを作成」「コンテンツアウトライン」「ブログブリーフ」「サービスページブリーフ」「ブリーフ〜」「ライティングブリーフ」「コンテンツプラン」「アウトライン〜」などと言った場合に使用します。

by AgriciDaniel
ALSEL独自Anthropic ClaudeEC・マーケティング

rakuten-seo

楽天市場の商品名・キャッチコピーをSEO最適化するスキル。「楽天SEO」「商品名最適化」「楽天の商品名」「キャッチコピー」「楽天のタイトル」「商品名を直して」「楽天検索対策」など、楽天市場の商品名やキャッチコピーの作成・改善・チェックに関するリクエストで必ずこのスキルを使う。既存の商品名の改善も、ゼロからの作成も対応。あらゆるジャンル(食品・ファッション・化粧品・家電・サプリ・インテリア・ベビー・ペット・業務用など)に対応。 【ALSEL独自スキル】株式会社ALSEL が、19年・5,000社超の EC 支援で得たノウハウをもとに開発したオリジナルスキルです。

by 株式会社ALSEL
ALSEL独自Anthropic ClaudeEC・マーケティング

amazon-seo-jp

Amazon.co.jp商品ページのSEO分析・最適化・自動採点スキル v2.0。 COSMO/Rufus/A10アルゴリズムに基づく採点。セラーセントラル出品レポート(.xlsm)を入力すると、 商品タイトル・箇条書き・検索キーワード・商品説明文を100点満点で採点し、 4項目すべての改善案を日本語で出力する。 トリガー: 「Amazon SEO」「商品ページ採点」「Amazon最適化」 「リスティング改善」「Amazon商品名」「箇条書き改善」 「COSMO対応」「Rufus最適化」「Amazon タイトル」 【ALSEL独自スキル】株式会社ALSEL が、19年・5,000社超の EC 支援で得たノウハウをもとに開発したオリジナルスキルです。

by 株式会社ALSEL
ALSEL独自Anthropic ClaudeEC・マーケティング

rakuten-bulk-control-csv

楽天RMSの一括登録/一括除外/一括更新用CSV(コントロールカラム,商品管理番号 の2列フォーマット)を作成するスキル。商品DL CSV・商品管理画面のコピペ・Excel・PDFなどから商品管理番号を抽出し、Shift-JIS+LF改行で出力する。「一括除外リスト作って」「楽天の除外CSV」「コントロールカラムnで」「2800円以下の商品をdで」「在庫0の商品を一括削除」「商品管理番号抜いてshift-jsで」「このフォーマットで」など、楽天RMSの商品一括処理用CSVを作るタスクで必ずこのスキルを使う。コントロールカラム値(n=新規/d=削除/u=更新)と抽出条件(全件・価格・在庫・販売状態など)をユーザー指示に応じて柔軟に切り替える。 【ALSEL独自スキル】株式会社ALSEL が、19年・5,000社超の EC 支援で得たノウハウをもとに開発したオリジナルスキルです。

by 株式会社ALSEL
ALSEL独自Anthropic ClaudeEC・マーケティング

amazon-a-plus-content-brief

Amazon A+コンテンツの構成・モジュール選定・画像指示・比較表・FAQを設計するスキル。「A+コンテンツ作って」「Aプラス構成」「ブランドストーリー」「比較表つきA+」「A+モジュール選定」「Amazonのページに画像入れたい」「A+のヘッダー画像」「A+コンテンツマネージャー」など、Amazon A+コンテンツの企画・設計・改善のリクエストで必ずこのスキルを使う。ベーシック17モジュール/Premium追加機能/画像サイズ規定/文字数目安/審査リジェクト要因を踏まえて、デザイナーに渡せるブリーフ形式で出力。あらゆるジャンル(家電・コスメ・食品・アパレル・日用品・ベビー・ペット等)に対応。※ブランドストア(マルチページ)の設計は別スキル `amazon-brand-store-planner`、タイトル・bullet改善は `amazon-title-bullet-rewriter-jp`、メイン画像のチェックは `amazon-main-image-checker`。 【ALSEL独自スキル】株式会社ALSEL が、19年・5,000社超の EC 支援で得たノウハウをもとに開発したオリジナルスキルです。

by 株式会社ALSEL
本サイトは GitHub 上で公開されているオープンソースの SKILL.md ファイルをクロール・インデックス化したものです。 各スキルの著作権は原作者に帰属します。掲載に問題がある場合は info@alsel.co.jp または /takedown フォームよりご連絡ください。
原作者: growthenginenowoslawski · growthenginenowoslawski/coldoutboundskills · ライセンス: MIT