Skip to content

Commit 33c4b24

Browse files
committed
Add upload file to aws s3
1 parent 8ee0254 commit 33c4b24

File tree

9 files changed

+146
-44
lines changed

9 files changed

+146
-44
lines changed

pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,11 @@
126126
</exclusion>
127127
</exclusions>
128128
</dependency>
129+
<dependency>
130+
<groupId>com.amazonaws</groupId>
131+
<artifactId>aws-java-sdk-s3</artifactId>
132+
<version>1.11.812</version>
133+
</dependency>
129134
<dependency>
130135
<groupId>org.grpcmock</groupId>
131136
<artifactId>grpcmock-junit5</artifactId>

wechaty-puppet-padplus/pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212

1313

1414
<dependencies>
15+
<dependency>
16+
<groupId>com.amazonaws</groupId>
17+
<artifactId>aws-java-sdk-s3</artifactId>
18+
</dependency>
1519
<dependency>
1620
<groupId>io.github.wechaty</groupId>
1721
<artifactId>wechaty-puppet_${scala-binary-version}</artifactId>

wechaty-puppet-padplus/src/main/scala/wechaty/padplus/schemas/ModelContact.scala

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,24 +20,24 @@ class PadplusContactPayload {
2020
var stranger:String = _ // // 用户v1码,从未加过好友则为空 "v1_0468f2cd3f0efe7ca2589d57c3f9ba952a3789e41b6e78ee00ed53d1e6096b88@stranger"
2121
var ticket:String = _ // // 用户v2码,如果非空则为单向好友(非对方好友) 'v2_xxx@stranger'
2222
var userName:String = _ // // "mengjunjun001" | "qq512436430" Unique name
23-
var verifyFlag:Number = _
24-
var contactFlag:Number = _
23+
var verifyFlag:Int = _
24+
var contactFlag:Int= _
2525
}
2626

