もがき系プログラマの日常

もがき系エンジニアの勉強したこと、日常のこと、気になっている技術、備忘録などを紹介するブログです。

LineのPushMessageをFlexMessageで簡単に送りたい

はじめに

こんばんは。

お仕事で LineのPushMessageを使うことがありました。

当然普通のテキストではなく、 FlexMessageです。

LineのDeveloperサイトではFlexMessageSimulatorというのがあるので、簡単じゃんと思ってました。

ただ、LineのDeveloperサイトで紹介されている PHPの公式SDKだと、せっかくSimulatorで組み立てたjsonなりyamlなりを展開して使わないといけないみたいです... (もしかしたら自分の調べが足りなくて、そういうメソッドあるのかも?)

github.com

できれば、 Simulatorで組み立てたjsonなりyamlをそのままペタっと貼り付けて使いたい。

ということでつくりました。

本題

作ったのは、以下です。

github.com

といっても、めんどくさかったので、Json型しかサポートしてません...

ReadMeに書いてる通り、MessageBuilderJsonを implementsしたclassを作成して以下のように呼び出せばOK

<?php

$message        = new ExampleMessageBuilder();
$pushMessage    = new PushMessage($channelAccessToken);
$pushMessage->execute($to, new MessageBuilder($message));

getContents はstring型を返せばいいだけので、 jsonは別ファイルにして return file_get_contents('./output.json'); とかでもありだと思います。

終わりに

公式のSDKは他のAPIもガッツリサポートされてるので、その兼ね合いで、自分が作ったやつみたいに雑に使えないのかな?とも思いました。

まぁそんな感じで、雑にpushMessage送りたい場合は簡単かと思います。

現場からは以上です。

Laravelの日付ミューテタで適用されるCarbonをCarbonImmutableに変更する

はじめに

こんばんは。

超簡単なものですが、調べて出来たので残しておきます。

Laravelの日付ミューテタは、Eloquentの dates プロパティにセットされたカラムを対象に、DBから取得したさいに文字列ではなく、 Illuminate\Support\Carbon として取得してくれます。

ちなみに created_at updated_atdates に記述しなくてもLaravelの方で勝手に Carbonクラスに変更してくれます。

Image from Gyazo

しかしこの Illuminate\Support\Carbon は Immutable版ではないです。

なので、 こちらの記事 で紹介されているようなミスが起きてしまいます。

toImmutable() とかで Immutableに変更できますが、面倒です。

日付ミューテタ全体的に CarbonImmutableに変更したいです。

本題

というわけで以下の一文を AppServiceProvider に追加します。

    public function register()
    {
        DateFactory::use(CarbonImmutable::class);
    }

おしまいです。

tinkerで試してみます。

Image from Gyazo

Immutableに変わってます。

終わり

こんな感じで内容の薄い記事でした。

Laravel楽しいです。

もうちょい使いこなせるようにがんばります。

あと、全く関係ないんですが、GyazoをGifを、はてなブログMarkdownで貼り付けたいときは、ここやればいいんですね。 Gyazo課金勢なのでバンバン使ってます。

f:id:kojirooooocks:20190915230947p:plain

現場からは以上です。

Effective DevOpsオンライン輪読会Vol.14レポート

はじめに

challenge-every-month の Slack メンバーで 「Effective DevOps」のオンライン輪読会を行っています!

今回は輪読会 Vol.14でした。

Effective DevOps ―4本柱による持続可能な組織文化の育て方

Effective DevOps ―4本柱による持続可能な組織文化の育て方

過去のレポート

Vol.1

kojirooooocks.hatenablog.com

Vol.2

sadayoshi-tada.hatenablog.com

Vol.3

kojirooooocks.hatenablog.com

Vol.4

kdnakt.hatenablog.com

Vol.5

kdnakt.hatenablog.com

Vol.6

sadayoshi-tada.hatenablog.com

Vol.7

kojirooooocks.hatenablog.com

Vol.8

kdnakt.hatenablog.com

Vol.9

kdnakt.hatenablog.com

Vol.10

sadayoshi-tada.hatenablog.com

Vol.11

kojirooooocks.hatenablog.com

Vol.12

sadayoshi-tada.hatenablog.com

Vol.13

kdnakt.hatenablog.com

