質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.11%

Lambdaでのエラー、「Unable to import module 'index'」の原因が分からない

受付中

回答 0

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 726

yuta_kg

score 24

以下の記事を参考に、LINEログインとMessaging APIを使って、AlexaスキルからLINE botに通知するスキルを開発しています。
記事:https://qiita.com/imajoriri/items/0e975b15b9023cafce24

外部モジュールを使うので、ローカルにインストールしzipで圧縮しLambdaにアップロードしたのですが、以下のエラーがでました。

Unable to import module 'index': Error
at Function.Module._resolveFilename (module.js:547:15)
at Function.Module._load (module.js:474:25)
at Module.require (module.js:596:17)
at require (internal/module.js:11:18)
at Object.<anonymous> (/var/task/index.js:4:15)
at Module._compile (module.js:652:30)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
at Function.Module._load (module.js:497:3)

このエラーはLambdaの設定で、ハンドラの名前がindex.handlerになってないこと(index.jsの場合)が原因らしいのですが、index.handlerに設定してあります。

このエラーの原因が分かる方は教えてください。

また、zipファイルの内部は以下になります。
index.js
node_modules

以下、index.jsのコードとAlexa Developer Consoleでテストした時のレスポンスです。

/* eslint-disable  func-names */
/* eslint-disable  no-console */

const Alexa = require('ask-sdk');
const rp = require('request-promise');
const line = require('@line/bot-sdk');

const client = new line.Client({
  // Lambdaの環境変数よりMessagingAPIのチャネルアクセストークンを取得
  channelAccessToken:  process.env["channelAccessToken"]
});

const LaunchRequestHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
  },
  async handle(handlerInput) {
    // Userごとのアクセストークン
    const accessToken = handlerInput.requestEnvelope.session.user.accessToken;
    console.log(accessToken);

    var options = {
      method: 'GET',
      uri: 'https://api.line.me/v2/profile',
      headers: {
        'Authorization': `Bearer ${accessToken}`
      }
    };
    // アクセストークンより、LINEのUser情報を取得
    var lineData = JSON.parse(await rp(options));

    const message = {
      type: 'text',
      text: 'スキルが起動されました。'
    };

    const userId = lineData.userId;

    // botに通知を送信
    await client.pushMessage(userId, message);

    var msg = 'Botにメッセージが送信されました';

    return handlerInput.responseBuilder
      .speak(msg)
      .reprompt(msg)
      .getResponse();
  }
};

// const GetNewFactHandler = {
//   canHandle(handlerInput) {
//     const request = handlerInput.requestEnvelope.request;
//     return request.type === 'LaunchRequest'
//       || (request.type === 'IntentRequest'
//         && request.intent.name === 'GetNewFactIntent');
//   },
//   handle(handlerInput) {
//     const factArr = data;
//     const factIndex = Math.floor(Math.random() * factArr.length);
//     const randomFact = factArr[factIndex];
//     const speechOutput = GET_FACT_MESSAGE + randomFact;

//     return handlerInput.responseBuilder
//       .speak(speechOutput)
//       .withSimpleCard(SKILL_NAME, randomFact)
//       .getResponse();
//   },
// };

const HelpHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'IntentRequest'
      && request.intent.name === 'AMAZON.HelpIntent';
  },
  handle(handlerInput) {
    return handlerInput.responseBuilder
      .speak(HELP_MESSAGE)
      .reprompt(HELP_REPROMPT)
      .getResponse();
  },
};

const ExitHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'IntentRequest'
      && (request.intent.name === 'AMAZON.CancelIntent'
        || request.intent.name === 'AMAZON.StopIntent');
  },
  handle(handlerInput) {
    return handlerInput.responseBuilder
      .speak(STOP_MESSAGE)
      .getResponse();
  },
};

const SessionEndedRequestHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'SessionEndedRequest';
  },
  handle(handlerInput) {
    console.log(`Session ended with reason: ${handlerInput.requestEnvelope.request.reason}`);

    return handlerInput.responseBuilder.getResponse();
  },
};

const ErrorHandler = {
  canHandle() {
    return true;
  },
  handle(handlerInput, error) {
    console.log(`Error handled: ${error.message}`);

    return handlerInput.responseBuilder
      .speak('Sorry, an error occurred.')
      .reprompt('Sorry, an error occurred.')
      .getResponse();
  },
};

