名刺をLINEに投稿すると、自動で個人情報を抽出+スプレッドシートに格納する方法

当ブログがオススメする

業務自動化サービスランキング

なお、業務効率化や工数削減を目指しているものの、どの業務から自動化すべきか、どのツールや手段が自社に合っているのかがあいまいな方は、「業務自動化プラン診断」をお試しください。

かかる時間は1分ほど。4つの質問に答えるだけで、あなたに最適な自動化対象業務や、推奨される自動化手段を診断してもらえます。

効率よく自社に適した業務効率化を知りたい方は、ぜひ一度お試しください。

\ 4つの質問に答えるだけ /

目次

名刺を写真に撮ってLINEに送るだけで、個人情報抽出+スプレッドシートに記録できる

名刺管理の手間、感じていませんか?

「紙の名刺を後で整理しようとつい放置してしまう」「情報を一枚ずつ入力するのが大変」そんな声に応えるのが、LINEに名刺写真を送るだけで、自動で情報を抽出しGoogleスプレッドシートにまとめるこの仕組みです。

面倒な名刺整理を、dify(AI OCR)・Google Apps Script・LINEを組み合わせて、“誰でも・簡単・自動”で解決できます。

ITが得意じゃない方も、この記事の通り進めれば、驚くほど簡単に「名刺の自動データ化」を始められます。

こんなシーンでの活用に適しています

1. 日々大量の名刺が集まる営業職・経営者の方へ

 → 帰社後や商談後、そのままLINEでパシャ!手元のスマホだけで名刺情報を一元管理できます。

2. 名刺情報の社内共有・データ化が課題の企業

 → スプレッドシートで自動集約されるので、全社で最新の名刺リストを共有しやすくなります。

3. クラウド名刺管理サービスのコストや運用負担を減らしたい

 → サブスク不要。自社運用で「紙→デジタル化」だけサクッと済ませたい場合に最適。

dify×LINE×GAS

簡単な仕組み・フローの説明

①LINEで名刺画像を送信

②Google Apps Script(GAS)が自動で画像をDrive保存&OCR依頼

③dify(AI)が名刺情報を自動抽出→スプレッドシートに転記

④転記完了後、「名刺が追加されました」とLINEに自動返信

メリット
スマホで撮影→LINE送信だけ。アプリ追加インストール不要
名刺入力作業がほぼゼロに
AIによる自動OCRなので、英語名刺や手書きでも高い認識率
Googleスプレッドシート活用で、社内共有・他ツール連携が簡単
自分だけのカスタム名刺データベースを“無料”で運用できる
デメリットAI OCR(dify)の精度は画像や名刺レイアウトによってバラつきがある
セットアップに最初は少し手間がかかる(LINE公式アカウント・dify APIの用意など)
GAS・APIに関するエラー時は自力で原因調査が必要
完全なノーコードではなく、コピペでの簡単なプログラミング作業あり
難易度・面倒さIT初心者でも、この記事の通り“画面のボタン”を押して進めばOK
Googleアカウント、LINE Developers、difyのアカウント登録が必要(どれも無料)
プログラム修正なしで「コピペ+設定」で動く難易度
特徴LINEだけで完結、手軽に名刺データ化
Googleの標準サービスを利用するので「自分や社内でカスタム活用しやすい」
サービス連携型なので、拡張やカスタマイズも自由自在
価格
Googleスプレッドシート/GAS/Drive:無料(GoogleアカウントがあればOK)
dify:無料枠あり(OCR数により有料プランも有)
LINE公式アカウント:無料枠で十分運用可能(大量利用時は有料になる場合も)

用意するもの

①Googleアカウント(GmailアドレスでOK)

②Googleスプレッドシート(名刺データ保存用)

③Google Drive(名刺画像用フォルダ)

④difyアカウント(AI OCR用エージェント・APIキー取得用)

⑤LINE公式アカウント(Messaging API)

※LINE Developers登録し、Webhook連携できるようにしておく

⑥(オプション)自動化サービス「ジドウカ」

→ 構築・運用代行も相談可能