2727
class GrpcContactPayload {
2828
var Alias:String = _
2929
var BigHeadImgUrl:String = _
3030
var ChatRoomOwner:String = _
31-
var ChatroomVersion:Number = _
31+
var ChatroomVersion:Int= _
3232
var City:String = _
33-
var ContactFlag:Number = _
33+
var ContactFlag:Int= _
3434
var ContactType:String = _
3535
var EncryptUsername:String = _
3636
var ExtInfo:String = _
3737
var ExtInfoExt:String = _
3838
var HeadImgUrl:String = _
3939
var LabelLists:String = _
40-
var MsgType:Number = _
40+
var MsgType:Int= _
4141
var NickName:String = _
4242
var Province:String = _
4343
var PYInitial:String = _
@@ -47,13 +47,13 @@ class GrpcContactPayload {
4747
var RemarkPYInitial:String = _
4848
var RemarkPYQuanPin:String = _
4949
var Seq:String = _
50-
var Sex:Number = _
50+
var Sex:Int= _
5151
var Signature:String = _
5252
var SmallHeadImgUrl:String = _
5353
var Type7:String = _
54-
var Uin:Number = _
54+
var Uin:Int= _
5555
var UserName:String = _
56-
var VerifyFlag:Number = _
56+
var VerifyFlag:Int= _
5757
var wechatUserName:String = _
5858
}
5959

wechaty-puppet-padplus/src/main/scala/wechaty/padplus/support/ContactRawSupport.scala

Lines changed: 53 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ import wechaty.padplus.schemas.ModelRoom.GrpcRoomPayload
1616
import wechaty.padplus.schemas.ModelUser.ScanData
1717
import wechaty.padplus.schemas.PadplusEnums.QrcodeStatus
1818
import wechaty.puppet.ResourceBox
19-
import wechaty.puppet.schemas.Contact
20-
import wechaty.puppet.schemas.Contact.ContactGender
19+
import wechaty.puppet.schemas.{Contact, Puppet}
20+
import wechaty.puppet.schemas.Contact.{ContactGender, ContactPayload, ContactType}
2121
import wechaty.puppet.schemas.Event.{EventLoginPayload, EventScanPayload}
2222
import wechaty.puppet.schemas.Puppet._
2323

@@ -55,7 +55,7 @@ trait ContactRawSupport {
5555
* contact
5656
*/
5757
override protected def contactRawPayload(contactId: String): Contact.ContactPayload = {
58-
???
58+
this.getContact(contactId)
5959
}
6060

6161
protected def getContact(contactId: String): PadplusContactPayload = {
@@ -83,7 +83,7 @@ trait ContactRawSupport {
8383
onQrcodeScan(response)
8484
case ResponseType.LOGIN_QRCODE =>
8585
val qrcodeData = objectMapper.readTree(response.getData)
86-
println(response.getData)
86+
logger.debug("qrcode:",response.getData)
8787

8888
val base64 = qrcodeData.get("qrcode").asText().replaceAll("\r|\n", "")
8989
val fileBox = ResourceBox.fromBase64(s"qrcode${(Math.random() * 10000).intValue()}.png", base64)
@@ -137,14 +137,14 @@ trait ContactRawSupport {
137137
selfId = Some(rawContactPayload.userName)
138138
}
139139

140-
contactSelfInfo { padplusContact =>
141-
selfId = Some(padplusContact.userName)
142-
logger.debug("contactSelf:{}", padplusContact)
143-
savePadplusContactPayload(padplusContact)
144-
val eventLoginPayload = new EventLoginPayload
145-
eventLoginPayload.contactId = padplusContact.userName
146-
emit(PuppetEventName.LOGIN, eventLoginPayload)
147-
}
140+
// contactSelfInfo { padplusContact =>
141+
// selfId = Some(padplusContact.userName)
142+
// logger.debug("contactSelf:{}", padplusContact)
143+
// savePadplusContactPayload(padplusContact)
144+
// val eventLoginPayload = new EventLoginPayload
145+
// eventLoginPayload.contactId = padplusContact.userName
146+
// emit(PuppetEventName.LOGIN, eventLoginPayload)
147+
// }
148148
} else {
149149
deleteUin()
150150
request(ApiType.GET_QRCODE)
@@ -174,7 +174,8 @@ trait ContactRawSupport {
174174
roomPayload
175175
}
176176
val roomCallback=roomPromises.getIfPresent(userName)
177-
roomCallback.foreach(_.complete(roomTry))
177+
if(roomCallback != null)
178+
roomCallback.foreach(_.complete(roomTry))
178179

179180
}else{
180181
val result:Try[PadplusContactPayload] = Try {
@@ -198,14 +199,14 @@ trait ContactRawSupport {
198199
case QrcodeStatus.Scanned =>
199200

200201
case QrcodeStatus.Confirmed =>
201-
contactSelfInfo { padplusContact =>
202-
selfId = Some(padplusContact.userName)
203-
logger.debug("contactSelf:{}", padplusContact)
204-
savePadplusContactPayload(padplusContact)
205-
val eventLoginPayload = new EventLoginPayload
206-
eventLoginPayload.contactId = padplusContact.userName
207-
emit(PuppetEventName.LOGIN, eventLoginPayload)
208-
}
202+
// contactSelfInfo { padplusContact =>
203+
// selfId = Some(padplusContact.userName)
204+
// logger.debug("contactSelf:{}", padplusContact)
205+
// savePadplusContactPayload(padplusContact)
206+
// val eventLoginPayload = new EventLoginPayload
207+
// eventLoginPayload.contactId = padplusContact.userName
208+
// emit(PuppetEventName.LOGIN, eventLoginPayload)
209+
// }
209210
case QrcodeStatus.Canceled | QrcodeStatus.Expired =>
210211

211212
}
@@ -217,7 +218,7 @@ trait ContactRawSupport {
217218
payload.bigHeadUrl = contactPayload.BigHeadImgUrl
218219
payload.city = contactPayload.City
219220
payload.contactFlag = contactPayload.ContactFlag
220-
payload.contactType = contactPayload.ContactType.toInt
221+
payload.contactType = if(Puppet.isBlank(contactPayload.ContactType)) 0 else contactPayload.ContactType.toInt
221222
payload.country = ""
222223
payload.nickName = contactPayload.NickName
223224
payload.province = contactPayload.Province
@@ -231,6 +232,36 @@ trait ContactRawSupport {
231232
payload.userName = contactPayload.UserName
232233
payload.verifyFlag = contactPayload.VerifyFlag
233234

235+
payload
236+
}
237+
implicit def convertPadplusContactToContactPayload(rawPayload:PadplusContactPayload): ContactPayload ={
238+
if (isRoomId(rawPayload.userName)) {
239+
throw new Error("Room Object instead of Contact!")
240+
}
241+
242+
var contactType = ContactType.Unknown
243+
if (isContactOfficialId(rawPayload.userName) || rawPayload.verifyFlag != 0) {
244+
contactType = ContactType.Official
245+
} else {
246+
contactType = ContactType.Personal
247+
}
248+
var friend = false
249+
if (rawPayload.contactFlag > 0 && rawPayload.contactFlag != 0 && rawPayload.verifyFlag == 0) {
250+
friend = true
251+
}
252+
val payload = new ContactPayload
253+
payload.alias = rawPayload.remark
254+
payload.avatar = rawPayload.bigHeadUrl
255+
payload.city = rawPayload.city
256+
payload.friend = friend
257+
payload.gender = rawPayload.sex
258+
payload.id = rawPayload.userName
259+
payload.name = rawPayload.nickName
260+
payload.province = rawPayload.province
261+
payload.signature = (rawPayload.signature).replace("+", "") // Stay+Foolis
262+
payload.`type` = contactType
263+
payload.weixin = rawPayload.alias
264+
234265
payload
235266
}
236267
}

wechaty-puppet-padplus/src/main/scala/wechaty/padplus/support/GrpcEventSupport.scala

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import wechaty.padplus.PuppetPadplus
77
import wechaty.padplus.grpc.PadPlusServerOuterClass.{ResponseType, StreamResponse}
88
import wechaty.puppet.schemas.Puppet.isBlank
99

10+
import scala.util.{Failure, Success, Try}
11+
1012
/**
1113
*
1214
* @author <a href="mailto:[email protected]">Jun Tsai</a>
@@ -32,8 +34,14 @@ trait GrpcEventSupport extends StreamObserver[StreamResponse]{
3234
callback(response)
3335
}
3436
}else {
35-
val partialFunction=loginPartialFunction(response) orElse messagePartialFunction(response)
36-
partialFunction.applyOrElse(response.getResponseType,{_:ResponseType => Unit})
37+
Try {
38+
val partialFunction = loginPartialFunction(response) orElse messagePartialFunction(response)
39+
partialFunction.applyOrElse(response.getResponseType, { _: ResponseType => Unit })
40+
} match {
41+
case Success(_)=>
42+
case Failure(exception) =>
43+
logger.error(exception.getMessage,exception)
44+
}
3745
}
3846
}
3947

wechaty-puppet-padplus/src/main/scala/wechaty/padplus/support/GrpcSupport.scala

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
package wechaty.padplus.support
22

3+
import java.io.InputStream
34
import java.util.UUID
45
import java.util.concurrent.atomic.AtomicLong
56
import java.util.concurrent.{ConcurrentHashMap, ConcurrentMap, Executors, TimeUnit}
67

8+
import com.amazonaws.auth.{AWSStaticCredentialsProvider, BasicAWSCredentials}
9+
import com.amazonaws.internal.StaticCredentialsProvider
10+
import com.amazonaws.regions.{Region, Regions}
11+
import com.amazonaws.services.s3.{AmazonS3Client, AmazonS3ClientBuilder}
12+
import com.amazonaws.services.s3.model.{CannedAccessControlList, GeneratePresignedUrlRequest, ObjectMetadata, PutObjectRequest}
713
import com.github.benmanes.caffeine.cache.{Cache, Caffeine}
814
import com.typesafe.scalalogging.LazyLogging
915
import io.grpc.{ManagedChannel, ManagedChannelBuilder}
@@ -181,4 +187,27 @@ trait GrpcSupport {
181187
logger.debug("request->response:{}",response)
182188
response
183189
}
190+
private val ACCESS_KEY_ID = "AKIA3PQY2OQG5FEXWMH6"
191+
private val BUCKET= "macpro-message-file",
192+
private val EXPIRE_TIME= 3600 * 24 * 3,
193+
private val PATH= "image-message",
194+
private val SECRET_ACCESS_KEY= "jw7Deo+W8l4FTOL2BXd/VubTJjt1mhm55sRhnsEn",
195+
// private val s3 = new AmazonS3Client(new BasicAWSCredentials(ACCESS_KEY_ID, SECRET_ACCESS_KEY));
196+
private val s3=new AmazonS3ClientBuilder()
197+
.withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(ACCESS_KEY_ID, SECRET_ACCESS_KEY)))
198+
.enablePayloadSigning()
199+
.withRegion(Regions.CN_NORTHWEST_1).build(); // 此处根据自己的 s3 地区位置改变
200+
201+
def uploadFile (filename: String, stream: InputStream) {
202+
// ACL: "public-read",
203+
// const s3 = new AWS.S3({ region: "cn-northwest-1", signatureVersion: "v4" })
204+
val meta = new ObjectMetadata
205+
val key=PATH+"/"+filename
206+
val params = new PutObjectRequest(BUCKET,key,stream,meta)
207+
val result = s3.putObject(params.withCannedAcl(CannedAccessControlList.PublicRead));
208+
//获取一个request
209+
val urlRequest = new GeneratePresignedUrlRequest( BUCKET, key);
210+
//生成公用的url
211+
s3.generatePresignedUrl(urlRequest);
212+
}
184213
}

wechaty-puppet-padplus/src/main/scala/wechaty/padplus/support/MessageRawSupport.scala

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ import com.fasterxml.jackson.dataformat.xml.XmlMapper
44
import com.typesafe.scalalogging.LazyLogging
55
import wechaty.padplus.grpc.PadPlusServerOuterClass.{ApiType, ResponseType, StreamResponse}
66
import wechaty.padplus.schemas.GrpcSchemas.GrpcMessagePayload
7-
import wechaty.padplus.schemas.ModelMessage.PadplusMessagePayload
7+
import wechaty.padplus.schemas.ModelMessage.{GrpcResponseMessageData, PadplusMessagePayload}
88
import wechaty.padplus.schemas.PadplusEnums.PadplusMessageType
99
import wechaty.puppet.ResourceBox
10+
import wechaty.puppet.ResourceBox.UrlResourceBox
1011
import wechaty.puppet.events.EventEmitter
1112
import wechaty.puppet.schemas.Event.EventMessagePayload
1213
import wechaty.puppet.schemas.Image.ImageType.Type
@@ -37,7 +38,28 @@ trait MessageRawSupport {
3738

3839
override def messageSendContact(conversationId: String, contactId: String): String = ???
3940

40-
override def messageSendFile(conversationId: String, file: ResourceBox): String = ???
41+
override def messageSendFile(conversationId: String, file: ResourceBox): String = {
42+
val url = file match{
43+
case urlResource:UrlResourceBox => urlResource.url
44+
case _ => uploadFile(file.name,file.toStream)
45+
}
46+
47+
/*
48+
data = {
49+
fileName,
50+
fromUserName: selfId,
51+
messageType: PadplusMessageType.Image,
52+
subType,
53+
toUserName: receiver,
54+
url,
55+
}
56+
const res = await this.requestClient.request({
57+
apiType: ApiType.SEND_FILE,
58+
data,
59+
})
60+
*/
61+
???
62+
}
4163

4264
override def messageSendMiniProgram(conversationId: String, miniProgramPayload: MiniProgram.MiniProgramPayload): String = ???
4365

@@ -47,9 +69,8 @@ trait MessageRawSupport {
4769
json.put("messageType",PadplusMessageType.Text.id)
4870
json.put("fromUserName",selfId.get)
4971
json.put("toUserName",conversationId)
50-
val response = request(ApiType.SEND_MESSAGE, Some(json.toString))
51-
//TODO
52-
""
72+
val response = requestForObject[GrpcResponseMessageData](ApiType.SEND_MESSAGE, Some(json.toString))
73+
response.msgId
5374
}
5475

5576
override def messageSendUrl(conversationId: String, urlLinkPayload: UrlLink.UrlLinkPayload): String = ???
@@ -120,10 +141,11 @@ trait MessageRawSupport {
120141
*/
121142
if (!isBlank(messagePayload.roomId)) {
122143
val xmlMapper = new XmlMapper();
123-
println(rawPayload.msgSource)
124-
val root = xmlMapper.readTree(rawPayload.msgSource)
125-
if(root.has("atuserlist")){
126-
messagePayload.mentionIdList = root.get("atuserlist").asText().split(",")
144+
if(!Puppet.isBlank(rawPayload.msgSource)) {
145+
val root = xmlMapper.readTree(rawPayload.msgSource)
146+
if (root.has("atuserlist")) {
147+
messagePayload.mentionIdList = root.get("atuserlist").asText().split(",")
148+
}
127149
}
128150
}
129151

wechaty-puppet/src/main/scala/wechaty/puppet/ResourceBox.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ object ResourceBox {
5555
val File :Type = Value(5)
5656
val Stream :Type = Value(6)
5757
}
58-
private class UrlResourceBox(url:String) extends AbstractResourceBox{
58+
class UrlResourceBox private(val url:String) extends AbstractResourceBox{
5959
override def toStream: InputStream = {
6060
val connection = new URL(url).openConnection.asInstanceOf[HttpURLConnection]
6161
connection.setConnectTimeout(5000)
@@ -76,7 +76,7 @@ object ResourceBox {
7676

7777
override def name: String = url.substring(url.lastIndexOf("/")+1)
7878
}
79-
private class Base64ResourceBox(override val name:String,base64:String) extends AbstractResourceBox{
79+
class Base64ResourceBox private(override val name:String,base64:String) extends AbstractResourceBox{
8080
override def toStream: InputStream = {
8181
//decode base64 as byte array input stream
8282
new ByteArrayInputStream(Base64.getDecoder.decode(base64))
@@ -93,7 +93,7 @@ object ResourceBox {
9393
}
9494

9595
}
96-
private class StreamResourceBox(override val name:String,stream:InputStream) extends AbstractResourceBox{
96+
class StreamResourceBox private(override val name:String,stream:InputStream) extends AbstractResourceBox{
9797
override def toStream: InputStream = stream
9898
override protected def using[T <: Closeable, R](resource: T)(block: T => R): R = {
9999
block(resource) //don't close the stream.must be closed by creator

wechaty/src/main/scala/wechaty/DingDongPadplusBot.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ object DingDongPadplusBot {
2424
val bot = Wechaty.instance(option)
2525

2626
bot.use(new DingDongPlugin(DingDongConfig()))
27+
.onMessage(message=>{
28+
println(message.text)
29+
})
2730
.onScan(payload => {
2831
println("Scan QR Code to login: %s\nhttps://api.qrserver.com/v1/create-qr-code/?data=%s\n".format(payload.status, payload.qrcode))
2932
})

0 commit comments

Comments
 (0)