担当した章

今回の担当章は 第17章 devops文化への架け橋:ストーリーから学ぶ です。

資料

感想

小さな成功などフィアレスチェンジに通じるところがありました。

また、カイゼン・ジャーニーを読んでいたときに知った Working Agreementに通じるところもありました。

「この知識はこういう場面でも有効なんだなぁ」

と、他の本で得た知識が更に強固になっていく感じがして、2度美味しかったです。

そして、どんなにレベルが低くても、常に成長思考な人でありたいと心から思いました。

次回

@tada さんの担当です。

現場からは以上です。

elasticbeanstalk に振り回された一日だった

はじめに

こんばんは。 今日は仕事を終わらした後、輪読会の本を読んで、資料を作ってみたいなことをやろうと思ってたら、いまお仕事を頂いている会社のjenkinsがぶっ壊れたということだったので、それの復旧で体力を使ってしまい何もやる気が起きなくなりました...

とりあえず、悩んだことを備忘録として書き残しておきます。

EBのことはほぼほぼわかってないので、雰囲気でやりました。

まず、前提として、今までのデプロイは、jenkins -> eb deploy というフローをとっており、そのjenkinsがぶっ壊れてしまったのでデプロイができないという状況でした。

社内でjenkinsの面倒をみれる方が退職していらっしゃらないようだったので、 jenkinsからebを叩くというフローを、circleCIから ebを叩くというフローに変更しました。

本題

1. circleCIでawsコマンドを叩くためインストールしたい

直接installしました。 imageとかあるのかな...?

    steps:
      - run: sudo apt update
      - run: sudo apt install -y python-pip python-dev
      - run: sudo pip install awsebcli

2. gdライブラリをインストールしたい

デプロイしたいレポジトリで phpspreadsheet を使ってるのでGDが必要なのでinstallしました。

packagist.org

    steps:
      - run: sudo apt-get install -y libpng-dev libjpeg-dev libwebp-dev
      - run: sudo docker-php-ext-configure gd --with-jpeg-dir=/usr/lib/x86_64-linux-gnu/ --with-webp-dir==/usr/lib/x86_64-linux-gnu/
      - run: sudo docker-php-ext-install gd

3. composerから落としてきたライブラリ群も一緒にデプロイしたい

eb deployは git archive されたzipファイルをアップロードするので、 composerから落としてきたファイル群は含まれません。

circleCI上にcheckoutしてきたレポジトリで、一回 git commitまですれば git archive に含まれます。

ただ、基本的に vendors とかはignore設定されていると思うので、無理やり外しちゃいます。

commit logは直前のcommit logを適用します。

    steps:
      - run: composer install --no-dev -n --prefer-dist
      - run: sed -i -e "s/vendors//g" .gitignore
      - run: git config user.email "xxxxxxxxxx@gmail.com"
      - run: git config user.name "zzzzzzzzzz"
      - run: git add .
      - run: git log --pretty=format:"%h - %an, %ar %s" -n 1 | xargs -ICOMMIT_LOG git commit -m COMMIT_LOG

ただ、こんなことをしなくても 以下のようにやればもっとスマートに出来そうでした。

stackoverflow.com

やってる時点で、「こんなムリヤリしなければいけないのはおかしいな」と思ってたのですが、案の定別のやり方がありました。awsむずかしい...

4. StagingにあげたものをProductionにあげたい

環境変数で切り分けているので、StagingにあげたバージョンをそのままProductionに適用したいのですが、そのまま eb deploy とかしちゃうと別バージョンで作られちゃいます。

--version を指定できればやりたいことが叶うので今回も無理やりました。

    steps:
      - run: eb status staging | grep "Deployed Version" | cut -d" " -f5 > app_version
      - run: cat app_version | xargs -IAPP_VERSION eb deploy product --version APP_VERSION

5. PRマージされたらStagingにデプロイしたい

workflows:
  version: 2
  build:
    jobs:
      - staging_deploy:
          filters:
            branches:
              only: develop

6. リリースタグ切られたらProductionにデプロイしたい

workflows:
  version: 2
  build:
    jobs:
      - production_deploy:
          filters:
            tags:
              only: /^release-.*/
            branches:
              ignore: /.*/

終わりに