設定手順 ※Google Chromeでの操作を推奨します。

🔹Step 1:Googleスプレッドシートを準備する

1.Googleスプレッドシートにアクセス

2.左上「+」で「空白のスプレッドシート」を新規作成

3.名前を「名刺管理」など分かりやすく変更(左上のタイトルをクリックして入力)

4.1行目に以下のような見出しを入力

日付, 会社名, 役職, 名前, 電話番号, メール, 住所, URL, 画像URL

5.シートを1つ追加し、シート名を「log」とする

6.スプレッドシートのURLをコピーしてメモ

🔹Step 2:Gemini AIの利用パス(APIキー)の取得

ChatGPTでもOKですが、Geminiですと、クレジットカード登録も不要で無料で使い続けられます。そのため、Geminiを今回も選択しました。

1.Google AI Studioにアクセス(検索で「Google AI Studio」と入力)

2.Googleアカウントでログイン。もしくは、Googleログイン状態で上記ページにアクセス。

※初回はポップアップが出現すると思います。チェックして、同意するボタンクリックで、次に進みます。

3.右上の「Get API key」をクリック

4.右上の「+APIキーを作成」をクリック

5.APIキーの確認

キャプチャ画像では、黒く塗りつぶされていますが、ここに表示された英数字をコピーしてメモ帳に保存 ※この番号は他人に教えないでください

これで、Gemini APIキーの取得完了です!

🔹Step 3:DifyでエージェントとAPIキーを作成

1.  Difyにログイン

https://cloud.dify.ai/apps

2. 左上のメニューから「最初から作成」をクリック

3. 「ワークフロー」をクリック

4. わかりやすい名前(例:「名刺OCR」)を入力

5.「開始」ノードを選択し、メニュー右上の+ボタンをクリック

6. 「入力フィールドを編集」内の各項目を設定

・フィールドタイプ:単一ファイル
・変数名:receipt
・ラベル名:receipt
・サポートされたファイルタイプ:画像
・アップロードされたファイルの対応:両方
→最後に「必須」にチェックを入れて保存。

7.「開始」の右側+ボタンを押して、「ブロック」から「LLM」ノードを追加

8. 「LLM」ノード内の各項目を編集

・AIモデル:Geminiのお好みのモデル
・SYSTEM:以下のプロンプト

画像から

{

"会社名": "",

"役職": "",

"名前": "",

"電話番号": "",

"メールアドレス": "",

"住所": "",

"URL": ""

}

これらを抽出して、JSON形式で出力してください。

JSON形式の出力結果以外のテキストは不要です。

・User:{x}をクリックして「開始」で設定した変数である{x}receiptを選択

9. 「終了」ノードを追加して出力変数を編集

変数名を入力:text
変数値を設定:先ほど設定したLLMノード内のtextを選択

10. 右上の「公開」ボタンを押して公開

11. 左側メニューから「APIアクセス」を開き、右上「APIキー」をクリック

11. 発行されたAPIキーを保存

ここで保存したAPIキーはこのあと使用するので、手元に大切に保存しておきましょう!

🔹Step 4:LINE Developersで公式アカウント・Messaging APIを作成

1. LINE Developersへアクセス

https://developers.line.biz/ja/

2. 右上「ログイン」

3. 「プロバイダーを作成」→「任意の名前(例:名刺OCR)」

4. 「チャネルを作成」→「Messaging API」を選ぶ

5. 「LINE公式アカウントを作成」から作成する

5. 必須項目を入力(チャネル名、説明、メールアドレスなど)

※個人利用の場合「会社名」は自分の名前でOK

6. 作成できたら「チャネル基本設定」画面に入る

7. 「チャネルシークレット」と「チャネルアクセストークン(長期)」を必ずコピーして保存

8. 「Messaging API設定」画面で「webhook URL」をあとで登録する(GASのデプロイ後に設定)

黒塗りの箇所は他の人に教えないように、自分だけが管理できる環境で大切に保管しましょう。

🔹Step 5:Google Apps Scriptでシステムを作る

1.スクリプトの新規作成

1. スプレッドシートの画面から「拡張機能」→「Apps Script」をクリック

2. 「無題のプロジェクト」を「名刺自動登録」などに変更

3. エディタ左側メニュー「プロジェクトの設定」から「スクリプトプロパティ」に先ほど保存した「Dify APIキー」「LINEアクセストークン」「スプレッドシートID」を保存

4. 既存の「コード. gs」ファイルに下記のコードをすべてコピペ

2.コードを入力

※コード内「★」マークを、自分の値に書き換えてください

// ========================================
// 設定定数(保守性向上のため、ここで一元管理)
// ========================================

// デバッグ設定
const DEBUG_SHEET_ID = '★スプレッドシートID★';
const DEBUG_SHEET_NAME = 'log';

// API設定
const LINE_ACCESS_TOKEN = PropertiesService.getScriptProperties().getProperty('LINE_ACCESS_TOKEN');
const DIFY_API_KEY = PropertiesService.getScriptProperties().getProperty('DIFY_API_KEY');

// スプレッドシート設定
const RESULT_SHEET_ID = PropertiesService.getScriptProperties().getProperty('RESULT_SHEET_ID');
const TARGET_SHEET_NAME = 'シート1';
const RESULT_SHEET_URL = `https://docs.google.com/spreadsheets/d/${RESULT_SHEET_ID}`;

// Dify設定
const DIFY_UPLOAD_URL = 'https://api.dify.ai/v1/files/upload';
const DIFY_WORKFLOW_URL = 'https://api.dify.ai/v1/workflows/run';
const DIFY_USER_ID = 'line-user';
const DIFY_INPUT_KEY = 'receipt'; // Difyワークフローで定義された変数名

// LINE API設定
const LINE_REPLY_URL = 'https://api.line.me/v2/bot/message/reply';
const LINE_CONTENT_URL = 'https://api-data.line.me/v2/bot/message';

// ファイル設定
const UPLOAD_FILE_NAME = 'image.jpg';
const UPLOAD_MIME_TYPE = 'image/jpeg';

// スプレッドシート列設定(ヘッダー)
const SHEET_HEADERS = ['登録日時', '会社名', '役職', '名前', '電話番号', 'メールアドレス', '住所', 'URL'];

// データマッピング設定(JSONキーの候補)
const KEY_MAPPING = {
  company: ['会社名', 'company', '企業名'],
  position: ['役職', 'position', 'title', '職位'],
  name: ['名前', 'name', '氏名'],
  phone: ['電話番号', 'phone', 'tel', '電話'],
  email: ['メールアドレス', 'email', 'mail', 'e-mail'],
  address: ['住所', 'address', '所在地'],
  url: ['URL', 'url', 'website', 'web', 'ホームページ']
};

// メッセージ設定
const MESSAGES = {
  success: '✅ 画像を解析してスプレッドシートに記録しました!',
  parseError: '❌ 画像の解析に失敗しました。もう一度お試しください。',
  requestImage: '📷 名刺やレシートなどの画像を送信してください。',
  checkSheet: '\n📊 確認はこちら:'
};

// ========================================
// 初期化
// ========================================

const debugsheet = SpreadsheetApp.openById(DEBUG_SHEET_ID).getSheetByName(DEBUG_SHEET_NAME);

