ラズパイからLINEへメッセージとステッカーを送る part2 ステッカーをランダムに取出す

シェアする

Pocket

久々のラズパイネタです。

以前、ラズパイから LINE へメッセージ及びステッカーを送れるという記事を載せました。

調べてみると、その記事は、2017年7月22日にアップしたんですが、内容が陳腐だったので、少し手を入れて見やすくしました。

それを行った際に、これを使って何かをしてみようと思い立ちました。

1.仕事の終了10分前に LINE にメッセージ送付

60爺は、未だに毎日お仕事をさせていただいております。時間は、9時開始、17時20分終了です。そこで、仕事の終了10分前に、この機能を使用してメッセージとステッカーを送ることにしました。

これだけでは、単純に curl コマンドを書けば終わってしまうのであまり面白くありません。色々考えていたら、LINE Engineering BLOG の記事のここに目が行きました。

※送信できるStickerは、documentにも記載してありますがMessaging APIと同じものになっています。

そこで、このページを見ていくと、Sticker一覧を見つけました。

かなりの量のステッカーがあり、これを利用できることがわかりました。

そこで、メッセージを送る前に、乱数を発生させて、その日送付するステッカーを決定することにしました。これならば、単純に curl 文を書くだけでないので、ちょっとした暇つぶしになると思います。

2.python プログラム作成

さて、python プログラムを作成します。しかし、このところ、python プログラムに全く触れていなかったため、一から作成するのに非常に苦労しました。

プログラムは、次の手順を踏みます。

乱数発生 ⇒ ステッカーID決定 ⇒ curl コマンド生成  ⇒ curl コマンド発行

そうそう、乱数発生の前に、日付から、曜日が土日か判断して、その場合はプログラムを終了させます。何たって、週休2日制ですので。

① 乱数発生

先ほどの Sticker一覧をみて、STKID を洗い出しました。この STKID ですが、1から始まり、632 で終わります。このため、乱数は 632 まで発生させます。

② ステッカーID決定

さて、Sticker に付いている STKID なんですが、632 個あるわけではありません。即ち、欠号が結構あります。そのため、乱数がその番号を取り出した場合は、却下して再度乱数を発生させて、有効なステッカー番号を取るまで繰り返しを行います。

調べたところ、ステッカーには次の範囲の番号が存在します。有効な個数は344個ですね。

 1 ~ 47、100 ~ 307、401 ~ 430、501 ~ 527、601 ~ 632

③ curl コマンド生成

STKID が決まったら、この番号を curl コマンドに指定できるようにします。

④ curl コマンド発行

最後に、curl コマンドを発行します。subprocess.call で実施する予定です。

3.コマンド発行テスト お決まりのエラー対応!

何で 60爺がプログラムを作ると問題が起こるのでしょうか?まア、余り素直に動いても面白くないんですが、半日で終わりかなと思っていたのに2日も時間を取られてしまいました。

記録を残しますので、ご覧ください。

① ステッカーはパッケージ識別子も必要

以下のコマンドに対して、Invalid stickerId なるエラーが発生しました。

curl -X POST https://notify-api.ization: Bearer アクセストークン" -F "message=あと10 分で、終了時間です!" -F "stickerPackageId=1" -F "stickerId=29"
{"status":400,"message":"Invalid stickerId."}

最初、何を言っているのかわからなかったのですが、Sticker識別子の他にパッケージ識別子が存在(先ほどのステッカー一覧を参照)しており、これが誤っていました。

stickerPackageId を2にすると正しく動作しました。

うーーん!stickerPackageId=1 にしておけば動くと思っていましたが甘かったようです。 Sticker一覧を見直したところ、1以外が入る場合があることがわかりました。

調査したところ、パッケージ識別子とSticker識別子の関係は以下のとおりです。

  • 識別子1 1 ~ 17、21、100 ~ 139、401 ~ 430
  • 識別子2 18 ~ 20、22 ~ 47、140 ~ 179、501 ~ 527
  • 識別子3 189 ~ 259
  • 識別子4 260 ~ 307、601 ~ 632

② subprocess.callでエラー発生

さて、上記の2つの識別子の取り込みを終わり、curlコマンドの組み立ても完了し、コマンド発行をしたところ、うまくいかずエラーが発生です。

{"status":401,"message":"Missing authorization header"}curl: (6) Could not resolve host: Bearer
curl: (6) Could not resolve host: アクセストークン"
curl: (6) Could not resolve host: xn--!"-n13a4oicb0905cz3fdj3cicycr51c

