🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
LINE Messaging API

LINE Messaging APIは、メッセージの送信・返信ができるAPIです。Web APIを経由しアプリケーションサーバとLINEのAPIでやり取りが可能。複数のメッセージタイプや分かりやすいAPIリファレンスを持ち、グループチャットにも対応しています。

Heroku

HerokuはHeroku社が開発と運営を行っているPaaSの名称です。RubyやNode.js、Python、そしてJVMベース(Java、Scala、Clojureなど)の複数のプログラミング言語をサポートしている。

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

811閲覧

【初心者】node.jsを用いて、linebotとpostgreSQLを接続する方法について

komukazu212

総合スコア1

LINE Messaging API

LINE Messaging APIは、メッセージの送信・返信ができるAPIです。Web APIを経由しアプリケーションサーバとLINEのAPIでやり取りが可能。複数のメッセージタイプや分かりやすいAPIリファレンスを持ち、グループチャットにも対応しています。

Heroku

HerokuはHeroku社が開発と運営を行っているPaaSの名称です。RubyやNode.js、Python、そしてJVMベース(Java、Scala、Clojureなど)の複数のプログラミング言語をサポートしている。

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2021/03/08 06:07

前提・実現したいこと

linebotとpostgreSQLの接続をnode.jsを用いて、行なっています。

まず簡単なおうむ返しbotを作っていてherokuにデプライまではできたのですが、そこからpostgreSQLへの接続がうまく言っていない状況です。

色々調べて、試してみたのですがうまくいかず質問させていただいています。
psqlのインストール、設定等の処理は完了しています。

また以下のコードで、デバッグしたところ、「受け取り成功」と「オウム返し成功」が返されてはいて、起動はしています

発生している問題・エラーメッセージ

herokuでデバッグしている限りではエラーメッセージは表示されず、以下のコード記述を下にも関わらず、すでに作っていたテーブル(mydata)にデータが格納されていない状況です。

該当のソースコード

index