// LINEからのPOSTリクエストを処理
function doPost(e) {
  Logger.log('--- doPost start ---');
  try {
    Logger.log('Received event: %s', JSON.stringify(e));
    
    if (!e.postData || !e.postData.contents) {
      Logger.log('postDataが存在しないため、処理を終了します。');
      return ContentService.createTextOutput(JSON.stringify({ content: 'no postData' })).setMimeType(ContentService.MimeType.JSON);
    }

    const json = JSON.parse(e.postData.contents);
    Logger.log('Received JSON: %s', JSON.stringify(json));

    const event = json.events[0];
    if (!event) {
      Logger.log('イベントが存在しないため、処理を終了します。');
      return ContentService.createTextOutput(JSON.stringify({ content: 'no event' })).setMimeType(ContentService.MimeType.JSON);
    }
    const replyToken = event.replyToken;

    if (event.message && event.message.type === 'image') {
      //画像処理
      const messageId = event.message.id;
      Logger.log('画像メッセージ受信: messageId=%s', messageId);
      const imageBlob = getImageFromLINE(messageId);
      Logger.log('画像取得成功。サイズ: %d bytes', imageBlob.getBytes().length);
      const base64Image = Utilities.base64Encode(imageBlob.getBytes());
      Logger.log('画像をbase64エンコード完了: length=%d', base64Image.length);

      // Difyにファイルをアップロード
      Logger.log('analyzeImage start');
      const fileId = uploadFileToDify(base64Image);
      Logger.log('DifyファイルID取得: %s', fileId);

      // Difyで画像を解析
      const dify_result = runDifyWorkflow(fileId);
      Logger.log('Difyで画像を解析した結果のJSON: %s', JSON.stringify(dify_result));
      Logger.log('analyzeImage end');
      
      //Jsonパース
      const sheetData = processJson(dify_result);
      
      if (!sheetData) {
        Logger.log('JSONパースに失敗しました');
        replyMessage(replyToken, MESSAGES.parseError);
        return ContentService.createTextOutput(JSON.stringify({ content: 'parse error' })).setMimeType(ContentService.MimeType.JSON);
      }

      Logger.log('Jsonをパースした結果: %s', JSON.stringify(sheetData));
      
      // スプレッドシートに書き込み
      writeToSheet(sheetData);

      // 成功メッセージを動的に生成
      const successMessage = generateSuccessMessage(sheetData);
      replyMessage(replyToken, successMessage);
      Logger.log('返信完了');
    } else {
      Logger.log('画像メッセージでないため、メッセージを返信します。');
      replyMessage(replyToken, MESSAGES.requestImage);
    }

    Logger.log('--- doPost end ---');

    //デバッグ
    if (debugsheet !== null) {
      debugsheet.insertRowBefore(1);
      let dt = new Date();
      debugsheet.getRange('A1').setValue(Utilities.formatDate(dt, "JST", 'yyyy-MM-dd HH:m:ss'));
      debugsheet.getRange('B1').setValue(Logger.getLog());
    }

    return ContentService.createTextOutput(JSON.stringify({ content: 'ok' })).setMimeType(ContentService.MimeType.JSON);

  } catch (error) {
    Logger.log(`エラーが発生しました: ${error.stack || error}`);

    //デバッグ
    if (debugsheet !== null) {
      debugsheet.insertRowBefore(1);
      let dt = new Date();
      debugsheet.getRange('A1').setValue(Utilities.formatDate(dt, "JST", 'yyyy-MM-dd HH:m:ss'));
      debugsheet.getRange('B1').setValue(Logger.getLog());
    }

    return ContentService.createTextOutput(JSON.stringify({ content: 'error' })).setMimeType(ContentService.MimeType.JSON);
  }
}

// LINEから画像を取得
function getImageFromLINE(messageId) {
  Logger.log('getImageFromLINE start: messageId=%s', messageId);
  const url = `${LINE_CONTENT_URL}/${messageId}/content`;
  const response = UrlFetchApp.fetch(url, {
    headers: { 'Authorization': `Bearer ${LINE_ACCESS_TOKEN}` },
  });
  Logger.log('LINE画像取得レスポンスステータス: %s', response.getResponseCode());
  Logger.log('getImageFromLINE end');
  return response.getBlob();
}

