LoginSignup
lotus1229
@lotus1229

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!

Messaging APIでエラーは表示されないがメッセージが送信されない。

解決したいこと

Messeging API と なろう小説APIを用いてユーザーが送信したメッセージで「小説家になろう」を検索し、ランダムにヒットした小説を紹介するLINE Botを作成しています。
メッセージを送信した際に、ターミナル上では実行ができているように確認ができたのですが、実際にLINEにメッセージが送信されないため、原因として何が考えられるかご助言いただきたいです。

発生している問題・エラー

ターミナル上でエラーログは表示されず、APIを叩いた情報の取得はできているように見えるがLINEに送信されない。

該当するソースコード

ソースコード全体を記載していますが、長いため格納を行っております。

サンプルコード **(クリックで表示)**
ソースコード
'use strict';

// ########################################
//               初期設定など
// ########################################

// パッケージを使用します
const express = require('express');
const line = require('@line/bot-sdk');
const axios = require('axios');

// ローカル(自分のPC)でサーバーを公開するときのポート番号です
const PORT = process.env.PORT || 3000;

// Messaging APIで利用するクレデンシャル(秘匿情報)です。
const config = {
    channelSecret: '********************************',
    channelAccessToken: '***************************'
};

const getNovelName = async (userId, tag) => {
    let result1 = '';
    let result2 = '';
    for(let i = 0; i<3; i++){
    let num = Math.floor(Math.random() * 10) + 1;
    try {
        // axiosでなろうのAPIを叩きます
        const res = await axios.get('https://api.syosetu.com/novelapi/api/?time=30-100&word=' + encodeURI(tag) + '&out=json');
        const item = res.data;

        result1 = item[num].title
        result2 = item[num].ncode
        // ターミナルにも検索結果を出しておきます
        console.log(item[num].title);
        console.log(item[num].ncode);
        console.log(num);
        // 正常に取得できればここで終了

        // リプライではなく「プッシュ」を送ります
        // Botからユーザーへ一方的に通知を送ることができる機能です
        await client.pushMessage[userId, {
            type: 'text',
            text: result1,
        },{
            type: 'text',
            text: 'https://ncode.syosetu.com/'+ result2 +'/', 
        }];
    } catch (error) {
        console.log(error);
    }
}
}

const sampleFunction = async (event) => {
    // ユーザーIDとメッセージ文字列を関数に渡します
    // メッセージ文字列でQiitaタグを検索し、結果をQiitaから受け取ったらユーザーIDに対して「プッシュ」送信します
    // 検索には少し時間がかかるので、これの結果は後でユーザーに送られます
    getNovelName(event.source.userId, event.message.text);

    // こちらが先に返事を返します
    // ユーザーからのメッセージに対する「リプライ」です
    // リプライは、受信したメッセージ1つにつき1回しか使えません
    return client.replyMessage(event.replyToken, {
        type: 'text',
        text: '検索しています……'
    });
};

// ########################################
//  LINEサーバーからのWebhookデータを処理する部分
// ########################################

// LINE SDKを初期化します
const client = new line.Client(config);

// LINEサーバーからWebhookがあると「サーバー部分」から以下の "handleEvent" という関数が呼び出されます
async function handleEvent(event) {
    // 受信したWebhookが「テキストメッセージ以外」であればnullを返すことで無視します
    if (event.type !== 'message' || event.message.type !== 'text') {
        return Promise.resolve(null);
    }
    // サンプル関数を実行します
    return sampleFunction(event);
}

// ########################################
//          Expressによるサーバー部分
// ########################################

// expressを初期化します
const app = express();

// HTTP POSTによって '/webhook' のパスにアクセスがあったら、POSTされた内容に応じて様々な処理をします
app.post('/webhook', line.middleware(config), (req, res) => {

    // 検証ボタンをクリックしたときに飛んできたWebhookを受信したときのみ以下のif文内を実行
    if (req.body.events.length === 0) {
        res.send('Hello LINE BOT! (HTTP POST)'); // LINEサーバーに返答します(なくてもよい)
        console.log('検証イベントを受信しました!'); // ターミナルに表示します
        return; // これより下は実行されません
    } else {
        // 通常のメッセージなど … Webhookの中身を確認用にターミナルに表示します
        console.log('受信しました:', req.body.events);
    }

    // あらかじめ宣言しておいた "handleEvent" 関数にWebhookの中身を渡して処理してもらい、
    // 関数から戻ってきたデータをそのままLINEサーバーに「レスポンス」として返します
    Promise.all(req.body.events.map(handleEvent)).then((result) => res.json(result));
});

// 最初に決めたポート番号でサーバーをPC内だけに公開します
// (環境によってはローカルネットワーク内にも公開されます)
app.listen(PORT);
console.log(`ポート${PORT}番でExpressサーバーを実行中です…`);

自分で試したこと

VS code上では画像のようにタイトル・ncode(小説のURLを判別するもの)が出力されましたがLINE上ではメッセージは表示がされませんでした。
ターミナル上で表示がされるためにAPIの叩き方ではなく、メッセージを送る部分のコードに原因があると考えましたが、何がよくなかったのか原因が思いついておりません。
テキストを1通にすると送信ができたので、2通送るのがそもそもできない、ということかもしれないと想像しています。

送信できない原因になっていそうなコード
await client.pushMessage[userId, {
            type: 'text',
            text: result1,
        },{
            type: 'text',
            text: 'https://ncode.syosetu.com/'+ result2 +'/', 
        }];
0

2Answer

送るメッセージ部分が一塊になっていないのが原因かなと思ったのですが、
[
 {
type: 'text',
text: result1,
 },
{
 type: 'text',
text: 'https://ncode.syosetu.com/'+ result2 +'/',
}
]
でも無理でしょうか?(手元とインデントが違う表示になってしまい、見づらくすみません。)

1

Comments

  1. もう一つ気になったのが、
    pushMessage(to: string, messages: Message | Message[], notificationDisabled: boolean = false)
    にのっとると、
    pushMessage(userId, [message])かなと思ったのですが、1通の時は送れたのだとするとそこは大丈夫ってことですよね。

@ped-yui123
コメントありがとうございます。
実装時は結局、メッセージ1通に2要素が入る形でコードを書き直して進めました。
いただいたコメントの形式でも一度試してみたいと思います。

0

Your answer might help someone💌