    001/*
    002 * Copyright (c) 2009 The openGion Project.
    003 *
    004 * Licensed under the Apache License, Version 2.0 (the "License");
    005 * you may not use this file except in compliance with the License.
    006 * You may obtain a copy of the License at
    007 *
    008 *     http://www.apache.org/licenses/LICENSE-2.0
    009 *
    010 * Unless required by applicable law or agreed to in writing, software
    011 * distributed under the License is distributed on an "AS IS" BASIS,
    012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
    013 * either express or implied. See the License for the specific language
    014 * governing permissions and limitations under the License.
    015 */
    016package org.opengion.fukurou.util;
    017
    018import org.opengion.fukurou.system.OgRuntimeException ;
    019
    020import java.io.OutputStream;
    021import java.io.BufferedWriter;
    022import java.io.OutputStreamWriter;
    023import java.net.HttpURLConnection;
    024import java.net.URL;
    025import java.net.Proxy;
    026import java.net.InetSocketAddress;
    027import java.net.URLEncoder;
    028
    029/**
    030 * LineNotify は、Line Notify を利用してLineﾒｯｾｰｼﾞを送信します。
    031 *
    032 *　《手順》
    033 *　　１．https://notify-bot.line.me/ja/　からログインして
    034 *　　　　マイページから「アクセストークンを発行」をクリック
    035 *　　２．トークンを設定する。
    036 *
    037 * <pre>
    038 * Usage: java org.opengion.fukurou.util.LineNotify -token アクセストークン -message メッセージ -stickerPackageId 4 -stickerId 614
    039 * </pre>
    040 *
    041 *　《SystemのProxy設定を使用》
    042 *　java 起動時に、-Djava.net.useSystemProxies=true　を指定する。
    043 *　プログラム内で設定済みです。
    044 *
    045 * @og.rev 7.2.6.2 (2020/07/22) 新規作成
    046 *
    047 * @version  7.2
    048 * @author   Kazuhiko Hasegawa
    049 * @since    JDK11.0,
    050 */
    051public class LineNotify {
    052        private final String token;
    053        private final Proxy  proxy;
    054
    055        private String  stmpPkg ;
    056        private String  stmpId ;
    057
    058        /**
    059         * アクセストークンを指定した、コンストラクター
    060         *
    061         * Proxyは、java.net.useSystemProxies=true 設定を使用します。
    062         *
    063         * @param       token   アクセストークン
    064         */
    065        public LineNotify( final String token ) {
    066                this.token = token;
    067                this.proxy = null;
    068
    069                System.setProperty("java.net.useSystemProxies","true");         // Proxyの自動設定
    070        }
    071
    072        /**
    073         * アクセストークンを指定した、コンストラクター
    074         *
    075         * Proxyが、nullか、ゼロ文字列の場合は、Proxy.NO_PROXY を指定します。
    076         * そうでない場合は、アドレス:ポート形式で指定します。
    077         *
    078         *
    079         * @param       token   アクセストークン(Line Notifyで取得したID)
    080         * @param       proxy   アドレス:ポート形式で指定します。
    081         */
    082        public LineNotify( final String token,final String proxy ) {
    083                this.token = token;
    084                if( proxy == null || proxy.isEmpty() ) {
    085                        this.proxy = Proxy.NO_PROXY;
    086                }
    087                else {
    088                        final int ad = proxy.indexOf( ':' );
    089                        final String adrs = proxy.substring( 0,ad );
    090                        final int    port = Integer.parseInt( proxy.substring( ad+1 ) );
    091
    092                        this.proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(adrs, port));
    093                }
    094        }
    095
    096        /**
    097         * スタンプ（スティッカー）を指定します。
    098         *
    099         * 指定は、パッケージIDとIDの両方とも必要です。
    100         *
    101         * @param       stmpPkg stickerPackageIdを指定します。
    102         * @param       stmpId  stickerIdを指定します。
    103         */
    104        public void setStamp( final String stmpPkg , final String stmpId ) {
    105                this.stmpPkg = stmpPkg;
    106                this.stmpId  = stmpId ;
    107        }
    108
    109        /**
    110         * メッセージを送信します。
    111         *
    112         * 送信は、コネクションを毎回disconnectします。
    113         *
    114         * @param       message 送信するメッセージ
    115         */
    116        public void notify( final String message ) {
    117                HttpURLConnection connection = null;
    118                try {
    119                        final URL url = new URL( "https://notify-api.line.me/api/notify" );
    120                        if( proxy == null ) {
    121                                connection = (HttpURLConnection) url.openConnection();
    122                        }
    123                        else {
    124                                connection = (HttpURLConnection) url.openConnection(proxy);
    125                        }
    126                        connection.setDoOutput( true );                         // POST可能にする
    127                        connection.setDoInput( true );                          // getResponseCode を取得するため
    128                        connection.setRequestMethod( "POST" );
    129                        connection.addRequestProperty( "Authorization", "Bearer " + token );
    130                        connection.setConnectTimeout( 10*1000 );        // 10秒でタイムアウト
    131
    132                        try( OutputStream os = connection.getOutputStream();
    133                                 final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8")) ) {
    134
    135//                              writer.append( "message=" ).append( message );
    136                                writer.append( "message=" ).append( URLEncoder.encode(message, "UTF-8") );
    137                                if( !StringUtil.isNull( stmpPkg,stmpId ) ) {
    138                                        writer.append( "&stickerPackageId=" ).append( stmpPkg );
    139                                        writer.append( "&stickerId="        ).append( stmpId  );
    140                                }
    141                                writer.flush();
    142
    143
    144                                final int status = connection.getResponseCode();
    145                                if( status != HttpURLConnection.HTTP_OK ) {
    146                                        final String errMsg = HttpConnect.code2Message( status );
    147                                        throw new OgRuntimeException( errMsg );
    148                                }
    149                        }
    150                }
    151                catch( final Throwable th ) {
    152                        throw new OgRuntimeException( th );
    153                }
    154                finally {
    155                        if( connection != null ) {
    156                                connection.disconnect();
    157                        }
    158                }
    159        }
    160
    161        /**
    162         * サンプル実行用のメインメソッド。
    163         *
    164         * @param       args    コマンド引数配列。
    165         */
    166        public static void main( final String[] args ) {
    167                String token   = "XXXX";
    168                String message = "テスト";
    169                String stmpPkg = "4";
    170                String stmpId  = "614";
    171
    172                for( int i=0; i<args.length; i++ ) {
    173                        if( "-token".equalsIgnoreCase( args[i] ) ) {
    174                                token = args[++i];
    175                        }
    176                        else if( "-message".equalsIgnoreCase( args[i] ) ) {
    177                                message = args[++i];
    178                        }
    179                        else if( "-stickerPackageId".equalsIgnoreCase( args[i] ) ) {
    180                                stmpPkg = args[++i];
    181                        }
    182                        else if( "-stickerId".equalsIgnoreCase( args[i] ) ) {
    183                                stmpId = args[++i];
    184                        }
    185                }
    186
    187                final LineNotify lineNotify = new LineNotify( token );
    188                lineNotify.setStamp( stmpPkg,stmpId );
    189                lineNotify.notify( message );
    190        }
    191}