// Difyにファイルをアップロード
function uploadFileToDify(base64Image) {
  Logger.log('uploadFileToDify start');
  try {
    const user = DIFY_USER_ID;
    const imageBytes = Utilities.base64Decode(base64Image);
    Logger.log('画像バイト長: %d', imageBytes.length);

    const blob = Utilities.newBlob(imageBytes, UPLOAD_MIME_TYPE, UPLOAD_FILE_NAME);
    Logger.log('Blob作成完了: type=%s, name=%s', blob.getContentType(), blob.getName());

    const formData = {
      'file': blob,
      'user': user
    };

    const options = {
      method: 'post',
      headers: {
        'Authorization': `Bearer ${DIFY_API_KEY}`
      },
      payload: formData,
      muteHttpExceptions: true
    };

    const response = UrlFetchApp.fetch(DIFY_UPLOAD_URL, options);
    const status = response.getResponseCode();
    const responseText = response.getContentText();
    Logger.log('Difyファイルアップロードレスポンスステータス: %d', status);
    Logger.log('Difyファイルアップロードレスポンスボディ: %s', responseText);

    const result = JSON.parse(responseText);

    if (!result.id) {
      Logger.log('ファイルアップロード失敗: %s', JSON.stringify(result));
      throw new Error('ファイルアップロードに失敗しました。');
    }

    Logger.log('uploadFileToDify end');
    return result.id; // file_idを返す
  } catch (error) {
    Logger.log('uploadFileToDifyでエラーが発生しました: %s', error.message);
    throw error;
  }
}

// Difyのワークフローを実行し、結果から情報を取得
function runDifyWorkflow(fileId) {
  Logger.log('runDifyWorkflow start: fileId=%s', fileId);
  const user = DIFY_USER_ID;
  const payload = {
    "inputs": {
      [DIFY_INPUT_KEY]: {
        "transfer_method": "local_file",
        "upload_file_id": fileId,
        "type": "image"
      }
    },
    "response_mode": "blocking",
    "user": user
  };
  Logger.log('ワークフロー実行ペイロード: %s', JSON.stringify(payload));

  const options = {
    method: 'post',
    headers: {
      'Authorization': `Bearer ${DIFY_API_KEY}`,
      'Content-Type': 'application/json'
    },
    payload: JSON.stringify(payload),
    muteHttpExceptions: true
  };

  const response = UrlFetchApp.fetch(DIFY_WORKFLOW_URL, options);
  const status = response.getResponseCode();
  const responseText = response.getContentText();
  Logger.log('Difyワークフローレスポンスステータス: %d', status);
  Logger.log('Difyワークフローレスポンスボディ: %s', responseText);

  const result = JSON.parse(responseText);
  
  if (result && result.data && result.data.outputs) {
    Logger.log('Difyワークフローoutputs全体: %s', JSON.stringify(result.data.outputs));
    const outputs = result.data.outputs;
    return outputs;
  } else {
    Logger.log('ワークフローの結果が期待した形式でありません: %s', JSON.stringify(result));
    throw new Error('画像解析結果の取得に失敗しました。');
  }
}

// JSONデータを解析する(マークダウン記法対応)
function processJson(jsonData) {
  Logger.log('processJson内の先頭: %s', JSON.stringify(jsonData));

  if (jsonData.text) {
    try {
      // マークダウンのコードブロック記法を除去
      let cleanedText = jsonData.text;
      
      // ```json で始まり ``` で終わる部分から中身のJSONだけを抽出
      const jsonMatch = cleanedText.match(/```json\n([\s\S]*?)\n```/);
      if (jsonMatch) {
        cleanedText = jsonMatch[1];
      } else {
        // ```json記法がない場合は、```で囲まれた部分を探す
        const codeMatch = cleanedText.match(/```([\s\S]*?)```/);
        if (codeMatch) {
          cleanedText = codeMatch[1];
        }
      }
      
      Logger.log('クリーニング後のJSON文字列: %s', cleanedText);
      
      const parsed = JSON.parse(cleanedText);
      Logger.log('パース成功: %s', JSON.stringify(parsed));
      
      return parsed;

    } catch (parseError) {
      Logger.log('processJson内で JSONパースに失敗しました: %s', parseError);
      Logger.log('パースしようとした文字列: %s', jsonData.text);
      throw new Error('解析結果のパースに失敗しました。');
    }
  } else {
    Logger.log('processJson内で textフィールドが存在しません');
    throw new Error('解析結果が取得できませんでした。');
  }
}

