@y_nn_6

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

<GAS>チャットボットの作成

解決したいこと

こちらのコードでLINEに位置情報を送った際に返答がない原因がわかりません。

LINEで位置情報検索できるチャットボットを開発しています。
解決方法を教えて下さい。

以下のコードでIDやアクセストークンは自分のもので当てはめて実行したが、うまくできませんでした。自分でも何度も時間を空けて調べた結果動きませんでした。
コードが長く見づらくて申し訳ありませんが、解決していただきたいです。

var YAHOO_APP_ID = 'Yahoo!デベロッパーネットワークのアプリケーションのClient ID'//ClientID
var LINE_BOT_CHANNEL_ACCESS_TOKEN = '自分のLINE chat botのチャネルアクセストークン'//チャネルアクセストークン

var ss = SpreadsheetApp.openById("自身で作成したスプレッドシートのID");//スプレッドシートID
var sh = ss.getSheetByName("業種コード");//スプレッドシートのシート名

var GC = sh.getRange('D2').getValue();//D2のコードをGCに代入

var LINE_REPLY_URL = 'https://api.line.me/v2/bot/message/reply';
var YAHOO_SEARCH_URL = 'https://map.yahooapis.jp/search/local/V1/localSearch';

//google検索
function getGoogleSearchUrl(query) {
return 'https://www.google.co.jp/search?q=' + encodeURIComponent(query) + '&ie=UTF-8';
}

//googleマップルート検索
function getGoogleMapRouteUrl(srcLatitude, srcLongitude, destLatitude, destLongitude) {
return 'http://maps.google.com/maps'
+ '?saddr=' + destLatitude + ',' + destLongitude
+ '&daddr=' + srcLatitude + ',' + srcLongitude
+ '&dirflg=w';
}

var Restaurant = function(name, address, googleSearchUrl, googleMapRouteUrl) {
this.name = name;
this.address = address;
this.googleSearchUrl = googleSearchUrl;
this.googleMapRouteUrl = googleMapRouteUrl;
};

//検索部分 
function getNearRestaurants(latitude, longitude) {
var url = YAHOO_SEARCH_URL
+ '?appid=' + YAHOO_APP_ID
+ '&cid=d8a23e9e64a4c817227ab09858bc1330' //カセットID
+ '&dist=3' // 3 km 以内
+ '&gc=' + GC // 業種コード
+ '&results=5' // 最大 5 件
+ '&lat=' + latitude//
+ '&lon=' + longitude//
+ '&output=json&sort=dist';//json
var response = UrlFetchApp.fetch(url);

var restaurants = [];
var features = JSON.parse(response.getContentText('UTF-8'))['Feature'];
for (i = 0; i < features.length; i++) {
var name = features[i].Name;
var address = features[i]['Property'].Address;
var coords = features[i]['Geometry'].Coordinates.split(',');
var restaurant_lonitude = coords[0];
var restaurant_latitude = coords[1];
var googleSearchUrl = getGoogleSearchUrl(name + ' ' + address);
var googleMapRouteUrl = getGoogleMapRouteUrl(restaurant_latitude, restaurant_lonitude, latitude, longitude);
restaurants.push(new Restaurant(name, address, googleSearchUrl, googleMapRouteUrl));
}
return restaurants;
}

function doPost(e) {
var json = JSON.parse(e.postData.contents);

var userId = json.events[0].source.userId;

var replyToken= json.events[0].replyToken;
if (typeof replyToken === 'undefined') {
return;
}

//ヘルプ用メッセージ
var helpMessage = '位置情報を送信すると、半径3 km 以内の店舗を、最大 5 つ探して次の情報をお伝えします。\n\n'
+ '・店の名前\n'
+ '・住所\n'
+ '・検索リンク\n'
+ '・ルート案内リンク\n\n'
+ '↓こちらのボタンから位置情報\n を送信できます。';

if ('message' == json.events[0].type) {
var userMessage = json.events[0].message;

//位置情報を送ったとき
if ('location' == userMessage.type) {
  var replyMessage = getNearRestaurants(userMessage.latitude, userMessage.longitude);
  var columns = replyMessage.map(function (v) {
    var title = v.name;
    var adr = v.address;
    return {
      'title': title,
      'text': adr,
      'actions': [
        {
          'type': 'uri',
      'thumbnailImageUrl':'',
          'label': 'ここを検索',
          'uri': v.googleSearchUrl
        },
        {
          'type': 'uri',
          'label': 'ここへのルート',
          'uri': v.googleMapRouteUrl
        }
      ]
    };
});
var altText = '';
replyMessage.forEach(function(element, index, array) {
  altText += element.name + ' | ';
});
var messages = [
  {
    'type': 'template',
    'altText': altText,
    'template': {
      'type': 'carousel',
      'columns': columns
    }
  }
];
//ヘルプが打たれた時
}else if(userMessage.text == "ヘルプ"){
  messages = [{'type': 'text', 'text': helpMessage}];
  
//それ以外の文字「飲食店」と打てばスプレッドシートから業種コードを検索し、記録する
}else{
  //シートの最終行を取得する
  var lastRow = sh.getLastRow();
  //シートの業種名と業種コードを二次元配列で取得する
  var shopList = sh.getRange(1,1,lastRow,2).getValues();
  
  //業種コードを格納するための空配列を宣言する
  var codeList = [];
  
  //LINEで受信した語句がシートの業種名と同じ場合、業種コードをcodeListにpushする
  for(var i = 1; i < shopList.length; i++) {
    if(shopList[i][0] == userMessage.text) {
     codeList.push(shopList[i][1]);
    }
  }
  //シートに出力
  sh.getRange('D2').setValue(codeList);

  if(codeList.length < 1) {
    return;
  }
  var changeMessage = userMessage.text + 'を検索します。\n位置情報を送信してください。';
  messages = [{'type': 'text', 'text': changeMessage}];
}

}
/*応答メッセージを送る処理。わからないなら応答メッセージを送るの部分みてhttps://developers.line.biz/ja/reference/messaging-api/*/
UrlFetchApp.fetch(LINE_REPLY_URL, {
'headers': {
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'Bearer ' + LINE_BOT_CHANNEL_ACCESS_TOKEN,
},
'method': 'post',
'payload': JSON.stringify({
'replyToken': replyToken,
'messages': messages,
}),
});
return ContentService.createTextOutput(JSON.stringify({'content': 'post ok'})).setMimeType(ContentService.MimeType.JSON);
}

