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 * 1.https://notify-bot.line.me/ja/ からログインして 034 * マイページから「アクセストークンを発行」をクリック 035 * 2.トークンを設定する。 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}