const SKILL_NAME = 'Space Facts';
const GET_FACT_MESSAGE = 'Here\'s your fact: ';
const HELP_MESSAGE = 'You can say tell me a space fact, or, you can say exit... What can I help you with?';
const HELP_REPROMPT = 'What can I help you with?';
const STOP_MESSAGE = 'Goodbye!';

const data = [
  'A year on Mercury is just 88 days long.',
  'Despite being farther from the Sun, Venus experiences higher temperatures than Mercury.',
  'Venus rotates counter-clockwise, possibly because of a collision in the past with an asteroid.',
  'On Mars, the Sun appears about half the size as it does on Earth.',
  'Earth is the only planet not named after a god.',
  'Jupiter has the shortest day of all the planets.',
  'The Milky Way galaxy will collide with the Andromeda Galaxy in about 5 billion years.',
  'The Sun contains 99.86% of the mass in the Solar System.',
  'The Sun is an almost perfect sphere.',
  'A total solar eclipse can happen once every 1 to 2 years. This makes them a rare event.',
  'Saturn radiates two and a half times more energy into space than it receives from the sun.',
  'The temperature inside the Sun can reach 15 million degrees Celsius.',
  'The Moon is moving approximately 3.8 cm away from our planet every year.',
];

const skillBuilder = Alexa.SkillBuilders.standard();

exports.handler = skillBuilder
  .addRequestHandlers(
    LaunchRequestHandler,
    // GetNewFactHandler,
    HelpHandler,
    ExitHandler,
    SessionEndedRequestHandler
  )
  .addErrorHandlers(ErrorHandler)
  .lambda();

レスポンス

{
    "version": "1.0",
    "session": {
        "new": false,
        "sessionId": "amzn1.echo-api.session.c6c70564-b3a6-483b-9fb1-3a5c81bacccc",
        "application": {
            "applicationId": "amzn1.ask.skill.0069cc67-8e5a-4305-9f9d-5c3d433d96d6"
        },
        "user": {
            "userId": "個人情報なので省略",
            "accessToken": "個人情報なので省略"
        }
    },
    "context": {
        "System": {
            "application": {
                "applicationId": "amzn1.ask.skill.0069cc67-8e5a-4305-9f9d-5c3d433d96d6"
            },
            "user": {
                "userId": "個人情報なので省略",
                "accessToken": "個人情報なので省略"
            },
            "device": {
                "deviceId": "個人情報なので省略",
                "supportedInterfaces": {}
            },
            "apiEndpoint": "https://api.fe.amazonalexa.com",
            "apiAccessToken": "個人情報なので省略"
        },
        "Viewport": {
            "experiences": [
                {
                    "arcMinuteWidth": 246,
                    "arcMinuteHeight": 144,
                    "canRotate": false,
                    "canResize": false
                }
            ],
            "shape": "RECTANGLE",
            "pixelWidth": 1024,
            "pixelHeight": 600,
            "dpi": 160,
            "currentPixelWidth": 1024,
            "currentPixelHeight": 600,
            "touch": [
                "SINGLE"
            ],
            "video": {
                "codecs": [
                    "H_264_42",
                    "H_264_41"
                ]
            }
        }
    },
    "request": {
        "type": "SessionEndedRequest",
        "requestId": "amzn1.echo-api.request.e911134b-5bf9-416e-b594-33fe204658eb",
        "timestamp": "2019-09-13T00:21:58Z",
        "locale": "ja-JP",
        "reason": "ERROR",
        "error": {
            "type": "INVALID_RESPONSE",
            "message": "An exception occurred while dispatching the request to the skill."
        }
    }
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正の依頼

  • y_waiwai

    2019/09/12 22:46

    コードを提示しましょう

    キャンセル

  • papinianus

    2019/09/13 08:11

    > このエラーはLambdaの設定で、ハンドラの名前がindex.handlerになってないこと(index.jsの場合)が原因らしい
    これ出典教えて下さい。むしろexports.handlerにしてないから発生したエラーに見えますが。

    キャンセル

  • yuta_kg

    2019/09/13 09:15 編集

    index.jsのコードを追記しました。

    index.handlerにする、と書いてあったのは以下の記事にです。
    https://qiita.com/tom_furu/items/1750cc5ca28b76da11f1

    また、exports.handlerにして実行してみたのですが同様のエラーが発生しました。

    キャンセル

まだ回答がついていません

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.11%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる