信頼はずっと、挑戦はもっと。

お問い合わせ
TEL:03-3496-3888

BLOG コアテックの社員ブログ (毎週月曜~金曜更新中)

LIST OF ARTICLES

記事一覧

  • テクログ

    Lambdaを試してみました

    お久しぶりです。在宅勤務になり、時間に余裕ができたのでAWSを色々試していました。今回はLambdaについて紹介したいと思います。処理の内容はS3のimagesにjpgの画像をアップすると、別のバケットにリサイズされた画像がアップされ、画像のアップロードパスと登録日時がdynamoDBに登録されます。まず、Lambda上でPillowを使えるようにするために、EC2で下記を実行しました。sudo yum -y install gcc openssl-devel bzip2-devel libffi-devel wget https://www.python.org/ftp/python/3.8.1/Python-3.8.1.tgz tar xzf Python-3.8.1.tgz cd Python-3.8.1 sudo ./configure --enable-optimizations sudo make altinstall pip3.8 install pillow -t . 上記で作成されたPILとPillow.libsとPillow-7.1.2.dist-infoとlambda_function.pyをzipで固めてアップロードします。次にLambdaのトリガーの設定ですが、S3を選択し、下記内容を入力し、追加をクリックします。バケット sample イベントタイプ すべてのオブジェクト作成イベント プレフィックス-オプション images/ サフィックス-オプション .jpg トリガーの有効化 チェック 次にdynamoDBで画像管理テーブルとautoincrementがないためidを管理するテーブルを作成します。テーブルを作成後、idsテーブルにtable_nameがs3_images、idが0を登録します。・s3_images id 主キー   数値型 upload_path 文字列型 created_at  文字列型 ・ids table_name 主キー 文字列型 id                数値型 次にS3で下記の二つのバケットを作成します。sample sample-resize 最後にlambda_function.pyは下記の内容です。import boto3 import os import sys import uuid from urllib.parse import unquote_plus from PIL import Image import PIL.Image import datetime s3_client = boto3.client('s3') dynamodb = boto3.resource('dynamodb') def resize_image(image_path, resized_path):   with Image.open(image_path) as image:     image.thumbnail(tuple(x / 2 for x in image.size))     image.save(resized_path) def get_id(table_name):   table = dynamodb.Table('ids')   data = table.update_item(     Key = {       'table_name': table_name     },     UpdateExpression = 'ADD id :id_val',     ExpressionAttributeValues = {       ':id_val': 1     },     ReturnValues = "UPDATED_NEW"   )       res = table.get_item(     Key = {       'table_name': table_name     }   )   return res['Item']['id'] def insert_dynamodb(id, upload_path):   table= dynamodb.Table('s3_images')   now = datetime.datetime.now()   table.put_item(     Item = {       'id': id,       'upload_path': upload_path,       'created_at': now.strftime("%Y-%m-%d %H:%M:%S")     }   ) def lambda_handler(event, context):   for record in event['Records']:     bucket = record['s3']['bucket']['name']     key = unquote_plus(record['s3']['object']['key'])     tmpkey = key.replace('/', '')     download_path = '/tmp/{}{}'.format(uuid.uuid4(), tmpkey)     upload_path = '/tmp/resized-{}'.format(tmpkey)     s3_client.download_file(bucket, key, download_path)     resize_image(download_path, upload_path)     s3_client.upload_file(upload_path, '{}-resized'.format(bucket), key)           id = get_id('s3_images')     insert_dynamodb(id, upload_path) これでS3のsampleバケットのimagesにjpgの画像をアップすると、sample-resizeバケットにリサイズされた画像がアップされます。Lambdaの設定は一部割愛しましたが、以上となります。
  • テクログ

    LINE Notify APIを試してみました

    初めまして。1月からお世話になっておりますJGです。最近LINE Notify APIを使い、毎朝自分のLINEに通知させました。それについて触れたいと思います。下記URLからLineIDでログインし、必要事項を入力します。その後、アクセストークン発行をクリックし、発行されたトークンをコピーして保存してください。https://notify-bot.line.me/ja/天気予報を取得する処理は下記のlivedoorを使用しました。http://weather.livedoor.com/weather_hacks/webservicePHPで処理を書き、作成したものをHerokuに上げ、毎朝通知するようにHerokuのスケジューラを設定しました。下記ソースのTOKENに、LINEのアクセストークンを指定すれば動きます。自分の住んでいる東京と出身地の神奈川の天気を通知するために、$city_listを下記のように指定しています。興味がある方は、是非試してみてください。<?php define('TOKEN', ''); define('MESSAGE_NOTIFY_API_URL', 'https://notify-api.line.me/api/notify'); define('WEATHER_API_URL', 'http://weather.livedoor.com/forecast/webservice/json/v1?city='); $city_list = [   130010,   140010,   140020 ]; foreach ($city_list as $city) {   //天気予報を取得   $weather_data = get_weather_data($city);   if (empty($weather_data)) {     $msg = "天気予報取得失敗です。";   } else {     //通知メッセージを作成     $msg = create_message($weather_data);   }   //通知   send_msg($msg); }   function get_weather_data($city) {   $ch = curl_init();   curl_setopt($ch, CURLOPT_URL, WEATHER_API_URL.$city);   curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');   curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);   $response = curl_exec($ch);   $http_code = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);   if ($http_code != 200) {     return false;   }   if (curl_error($ch)) {     return false;   }   $weather_data = json_decode($response, true);   curl_close($ch);   return $weather_data; } function create_message($arr) {   $msg = '';   $title = $arr['title'] ?? '';   $msg .= $title."\n\n";   for ($i = 0; $i < 2; $i++) {     $date = $arr['forecasts'][$i]['date'] ?? '';     $date_label = $arr['forecasts'][$i]['dateLabel'] ?? '';     $weather = $arr['forecasts'][$i]['image']['title'] ?? '';     $min = $arr['forecasts'][$i]['temperature']['min']['celsius'] ?? '';     $max = $arr['forecasts'][$i]['temperature']['max']['celsius'] ?? '';     $msg .= $date_label.'('.$date.')'."\n";     $msg .= '天気: '.$weather."\n";     $msg .= '最高気温: '.$max."\n";     $msg .= '最低気温: '.$min;     if ($i < 1) {       $msg .= "\n\n";     }   }   return $msg; } function send_msg($msg) {   $post_data = http_build_query(['message' => $msg]);   $ch = curl_init(MESSAGE_NOTIFY_API_URL);   curl_setopt($ch, CURLOPT_POST, true);   curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);   curl_setopt($ch, CURLOPT_HTTPHEADER, [     'Content-Type: application/x-www-form-urlencoded',     'Authorization: Bearer '.TOKEN,     'Content-Length: '.strlen($post_data)   ]);   curl_exec($ch);   $http_code = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);   if ($http_code != 200) {     return false;   }   if (curl_error($ch)) {     return false;   }   curl_close($ch);   return true; }