今までCircleCIもAWSもすごく雰囲気でやっちゃってましたので、疲れました。

無理やり頑張ったので、もっとシンプルにわかりやすく書くとどうなるかが知りたいです。

現場からは以上です。

Laravelの配列のvalidation定義にちょっとハマった

はじめに

Laravelのリクエストで配列が送られてくる場合のvalidationを書いてたときに、意外とハマったのでめちゃめちゃ簡単ですが残しときます。

本題

1. 空でも良いから配列のパラメータとして送られてほしい

'items' => 'present|array',

2. 配列のパラメータで必ず何かが入っててほしい

'items' => 'required|array',

3. 配列のパラメータで要素数が3つ入っててほしい

'items' => 'required|array|size:3',

4. 配列のパラメータで要素数が3つ以上入っててほしい

'items' => 'required|array|min:3',

5. 配列のパラメータで要素数が2つ〜4つ入っててほしい

'items' => 'required|array|between:2,4',

6. 配列のパラメータで指定の要素が入っててほしい

'items'   => 'required|array',
'items.*' => Rule::in(['item1', 'item2', 'item3', 'item4', 'item5']),

7. 配列のパラメータで空配列もしくは、指定の要素が入っててほしい

'items'   => 'present|array',
'items.*' => Rule::in(['item1', 'item2', 'item3', 'item4', 'item5']),

終わりに

自分がハマってたのは、7番でした。

配列で決められたものを送られてほしいけど、空配列は許すっていうのを調べてました。

簡単ですが現場からは以上です。

phpでGoogleCalendarAPIを使って祝日の情報を取得する

はじめに

こんばんは。

もうコレ関連やるたびに毎回ググって時間かかっちゃうので、まとめときます。

GoogleのDeveloperサイトで、GoogleCalendarAPIのサービスの使用を許可しているのが前提です。

本題

1. 必要パッケージのインストール

以下を落としてきます。

packagist.org

composer require google/apiclient

2. 使用するクラス群

GoogleCalendarConfig.php

<?php


namespace Kojirock\Resource;

class GoogleCalendarConfig
{
    /**
     * @var string
     */
    private $authConfigPath;

    /**
     * @var string
     */
    private $calendarId;

    /**
     * GoogleCalendarConfig constructor.
     * @param array $configData
     */
    public function __construct(array $configData)
    {
        foreach ($this as $key => $val) {
            if (!isset($configData[$key])) {
                throw new \InvalidArgumentException("{$key} is property nothing");
            }
            $this->$key = $configData[$key];
        }
    }

    /**
     * @return string
     */
    public function getAuthConfigPath()
    {
        return $this->authConfigPath;
    }

    /**
     * @return string
     */
    public function getCalendarId()
    {
        return $this->calendarId;
    }
}

GoogleCalendar.php

<?php


namespace Kojirock\Infrastructure\Adapter\Google;

use Kojirock\Resource\GoogleCalendarConfig;

class GoogleCalendar
{
    /**
     * @var GoogleCalendarConfig
     */
    private $googleCalendarConfig;

    /**
     * GoogleCalendar constructor.
     * @param GoogleCalendarConfig $googleCalendarConfig
     */
    public function __construct(GoogleCalendarConfig $googleCalendarConfig)
    {
        $this->googleCalendarConfig = $googleCalendarConfig;
    }

    /**
     * @return \Google_Service_Calendar
     * @throws \Google_Exception
     */
    public function createInstanceGoogleCalendarService()
    {
        $client = new \Google_Client();
        $client->setAuthConfig($this->googleCalendarConfig->getAuthConfigPath());
        $client->setScopes(\Google_Service_Calendar::CALENDAR_EVENTS_READONLY);
        return new \Google_Service_Calendar($client);
    }

    /**
     * 祝日データを取得する
     * @param string $startDate
     * @param string $endDate
     * @return array
     * @throws \Google_Exception
     */
    public function fetchHolidays($startDate, $endDate)
    {
        $service  = $this->createInstanceGoogleCalendarService();
        $response = $service->events->listEvents($this->googleCalendarConfig->getCalendarId(), [
            'timeMin'      => $startDate,
            'timeMax'      => $endDate,
            'singleEvents' => true,
            'orderBy'      => 'startTime',
            'timeZone'     => 'Asia/Tokyo',
        ]);

        $results = [];
        foreach ($response->getItems() as $k => $item) {
            $results[$item->getStart()->getDate()] = $item->getSummary();
        }

        return $results;
    }
}