実際、作成したcurl文はこれです。このcurlコマンドだけを切り取って流すと正常に流れます!!

curl -X POST https://notify-api.line.me/api/notify -H 'Authorization: Bearer vWjkChWETa5qPezWZr09KzWa520rlaxpCfyQKqEMUF4' -F 'message=あと10 分で、終了時間です !' -F 'stickerPackageId=1' -F 'stickerId=125'

上記、401のエラーを検索したところ、以下の解決法が出ています。 これですが、シングルクォーテーションではなくダブルクォーテーションで囲むと解決したので、試してみてください。

しかし、以下のように、シングルクォーテーションではなくダブルクォーテーションに変更しても、エラーは全く同じでした。

curl -X POST https://notify-api.line.me/api/notify -H "Authorization: Bearer アクセストークン" -F "message=あと10 分で、終了時間です !" -F "stickerPackageId=1" -F "stickerId=10"{"status":401,"message":"Missing authorization header"}curl: (6) Could not resolve host: Bearer
curl: (6) Could not resolve host: アクセストークン"
curl: (6) Could not resolve host: xn--!"-n13a4oicb0905cz3fdj3cicycr51c

③ シェルで対応しようとしたが、・・・・

訳の分からんエラーで先に進めないので、シェルで出来ないか可能性を探りました。しかし、・・・。

#!/bin/shPackageId=`expr $1`
stickerId=`expr $2`curl -X POST https://notify-api.line.me/api/notify -H 'Authorization: Bearer vWjkChWETa5qPezWZr09KzWa520rlaxpCfyQKqEMUF4' -F 'message=test' -F 'stickerPackageId=${PackageId}' -F 'stickerId=${stickerId}'./q.sh 1 109
{"status":400,"message":"StickerPackageId must be number value."}

StickerPackageIdは、数値にしろなんて言われました。調べると、シェルの引数は文字列なんですね。文字列を数字にできないか格闘しましたが、これも諦めました。

4.os関数を使用したら解決

結局、pythonのプログラムに戻り、subprocess.callの代わりに、os.systemを使用したら、あっさりと解決し、コマンド発行も無事終わりました。

完成です。

あとは、祭日も土日と同じようにするとか考えられますが、ひとまず、crontabで17時10分に、このプログラムを起動するようにしました。

5.プログラム公開

最後に、稚拙ですがプログラムを公開します。

import random
import os
import datetime
import sys
#import subprocessdef rdm_return():#ステッカーNo.取得

    rdm = random.randrange(632) #乱数発生
    if rdm >= 1 and rdm <= 47 : pass
       elif rdm >= 100 and rdm <= 307 : pass
       elif rdm >= 401 and rdm <= 430 : pass
       elif rdm >= 501 and rdm <= 527 : pass
       elif rdm >= 601 and rdm <= 632 :
           pass
    else:
           rdm = 0    return(rdm)def STKPKGID_return(STKID):
#ステッカーID取得
    STKPKGID = 1
    if STKID >= 1 and STKID <= 17      : pass
    elif STKID == 21                   : pass
    elif STKID >= 100 and STKID <= 139 : pass
    elif STKID >= 401 and STKID <= 430 :
        pass
    elif STKID >= 189 and STKID <= 259 :
        STKPKGID = 3

    elif STKID >= 260 and STKID <= 307 :
        STKPKGID = 4
    elif STKID >= 601 and STKID <= 632 :
        STKPKGID = 4
    else
        STKPKGID = 2
    return(STKPKGID)

#プログラム開始

today = datetime.date.today() # 現在の日付を取得
if today.weekday() == 5 or today.weekday() == 6 :
   sys.exit()

sticker_no = 0
while sticker_no == 0 :
   sticker_no = rdm_return()
   print(sticker_no)sticker_id = STKPKGID_return(sticker_no)

# コマンド作成
#cmd1 = "curl -X POST https://notify-api.line.me/api/notify -H 'Authorization: Bearer アクセストークン' -F 'message=あと10 分で、終了時間です!' -F 'stickerPackageId="
cmd1 = 'curl -X POST https://notify-api.line.me/api/notify -H "Authorization: Bearer アクセストークン" -F "message=あと10 分で、終了 時間です!" -F "stickerPackageId='
cmd2 = '" -F "stickerId='
cmd3 = '"'
cmd = cmd1 + str(sticker_id) + cmd2 + str(sticker_no) + cmd3

# コマンド発行
#subprocess.call(cmd.split())
os.system(cmd)
print(cmd)
スポンサーリンク

シェアする

フォローする