test -e auto_update.sh; echo $? FILE="auto_update.sh" if test -n "$FILE"; then echo "File is exist" fi
$ sh test.sh
0
File is exist
インストール関連はシェルで書いて、テストもシェルで書くのね。なるほど、勉強になりますね。
随机应变 ABCD: Always Be Coding and … : хороший
test -e auto_update.sh; echo $? FILE="auto_update.sh" if test -n "$FILE"; then echo "File is exist" fi
$ sh test.sh
0
File is exist
インストール関連はシェルで書いて、テストもシェルで書くのね。なるほど、勉強になりますね。
auto_update.sh
#!/bin/bash today=$(date "+%Y%m%d") log_DIR="./update_log" log_FILE="./update_log/update_${today}.log" if [! -d $log_DIR]; then sudo mkdir ${log_DIR} fi if [ ! -e $log_FILE ]; then sudo touch ${log_FILE} fi all_update(){ sudo apt-get update -y } start_time=$(date '+%Y/%m/%d %T') echo "#### $start_time start update ####" | sudo tee -a ${log_FILE} all_update | sudo tee -a ${log_FILE} end_time=$(date '+%Y/%m/%d %T') echo "#### $end_time end update ####" | sudo tee -a ${log_FILE}
$ chmod 777 auto_update.sh
$ ls -a
. .. auto_update.sh update_log
$ sh auto_update.sh
teeは標準入力から受け取った内容を、標準出力とファイルに書き出すコマンド
### ワット(W)とは
どれだけの電圧(V)で、どれだけの電流(A)を流せたかという仕事量を表す単位
ワットすうが高いほど、大きな電気エネルギーを使っている
Aアンペア x Vボルト = Wワット
### アンペア(A)
電流、電気の流れる量
### 電圧(V)
電気の強さ
※一般家庭では、100Vが一般的、国別に見ると、Europeは220Vが多い。高電圧に変更する場合は数万円程度かかる
※マイニングには100Vと200Vではパフォーマンスに差が出ると言われている
### ワットアワー(Wh)
1時間に使用するワットアワー
1000(W) x 1(h) = 1000Wh = 1kWh
### アンペア
一般家庭では20、30アンペア
東京電力では、アンペアブレーカーの色でアンペアがわかる
赤10、桃15, 黄20、緑30、グレー40、茶色50、紫60
### コンセント
一般家庭のコンセントでは1500Wまで使えるというのが多い
### 電気料金の決まり方
基本料金(アンペア)と従量課金
### 電力目安
新電力料金目安単価(1時間に1000W使用)31円/kWh(税込)〈
### 東京電力の単価表
最初の120kWhまで(第1段階料金) 1kWh 30円00銭
120kWhをこえ300kWhまで(第2段階料金) 〃 36円60銭
上記超過(第3段階料金) 〃 40円69銭
https://www.tepco.co.jp/ep/private/plan/old01.html
リミックスポイントは1kWhが東電より8円くらい安い
### 新電力
発電と送配電は大手が担っているが、小売を新電力が参入していることが多いらしい
なるほど、マイニングには電気の知識も必要やな
modelをTextMessageではなく、TemplateMessageに変更する
公式ドキュメントを参考にする
https://developers.line.biz/en/reference/messaging-api/#imagemap-message
SDKのモデル一覧はこちら
https://github.com/line/line-bot-sdk-php/blob/master/examples/KitchenSink/src/LINEBot/KitchenSink/EventHandler/MessageHandler/TextMessageHandler.php
$template = array('type' => 'confirm', 'text' => 'テキストメッセージ。最大240文字', 'actions' => array( array('type'=>'message', 'label'=>'yes', 'text'=>'yesを押しました' ), array('type'=>'message', 'label'=>'no', 'text'=>'noを押しました' ) ) ); $message = new \LINE\Clients\MessagingApi\Model\TemplateMessage(['type' => 'template','altText' => '代替テキスト','template' => $template]); $request = new \LINE\Clients\MessagingApi\Model\ReplyMessageRequest([ 'replyToken' => $replyToken, 'messages' => [$message], ]); $response = $messagingApi->replyMessage($request);
LINE側の挙動は確認できたので、あとはMySQLのCRUDとChatGPTのレスポンスの確認
複数のメッセージを送信したい場合は、messagesを配列にする。
$message = new \LINE\Clients\MessagingApi\Model\TextMessage(['type' => 'text','text' => $message->{"text"}]); $userId = new \LINE\Clients\MessagingApi\Model\TextMessage(['type' => 'text','text' => $userId]); $request = new \LINE\Clients\MessagingApi\Model\ReplyMessageRequest([ 'replyToken' => $replyToken, 'messages' => [$message, $userId], ]); $response = $messagingApi->replyMessage($request);
1つのリクエストでreplyTokenを複数作ることはできないので、以下のようにレスポンスを複数は書けない。この場合、最初のレスポンスしか表示されない。
$message = new \LINE\Clients\MessagingApi\Model\TextMessage(['type' => 'text','text' => $message->{"text"}]); $request = new \LINE\Clients\MessagingApi\Model\ReplyMessageRequest([ 'replyToken' => $replyToken, 'messages' => [$message], ]); $response = $messagingApi->replyMessage($request); $userId = new \LINE\Clients\MessagingApi\Model\TextMessage(['type' => 'text','text' => $userId]); $request = new \LINE\Clients\MessagingApi\Model\ReplyMessageRequest([ 'replyToken' => $replyToken, 'messages' => [$userId], ]); $response = $messagingApi->replyMessage($request);
webhookイベントオブジェクトの構造を参考にUserIDを取得する
### webhookイベントオブジェクト
https://developers.line.biz/ja/reference/messaging-api/#webhook-event-objects
これを見ると、sourceのuserIdがあるので、これをキーに出来そう
{ "destination": "xxxxxxxxxx", "events": [ { "type": "message", "message": { "type": "text", "id": "14353798921116", "text": "Hello, world" }, "timestamp": 1625665242211, "source": { "type": "user", "userId": "U80696558e1aa831..." }, "replyToken": "757913772c4646b784d4b7ce46d12671", "mode": "active", "webhookEventId": "01FZ74A0TDDPYRVKNK77XKC3ZR", "deliveryContext": { "isRedelivery": false } }, { "type": "follow", "timestamp": 1625665242214, "source": { "type": "user", "userId": "Ufc729a925b3abef..." }, "replyToken": "bb173f4d9cf64aed9d408ab4e36339ad", "mode": "active", "webhookEventId": "01FZ74ASS536FW97EX38NKCZQK", "deliveryContext": { "isRedelivery": false } }, { "type": "unfollow", "timestamp": 1625665242215, "source": { "type": "user", "userId": "Ubbd4f124aee5113..." }, "mode": "active", "webhookEventId": "01FZ74B5Y0F4TNKA5SCAVKPEDM", "deliveryContext": { "isRedelivery": false } } ] }
ソースコード上ではこのように取得する
$message = $jsonObj->{"events"}[0]->{"message"}; $userID = $jsonObj->{"events"}[0]->{"source"}->{"userId"};
さあ、mysqlの構造をどうするかですね。
その前にレスポンスのバリエーションを確認したい。
LINE Messaging APIを使用した開発をやります。
$ php composer.phar require linecorp/line-bot-sdk
$ php composer.phar require guzzlehttp/guzzle
こちらでは上手くいかない
require("vendor/autoload.php"); use LINE\LINEBot\Constant\HTTPHeader; use LINE\LINEBot\HTTPClient\CurlHTTPClient; use LINE\LINEBot; $channel_access_token = 'xxxx'; $channel_secret = 'xxxx'; $http_client = new CurlHTTPClient($channel_access_token); $bot = new LINEBot($http_client, ['channelSecret' => $channel_secret]); $signature = $_SERVER['HTTP_' . HTTPHeader::LINE_SIGNATURE]; $http_request_body = file_get_contents('php://input'); $events = $bot->parseEventRequest($http_request_body, $signature); $event = $events[0]; $reply_token = $event->getReplyToken(); $reply_text = $event->getText(); $bot->replyText($reply_token, $reply_text);
Githubを見ながら少し内容を変更します。SDKのバージョンによってライブラリのclass構成が変わっているようです。
https://github.com/line/line-bot-sdk-php
replyTokenは、{“events”}[0]に入っている。line-bot-sdk-phpのsampleを見ても全然わからなかったので、凄い時間がかったw
ini_set("display_errors", 1); error_reporting(E_ALL); require("vendor/autoload.php"); $jsonString = file_get_contents('php://input'); error_log($jsonString); $jsonObj = json_decode($jsonString); $message = $jsonObj->{"events"}[0]->{"message"}; $replyToken = $jsonObj->{"events"}[0]->{"replyToken"}; $client = new \GuzzleHttp\Client(); $config = new \LINE\Clients\MessagingApi\Configuration(); $config->setAccessToken(''); $messagingApi = new \LINE\Clients\MessagingApi\Api\MessagingApiApi( client: $client, config: $config, ); $message = new \LINE\Clients\MessagingApi\Model\TextMessage(['type' => 'text','text' => $message->{"text"}]); $request = new \LINE\Clients\MessagingApi\Model\ReplyMessageRequest([ 'replyToken' => $replyToken, 'messages' => [$message], ]); $response = $messagingApi->replyMessage($request);
$ sudo apt update
### PHP
$ sudo apt install php libapache2-mod-php php-mysql
$ php -v
PHP 8.1.2-1ubuntu2.14 (cli) (built: Aug 18 2023 11:41:11) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.2, Copyright (c) Zend Technologies
with Zend OPcache v8.1.2-1ubuntu2.14, Copyright (c), by Zend Technologies
### MySQL
$ sudo apt install mysql-server
### composer.phar
$ curl -sS https://getcomposer.org/installer | php
まずGithubから bitcoincore のソースコードを clone してきます。
github上で見てもいいんですが、なんとなくローカルに落としたいですよね。。
$ git clone https://github.com/bitcoin/bitcoin.git
$ $ tree -L 3 -d
.
└── bitcoin
├── build-aux
│ └── m4
├── build_msvc
│ ├── bench_bitcoin
│ ├── bitcoin-cli
│ ├── bitcoind
│ ├── bitcoin-qt
│ ├── bitcoin-tx
│ ├── bitcoin-util
│ ├── bitcoin-wallet
│ ├── libbitcoin_cli
│ ├── libbitcoin_common
│ ├── libbitcoin_consensus
│ ├── libbitcoin_crypto
│ ├── libbitcoin_node
│ ├── libbitcoin_qt
│ ├── libbitcoin_util
│ ├── libbitcoin_wallet
│ ├── libbitcoin_wallet_tool
│ ├── libbitcoin_zmq
│ ├── libleveldb
│ ├── libminisketch
│ ├── libsecp256k1
│ ├── libtest_util
│ ├── libunivalue
│ ├── msbuild
│ ├── test_bitcoin
│ └── test_bitcoin-qt
├── ci
│ ├── lint
│ ├── retry
│ └── test
├── contrib
│ ├── completions
│ ├── debian
│ ├── devtools
│ ├── guix
│ ├── init
│ ├── linearize
│ ├── macdeploy
│ ├── message-capture
│ ├── qos
│ ├── seeds
│ ├── shell
│ ├── signet
│ ├── testgen
│ ├── tracing
│ ├── verify-binaries
│ ├── verify-commits
│ ├── windeploy
│ └── zmq
├── depends
│ ├── builders
│ ├── hosts
│ ├── packages
│ └── patches
├── doc
│ ├── design
│ ├── man
│ ├── policy
│ └── release-notes
├── share
│ ├── examples
│ ├── pixmaps
│ ├── qt
│ └── rpcauth
├── src
│ ├── bench
│ ├── common
│ ├── compat
│ ├── config
│ ├── consensus
│ ├── crc32c
│ ├── crypto
│ ├── index
│ ├── init
│ ├── interfaces
│ ├── ipc
│ ├── kernel
│ ├── leveldb
│ ├── logging
│ ├── minisketch
│ ├── node
│ ├── policy
│ ├── primitives
│ ├── qt
│ ├── rpc
│ ├── script
│ ├── secp256k1
│ ├── support
│ ├── test
│ ├── univalue
│ ├── util
│ ├── wallet
│ └── zmq
└── test
├── functional
├── fuzz
├── lint
├── sanitizer_suppressions
└── util
各ディレクトリ、各機能ごとの役割を細く見て行くことが必要ですね。
rand()は 0 から RAND_MAXまでの疑似乱数を返す。stdlib.hに定義されている。
多くのプログラムはエポックからの経過秒数を種にして使用している。
#include <stdio.h> #include <stdlib.h> int main() { int i; printf("RAND_MAX: %u\n", RAND_MAX); srand(time(0)); printf("0からRAND_MAXまでの乱数値\n"); for(i=0; i< 8; i++) printf("%d\n", rand()); printf("0から20までの乱数値\n"); for(i=0; i< 8; i++) printf("%d\n", (rand()%20)+1); return 0; }
$ ./a.out
RAND_MAX: 2147483647
0からRAND_MAXまでの乱数値
1059493860
583633074
1632571078
678819775
1658879329
1703267400
1565774963
996314262
0から20までの乱数値
13
4
2
13
13
7
11
18