execute.php

<?php

$googleCalendarConfig = new \Kojirock\Resource\GoogleCalendarConfig([
    'authConfigPath' => 'DeveloperサイトからDLしてきたJsonファイルまでのパス',
    'calendarId'     => 'ja.japanese#holiday@group.v.calendar.google.com',
]);

$googleCalendar = new \Kojirock\Infrastructure\Adapter\Google\GoogleCalendar($googleCalendarConfig);

// 例えば、今月から1年先の祝日データを取得する
$startDate = \Carbon\Carbon::now()->startOfMonth()->format('c');
$endDate   = \Carbon\Carbon::now()->startOfMonth()->addYear(1)->format('c');
$holidays  = $googleCalendar->fetchHolidays($startDate, $endDate);
var_dump($holidays);

実行結果

array(22) {
  '2019-08-11' =>
  string(9) "山の日"
  '2019-08-12' =>
  string(22) "山の日 振替休日"
  '2019-09-16' =>
  string(12) "敬老の日"
  '2019-09-23' =>
  string(12) "秋分の日"
  '2019-10-14' =>
  string(12) "体育の日"
  '2019-10-22' =>
  string(39) "即位礼正殿の儀の行われる日"
  '2019-11-03' =>
  string(12) "文化の日"
  '2019-11-04' =>
  string(25) "文化の日 振替休日"
  '2019-11-23' =>
  string(18) "勤労感謝の日"
  '2020-01-01' =>
  string(6) "元日"
  '2020-01-13' =>
  string(12) "成人の日"
  '2020-02-11' =>
  string(18) "建国記念の日"
  '2020-02-23' =>
  string(15) "天皇誕生日"
  '2020-02-24' =>
  string(28) "天皇誕生日 振替休日"
  '2020-03-20' =>
  string(12) "春分の日"
  '2020-04-29' =>
  string(12) "昭和の日"
  '2020-05-03' =>
  string(15) "憲法記念日"
  '2020-05-04' =>
  string(15) "みどりの日"
  '2020-05-05' =>
  string(15) "こどもの日"
  '2020-05-06' =>
  string(28) "憲法記念日 振替休日"
  '2020-07-23' =>
  string(9) "海の日"
  '2020-07-24' =>
  string(12) "体育の日"
}

終わりに

こんな感じ祝日データをとってきました。

GoogleCalendarAPIを使って祝日とってくる作業って、記憶に残ってるだけで4回目くらいだったのに、それでも毎回忘れてるのでコードそのまま残しときました。

↓を見る限り、一日100万回の制限があるっぽいんですが、バッチとかで1日1回取得して、RedisとかにキャッシュしとけばOKかなとか思います。

developers.google.com

現場からは以上です。

Effective DevOpsオンライン輪読会Vol.11レポート

はじめに

challenge-every-month の Slack メンバーで 「Effective DevOps」のオンライン輪読会を行っています!

今回は輪読会 Vol.11でした。

Effective DevOps ―4本柱による持続可能な組織文化の育て方

Effective DevOps ―4本柱による持続可能な組織文化の育て方

過去のレポート

Vol.1

kojirooooocks.hatenablog.com

Vol.2

sadayoshi-tada.hatenablog.com

Vol.3

kojirooooocks.hatenablog.com

Vol.4

kdnakt.hatenablog.com

Vol.5

kdnakt.hatenablog.com

Vol.6

sadayoshi-tada.hatenablog.com

Vol.7

kojirooooocks.hatenablog.com

Vol.8

kdnakt.hatenablog.com

Vol.9

kdnakt.hatenablog.com

Vol.10

sadayoshi-tada.hatenablog.com

担当した章

今回の担当章は 第14章 スケーリングの 14.7.1 チームの成長:スケーリングとしての採用 です。

資料

感想

社員の定着というところが主な話でした。

定着させるための方法など諸々書かれておりました。

次回

@tada さんの担当です。

ただ、自分が今体調が悪く、もしかしたらリスケさせて貰う可能性があります...

毎回すいません。。。

現場からは以上です。