0 likes

2Answer

コードのコメントに「わからないなら応答メッセージを送るの部分みて」とありますが、誰かから引き継いだのでしょうか。

  • 基本的なことですがチャンネルトークンは正しいですか?

  • GAS デプロイ時のアクセス権限は「全員」になっていますか?

  • 修正後デプロイし直すとデプロイURLは変わります。変わった後のURLをきちんとLINE DevelopersのページのwebhookURLに設定していますか?

  • LINE Developesでwebhookの検証ボタンをクリックしたときに「ok」が返ってきていますか?

  • スプレッドシートの「業種コード」シートはどのような状況でしょうか。
    「あなたが引き継いだ元の作者さん」?の想定通りに「業種コード」シートに正しくデータは入っていますか?
    (空白だったり間違った列に入っている可能性はありませんか)

  • テスト時、LINEへの入力手順は正しいですか?プログラム上、返事が返ってこないようにLINEにメッセージを入力すると、返事は返ってきません。(これはエラーなどではなく、質問に記載されたプログラム上、そうなるようになっているからそうなるだけです)
    そのような入力を行っているために、動かないのだと勘違いされていませんか?

2Like

Comments

  1. @y_nn_6

    Questioner

    引き継いだものであります。
    コメントいただいたことはすべて確認したのですが、おそらく間違いはありませんでした。

    LINE上で位置情報を送った際にその返答が返ってきません。

繰り返します。

「業種コードのシート」は、どのような状況ですか?
プログラムで動作するよう、意図したとおりになっていますか?

具体的には、A列は業種名、B列はそれに対応する、ゼロ始まりで、YahooロケーションAPIにとって意味のある業種コードである必要があります。

image.png

ゼロ始まりでない数字になっている場合、YahooロケーションAPIにリクエストしても、存在しない業種コードなので、データゼロ件で返ってきます。

質問に記載されたプログラムコードは、YahooAPIからのデータがゼロ件の場合、LINEメッセージを何も返すことなく終了します。

  • D2セルにリクエストした業種コードが記録されるようになっていますが、D2セルの書式を「書式なしテキスト」にしていないと、プログラムでコピーされた業種コードの先頭ゼロが抜けてしまうので、正常に動作しません。

その他:
手元では質問のコードで正常に動いています

(ただしメッセージが返ってこない場合バグかどうかわからないので、Yahoo APIの検索結果がゼロ件の場合はLINEにゼロ件というメッセージを返すように変えましたが)

バグの原因が分からないということかもしれませんが、Yahoo APIとLINE Message とスプレッドシートの3つに役割が分かれているプログラムなので、まずは問題を切り分ける必要があるでしょう。

たとえば

  • LINE メッセージをオウム返しできるか?
  • Yahoo APIの呼び出しは問題ないか?(console.logで確認)
  • スプレッドシートからのデータ読み取りや書き込みにバグはないか?

など、他の2つの機能をコメントアウトするなりして1つずつ試してみては?

0Like

Comments

  1. @y_nn_6

    Questioner

    D2セルの書式を訂正したら動きました。
    ほんとうにありがとうございます。

    これに追加で2つのことをやりたいのですが、
    ・レビュー順に並び替え
    ・店舗サムネイルの追加
    こちらの2つですが、レビュー順に並べようと思ったらコードが正常に動かなくなったのと、店舗サムネイルの追加は写真の追加がなく、白の画像が貼り付けてあるという形になったのですが、原因や改善があれば教えていただきたいです。

    • レビュー順に並べようと思ったらコードが正常に動かなくなった

    正常に動かない、というのは具体的にどういう状態ですか?
    「まったく返答が返ってこない」ということなら、以下の可能性があります。
    ・Yahoo APIへのリクエストが間違っていて、APIから戻ってくるデータが0件のため、返事がない。
    ・レビュー順に並べるため追加したコードに文法誤りがあってGAS側の動作が止まっている。
     
     

    • 店舗サムネイルの追加は写真の追加がなく、白の画像が貼り付けてあるという形になった

    →質問には画像を表示する部分がないようですが、具体的にどのようなコードで試されたのですか?
    現状は、LINEMessaging APIの仕様に沿った書き方になっていない可能性がある、としか答えようがありません。

Your answer might help someone💌