1'use strict' 2 3/** 4* ライブラリのインポート 5*/ 6const express = require('express') 7 8 9 10/** 11* 初期設定 12*/ 13require('dotenv').config() 14const app = express() 15const routes = { 16 webhookRouter: require('./routes/webhook.js')//webhook時に、移動するためのライブラリの設定 17} 18 19/** 20* APIルート作成 21*/ 22app.use('/webhook', routes.webhookRouter) 23 24/** 25* サーバの起動 26*/ 27const port = process.env.PORT || 3000 28app.listen(port, () => { 29 console.log(`listening on ${port}`) 30}) 31

webhook

1'use strict' 2 3/** 4* ライブラリのインポート 5*/ 6const line = require('@line/bot-sdk') 7const express = require('express') 8 9/** 10* 初期化 11*/ 12const router = express.Router() 13const config = { 14 channelAccessToken: process.env.CHANNEL_ACCESS_TOKEN, 15 channelSecret: process.env.CHANNEL_SECRET 16} 17const client = new line.Client(config)// 18const ONE_MINUTES = 60000 19 20const{Client} = require ('pg') 21 22 23const dbclient=new Client({ 24 user: process.env.DB_USER, 25 host: process.env.DB_HOST, 26 database: process.env.DB_DATABASE, 27 password: process.env.DB_PASSWORD, 28 port: process.env.DB_PORT 29 }); 30 31/*const dbclient = new Client({ 32 connectionString: process.env.DATABASE_URL, 33});*/ 34 35dbclient.connect(); 36 37const query = { 38 text: 'INSERT INTO mydata(name,mail) VALUES($1, $2)', 39 values: ['太郎', 'mytest@samplel.com'], 40} 41 42 43 44 45 46 47 48/** 49* 動作確認用のルート 50*/ 51router.get('/', (req, res) => { 52 dbclient.query(query) 53 .then((res) => { 54 console.log(res.rows[0])}) 55 .catch((e) => {console.error(e.stack)}) 56})//純粋にリクエストを受け取ったら、ハローワールドをレスポンスとして送って、レスポンスのステータスを200にすることで応答を終了する 57 58/** 59* 本番用のルート 60*/ 61router.post('/', line.middleware(config), async (req, res) => { 62 63 64 Promise.all(req.body.events.map(handlerEvent)) 65 .then((result) => { 66 console.log(result) 67 res.status(200).end() 68 }) 69 .catch((err) => { 70 console.error(err) 71 res.status(500).end() 72 }) 73}) 74 75/** 76* メイン関数 77*/ 78const handlerEvent = async (event) => { 79 // Webhookの検証 80 if (event.replyToken && event.replyToken.match(/^(.)\1*$/)) { 81 return 'Webhookの検証' 82 } 83 84 const replyToken = event.replyToken 85 86 // イベントの処理 87 switch (event.type) { 88 case 'message': 89 const message = event.message 90 let text 91 92 switch (message.type) { 93 case 'text': 94 text = message.text 95 await replyText(replyToken, `${text}だというのか!`) 96 console.log("受け取り成功") 97 return 'オウム返し成功' 98 default: 99 text = 'テキストを送信してください' 100 await replyText(replyToken, text) 101 return 'その他' 102 } 103 default: 104 return 'その他' 105 } 106} 107 108/** 109* テキストを返信する関数 110* @param {String} token//メソッドのパラメーターの表示をしている 111* @param {String[] | String} texts 112*/ 113const replyText = (token, texts) => { 114 texts = Array.isArray(texts) ? texts : [texts] 115 return client.replyMessage( 116 token, 117 texts.map((text) => ({ type: 'text', text })) 118 ) 119} 120 121module.exports = router 122

試したこと

データベース自体はできていて、ターミナルからはデータベースの操作ができる状態にはなっています。
また、postgreSQLへの接続に関するコードを、index.jsに移してみたり、起動ができている関数の中に入れてみたりしましたが、状況は変わりませんでした。

また以下の記事を参考にして組み立てています。

https://qiita.com/tanakadaichi_1989/items/15e22cf9c9926e316166
https://qiita.com/nkjm/items/38808bbc97d6927837cd
https://note.com/96nz/n/n0eb4cc5b43b1

補足情報(FW/ツールのバージョンなど)

node 14.16.0
psql 13.2

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

以下のコードのようにSSL認証についての記述を追加したところ、無事、データのインサートができるようになりましたただ、.getメソッドの内部では、dbclient.connectionが起動せず、.postの内部では起動して、その原因については不明なままです。

node

1'use strict' 2 3/** 4* ライブラリのインポート 5*/ 6const line = require('@line/bot-sdk') 7const express = require('express') 8const{Client} = require ('pg'); 9 10/** 11* 初期化 12*/ 13const router = express.Router() 14const config = { 15 channelAccessToken: process.env.CHANNEL_ACCESS_TOKEN, 16 channelSecret: process.env.CHANNEL_SECRET 17} 18const client = new line.Client(config)// 19const ONE_MINUTES = 60000 20 21 22 23 24 25//以下の方法でもいけるのかチャレンジをしたところダメでした! 26// const dbclient=new Client({ 27// user: process.env.DB_USER, 28// host: process.env.DB_HOST, 29// database: process.env.DB_DATABASE, 30// password: process.env.DB_PASSWORD, 31// port: process.env.DB_PORT 32// }); 33 34const dbclient = new Client({ 35 connectionString: process.env.DATABASE_URL, 36 //ssl:true 37 ssl: { 38 rejectUnauthorized: false //SSL接続なくても許可すると宣言 39 } 40}); 41 42 43dbclient.connect() 44.then(() => console.log("Connected successfuly")) 45.catch((e => console.log(e))); 46 47const query = { 48 text:"SELECT * FROM mydata" 49 // text: 'INSERT INTO mydata(id,name,mail) VALUES($1,$2,$3)', 50 // values: ["4",'太郎', 'mytest@samplel.com'], 51} 52 53 54 55 56 57 58 59/** 60* 動作確認用のルート 61*/ 62// router.get('/', async(req, res) => { 63// dbclient.query(query)  //この中で、client.queryをしても失敗するなぜ?? 64// .then((res) => { 65// console.log(res.rows[0])}) 66// .catch((e) => {console.error(e.stack)}) 67// }) 68/** 69* 本番用のルート 70*/ 71router.post('/', line.middleware(config), async (req, res) => { 72 73 dbclient.query(query) 74 .then((res) => { 75 console.log(res.rows[0])}) 76 .catch((e) => {console.error(e.stack)}) 77 78 79 Promise.all(req.body.events.map(handlerEvent)) 80 .then((result) => { 81 console.log(result) 82 res.status(200).end() 83 }) 84 .catch((err) => { 85 console.error(err) 86 res.status(500).end() 87 }) 88}) 89 90/** 91* メイン関数 92*/ 93const handlerEvent = async (event) => { 94 // Webhookの検証 95 if (event.replyToken && event.replyToken.match(/^(.)\1*$/)) { 96 return 'Webhookの検証' 97 } 98 99 const replyToken = event.replyToken 100 101 // イベントの処理 102 switch (event.type) { 103 case 'message': 104 const message = event.message 105 let text 106 107 switch (message.type) { 108 case 'text': 109 text = message.text 110 await replyText(replyToken, `${text}だというのか!`) 111 console.log("受け取り成功") 112 return 'オウム返し成功' 113 default: 114 text = 'テキストを送信してください' 115 await replyText(replyToken, text) 116 return 'その他' 117 } 118 default: 119 return 'その他' 120 } 121} 122 123/** 124* テキストを返信する関数 125* @param {String} token//メソッドのパラメーターの表示をしている 126* @param {String[] | String} texts 127*/ 128const replyText = (token, texts) => { 129 texts = Array.isArray(texts) ? texts : [texts] 130 return client.replyMessage( 131 token, 132 texts.map((text) => ({ type: 'text', text })) 133 ) 134} 135 136module.exports = router

投稿2021/03/08 12:47

komukazu212

総合スコア1

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問