// スプレッドシートに書き込む
function writeToSheet(data) {
  try {
    const sheet = SpreadsheetApp.openById(RESULT_SHEET_ID).getSheetByName(TARGET_SHEET_NAME);
    
    if (!sheet) {
      Logger.log('%sが見つかりません', TARGET_SHEET_NAME);
      throw new Error(`${TARGET_SHEET_NAME}が見つかりません`);
    }
    
    // 現在の日時を取得
    const now = new Date();
    const timestamp = Utilities.formatDate(now, "JST", 'yyyy-MM-dd HH:mm:ss');
    
    // ヘッダーの存在確認(より確実な方法)
    const lastRow = sheet.getLastRow();
    let hasHeader = false;
    
    if (lastRow > 0) {
      // 1行目のA1セルの値を確認
      const firstCell = sheet.getRange(1, 1).getValue();
      if (firstCell && (firstCell.toString().includes('登録日時') || firstCell.toString().includes('日時'))) {
        hasHeader = true;
      }
    }
    
    // ヘッダーがない場合は強制的に追加
    if (!hasHeader) {
      Logger.log('ヘッダーが存在しないため追加します');
      
      // シートが完全に空の場合
      if (lastRow === 0) {
        sheet.appendRow(SHEET_HEADERS);
      } else {
        // データがある場合は1行目に挿入
        sheet.insertRowBefore(1);
        sheet.getRange(1, 1, 1, SHEET_HEADERS.length).setValues([SHEET_HEADERS]);
      }
      Logger.log('ヘッダー追加完了');
    }
    
    // 受信したJSONデータから利用可能なキーを動的に取得
    const availableKeys = Object.keys(data);
    Logger.log('利用可能なキー: %s', JSON.stringify(availableKeys));
    
    // データを1行として追加(動的マッピング使用)
    const rowData = [
      timestamp,
      getValueFromMapping(data, KEY_MAPPING.company),
      getValueFromMapping(data, KEY_MAPPING.position),
      getValueFromMapping(data, KEY_MAPPING.name),
      getValueFromMapping(data, KEY_MAPPING.phone),
      getValueFromMapping(data, KEY_MAPPING.email),
      getValueFromMapping(data, KEY_MAPPING.address),
      getValueFromMapping(data, KEY_MAPPING.url)
    ];
    
    sheet.appendRow(rowData);
    
    Logger.log('%sへの書き込みに成功しました: %s', TARGET_SHEET_NAME, JSON.stringify(rowData));
    
    // 追加で、受信した全データも参考用にログ出力
    Logger.log('受信した全データ: %s', JSON.stringify(data));
    
  } catch (error) {
    Logger.log('writeToSheetでエラーが発生しました: %s', error.message);
    throw error;
  }
}

// LINEにメッセージを返信
function replyMessage(replyToken, message) {
  Logger.log('replyMessage start');
  const payload = {
    replyToken: replyToken,
    messages: [{ type: 'text', text: message }],
  };

  const options = {
    method: 'post',
    headers: {
      'Authorization': `Bearer ${LINE_ACCESS_TOKEN}`,
      'Content-Type': 'application/json',
    },
    payload: JSON.stringify(payload),
  };

  Logger.log('返信ペイロード: %s', JSON.stringify(payload));

  try {
    const response = UrlFetchApp.fetch(LINE_REPLY_URL, options);
    Logger.log('返信成功: %s', response.getContentText());
  } catch (error) {
    Logger.log(`返信失敗: ${error.stack || error}`);
    throw new Error('返信に失敗しました。');
  }
  Logger.log('replyMessage end');
}

// ========================================
// ヘルパー関数
// ========================================

// キーマッピングから値を取得するヘルパー関数
function getValueFromMapping(data, keyArray) {
  for (const key of keyArray) {
    if (data[key] && data[key] !== '') {
      return data[key];
    }
  }
  return '';
}

// 成功メッセージを動的に生成する関数
function generateSuccessMessage(data) {
  let message = MESSAGES.success;
  
  // 全項目を表示(空白でも表示)
  message += '\n\n📋 解析結果:';
  
  const company = getValueFromMapping(data, KEY_MAPPING.company);
  const position = getValueFromMapping(data, KEY_MAPPING.position);
  const name = getValueFromMapping(data, KEY_MAPPING.name);
  const phone = getValueFromMapping(data, KEY_MAPPING.phone);
  const email = getValueFromMapping(data, KEY_MAPPING.email);
  const address = getValueFromMapping(data, KEY_MAPPING.address);
  const url = getValueFromMapping(data, KEY_MAPPING.url);
  
  message += `\n🏢 会社名: ${company || '(空白)'}`;
  message += `\n👔 役職: ${position || '(空白)'}`;
  message += `\n👤 名前: ${name || '(空白)'}`;
  message += `\n📞 電話番号: ${phone || '(空白)'}`;
  message += `\n📧 メールアドレス: ${email || '(空白)'}`;
  message += `\n🏠 住所: ${address || '(空白)'}`;
  message += `\n🌐 URL: ${url || '(空白)'}`;
  
  message += MESSAGES.checkSheet + '\n' + RESULT_SHEET_URL;
  
  return message;
}

3.権限設定&デプロイ

1. 上の「デプロイ」→「新しいデプロイ」→「ウェブアプリ」

2. 説明欄は「名刺LINE自動登録などや、空欄のまま」でOK

3. 「次のユーザーとして実行」は「自分」

4. 「アクセスできるユーザー」は「全員」にする

5. 「デプロイ」ボタンを押す

6. 「ウェブアプリのURL」をコピー(これをLINEのWebhookに使う)

4.LINE DevelopersでWebhook URLを設定

1. LINE Developersに戻る

先ほどコピーした”ウェブアプリのURL”をラインの設定画面に登録することで、スプレッドシートと、LINEが接続できるようになります。

2. 「Messaging API」→「チャネル」→「Webhook URL」へ、さっきコピーしたGASのウェブアプリURLを貼り付けて保存

3. Webhookの利用を「利用する」にON

4. LINE Official Account Managerの「応答設定」に移動し、「チャット」をオフ+「Webhook」がオンになっているか確認

5.テスト

1. 作ったLINE公式アカウントを「友だち追加」

2. スマホで名刺の写真を撮影し、LINEで公式アカウントに画像を送る

3. 自動返信で「名刺が追加されました」と来ていればOK

4. スプレッドシートとDriveにデータが記録されているか確認

よくある質問

名刺画像を送っても情報が正しく抜き出せません。なぜ?

画像が暗かったり、名刺が斜め・ピンボケの場合はAIの認識率が下がります。できるだけ明るい場所で、名刺全体が正面に収まるよう撮影しましょう。また、特殊なレイアウト・手書きの場合は項目ごとに手修正が必要なケースもあります。

スプレッドシートの情報を複数人で共有できますか?

もちろん可能です。Googleスプレッドシートの「共有」機能を使えば、社内メンバー全員で名刺リストをリアルタイムで参照・編集できます。

途中でエラーが出て動かなくなりました。どうすれば?

まずはエラー内容を「GASのエディタ」画面の「表示→実行ログ」で確認し、入力したIDやAPIキーの間違いがないか再チェックしてください。不明点があれば本記事下部の「ジドウカ」サービスに気軽にご相談を。

なかなかうまくいかないときは?

いくらノーコードツールとはいえ、プログラミングが未経験の方にとっては少しハードルが高く「諦めるしかない⋯」と挫折するきっかけを生みかねません。

「社内で自動化したは良いものの、自分がやめたら引き継ぐ人がいない⋯」

「一つ自動化したら、他部署からも自動化を依頼されて自分の仕事が進まない⋯」

と不安な方もいますよね。

そこで、おすすめしたいのが「ジドウカ」です。

ジドウカは、これまで合計800タスク以上の業務の自動化をしてきた実績のある法人専用の自動化サービスです。

業務の一部を“タスク単位”で自動化し、【月額1万円から】安定運用できるサブスクリプション型のサービスです。 タスクを外注するため手離れもよく、技術のことが分からなくても、「こういう作業をラクにしたい」と伝えるだけで自動化することが可能です。

「わたしが自動化したい内容って自動化できるんだろうか⋯」という方には、少額・短期間での「お試し開発」があるので、お気軽にご活用ください。

まとめ

「名刺管理が面倒…」そんな悩みは、LINEに画像を送るだけで一発解決!

この記事のステップ通りに進めれば、専門知識がなくても“今すぐ・無料で”名刺情報のデジタル化が始められます。

うまくいかない時や「自分での運用が不安」な場合は、プロの自動化サービスも併用しながら、ラクに・賢く名刺管理をアップデートしましょう!

自社で自動化する際によくある失敗ランキング

自動化ツールを導入すれば業務が自動化され、効率が劇的に向上する——。 そう考えている企業は多いですが、実際には多くの企業が自動化ツールを十分に活用できていません。 有名な自動化ツールであるRPAを例にあげても、導入した企業の実態は理想と大きく異なった結果となっています。

RPA導入企業の約60%が「あまり活用できていない」と回答

多くの企業がRPAを導入しているにも関わらず、約60%の企業が「期待したほど活用できていない」と感じているというデータです。これは、「導入しただけでは、業務改善につながらない」という現実を示しています。

RPAの効果を実感できない要因は『RPA開発が進んでいない』

「RPAの効果を実感できていない」と回答した企業の多くが、その理由として「RPA開発が進んでいない」「他業務・他部署への展開ができていない」ことを挙げています。   「〇〇業務はツールを導入すればすぐにラクになるはず」と思って、自社で自動化に挑戦した方も多いのではないでしょうか?しかし私たちには、こんな“あるあるの失敗談”がよく届きます。

🥇 第1位:初期設定でつまずき、結局断念…

思っていたより設定が複雑で、ツールの仕様を理解する前に挫折してしまうケース。 特にRPAツールやノーコードツールは、「慣れるまでが大変」という声が多いです。

🥈 第2位:担当者が辞めて、運用不能に…

担当者が社内で唯一のキーマンだった場合、その人がいなくなると全て止まってしまうという問題が発生します。 しかも、「誰も中身が分からないから触れない」という状況になりがち。

🥉 第3位:不具合や修正対応に時間がかかる…

自動化が止まったとき、「誰が見ればいいのか分からない」「ベンダーに相談するのも手間」という理由で、対応が後手に。 気づけばその対応に何時間も時間を取られ、本業に集中できなくなってしまうことも…。   実はよくある…自社で自動化に挑戦したときの“落とし穴” 共通するのは「すべて自社で完結しようとした」こと。 このようなケースに共通するのが、「最初から最後まで、すべて自社で完結しようとした」点です。 最初はうまくいっても、長期的に安定した自動化運用には、継続的な保守や柔軟な調整が不可欠です。

安定的に自動化したいならジドウカがおすすめ

 「ツールを入れただけ」では業務はラクになりません 「業務をラクにする自動化」のためには、設定・運用・トラブル対応まで含めてプロに任せるのが最も確実です。

ジドウカとは?

業務の一部を“タスク単位”で自動化し、月額で安定運用できるサブスクリプション型のサービスです。 技術のことが分からなくても、「こういう作業をラクにしたい」と伝えるだけでOK。

ジドウカでできること(業務例)

・定期レポートの自動作成とSlack送信 ・受注データのExcel整形とkintone登録 ・競合サイトの自動モニタリングとアラート通知 ・営業リストの自動生成とCRMへの投入 など

ジドウカが選ばれる理由

弊社の自動化サービス「ジドウカ」は、1社1社、1タスク1タスクに合わせて完全オーダーメイドで開発するサービス担っています。
  • ヒアリングから開発・運用まで丸ごとサポート
  • トラブル発生時には即時対応
  • 月額料金内で自由に修正をご依頼可能
実際に多くのお客様から「自社での自動化運用に失敗した後に依頼してよかった」と高評価をいただいています。
目次