2018-05-16 21:09:49 +02:00
|
|
|
package jp.juggler.subwaytooter.util
|
|
|
|
|
|
|
|
import android.content.Context
|
|
|
|
import jp.juggler.subwaytooter.PollingWorker
|
|
|
|
import jp.juggler.subwaytooter.R
|
|
|
|
import jp.juggler.subwaytooter.api.TootApiClient
|
|
|
|
import jp.juggler.subwaytooter.api.TootApiResult
|
|
|
|
import jp.juggler.subwaytooter.api.entity.TootInstance
|
|
|
|
import jp.juggler.subwaytooter.api.entity.TootPushSubscription
|
|
|
|
import jp.juggler.subwaytooter.api.entity.parseItem
|
|
|
|
import jp.juggler.subwaytooter.table.SavedAccount
|
|
|
|
import jp.juggler.subwaytooter.table.SubscriptionServerKey
|
2019-12-18 05:38:57 +01:00
|
|
|
import jp.juggler.util.*
|
2018-05-16 21:09:49 +02:00
|
|
|
import okhttp3.Request
|
|
|
|
|
|
|
|
class PushSubscriptionHelper(
|
|
|
|
val context : Context,
|
|
|
|
val account : SavedAccount,
|
|
|
|
val verbose : Boolean = false
|
|
|
|
) {
|
|
|
|
|
2018-08-30 05:23:13 +02:00
|
|
|
companion object {
|
2019-12-17 22:00:09 +01:00
|
|
|
private const val ERROR_PREVENT_FREQUENTLY_CHECK =
|
2019-12-17 19:33:01 +01:00
|
|
|
"prevent frequently subscription check."
|
2019-12-17 20:29:30 +01:00
|
|
|
|
2019-12-18 05:38:57 +01:00
|
|
|
private val lastCheckedMap : HashMap<String, Long> = HashMap()
|
2019-12-17 18:58:49 +01:00
|
|
|
|
2019-12-17 20:29:30 +01:00
|
|
|
fun clearLastCheck(account : SavedAccount) {
|
|
|
|
synchronized(lastCheckedMap) {
|
2019-12-17 19:11:19 +01:00
|
|
|
lastCheckedMap.remove(account.acct)
|
|
|
|
}
|
|
|
|
}
|
2019-12-18 05:38:57 +01:00
|
|
|
|
|
|
|
private fun Boolean.booleanToInt(trueValue : Int, falseValue : Int = 0) =
|
|
|
|
if(this) trueValue else falseValue
|
2018-08-30 05:23:13 +02:00
|
|
|
}
|
|
|
|
|
2019-12-18 05:38:57 +01:00
|
|
|
private fun isRecentlyChecked() : Boolean {
|
|
|
|
if(verbose) return false
|
2018-08-30 05:23:13 +02:00
|
|
|
val now = System.currentTimeMillis()
|
2019-12-18 05:38:57 +01:00
|
|
|
val acct = account.acct
|
2018-08-31 12:29:34 +02:00
|
|
|
synchronized(lastCheckedMap) {
|
2019-12-18 05:38:57 +01:00
|
|
|
val lastChecked = lastCheckedMap[acct]
|
|
|
|
val rv = lastChecked != null && now - lastChecked < 3600000L
|
|
|
|
if(! rv) lastCheckedMap[acct] = now
|
|
|
|
return rv
|
2018-08-30 05:23:13 +02:00
|
|
|
}
|
|
|
|
}
|
2018-08-31 12:29:34 +02:00
|
|
|
|
2018-05-16 21:09:49 +02:00
|
|
|
val flags : Int
|
|
|
|
|
2019-03-13 19:11:11 +01:00
|
|
|
private var subscribed : Boolean = false
|
2018-05-16 21:09:49 +02:00
|
|
|
|
|
|
|
init {
|
2019-12-18 05:38:57 +01:00
|
|
|
this.flags = account.notification_boost.booleanToInt(1) +
|
|
|
|
account.notification_favourite.booleanToInt(2) +
|
|
|
|
account.notification_follow.booleanToInt(4) +
|
|
|
|
account.notification_mention.booleanToInt(8) +
|
|
|
|
(account.isMisskey && account.notification_reaction).booleanToInt(16) +
|
|
|
|
account.notification_vote.booleanToInt(32) +
|
|
|
|
account.notification_follow_request.booleanToInt(64)
|
2018-05-16 21:09:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
val log : String
|
|
|
|
get() = sb.toString()
|
|
|
|
|
|
|
|
private val sb = StringBuilder()
|
|
|
|
|
|
|
|
private fun addLog(s : String?) {
|
|
|
|
if(s?.isNotEmpty() == true) {
|
|
|
|
if(sb.isNotEmpty()) sb.append('\n')
|
|
|
|
sb.append(s)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun updateServerKey(
|
|
|
|
client : TootApiClient,
|
|
|
|
clientIdentifier : String,
|
|
|
|
serverKey : String?
|
2018-05-24 09:56:30 +02:00
|
|
|
) : TootApiResult? {
|
|
|
|
|
|
|
|
if(serverKey == null) {
|
2019-12-18 05:38:57 +01:00
|
|
|
return TootApiResult(context.getString(R.string.push_notification_server_key_missing))
|
2018-05-24 09:56:30 +02:00
|
|
|
} else if(serverKey.isEmpty()) {
|
2019-12-18 05:38:57 +01:00
|
|
|
return TootApiResult(context.getString(R.string.push_notification_server_key_empty))
|
2018-05-16 21:09:49 +02:00
|
|
|
}
|
2018-05-24 09:56:30 +02:00
|
|
|
|
2018-05-16 21:09:49 +02:00
|
|
|
// 既に登録済みの値と同じなら何もしない
|
|
|
|
val oldKey = SubscriptionServerKey.find(clientIdentifier)
|
2018-05-24 09:56:30 +02:00
|
|
|
if(oldKey != serverKey) {
|
2018-05-16 21:09:49 +02:00
|
|
|
|
2018-05-24 09:56:30 +02:00
|
|
|
// サーバキーをアプリサーバに登録
|
|
|
|
val r = client.http(
|
2020-01-07 09:03:32 +01:00
|
|
|
JsonObject().apply{
|
|
|
|
put("client_id", clientIdentifier)
|
|
|
|
put("server_key", serverKey)
|
|
|
|
}
|
2018-12-02 11:25:00 +01:00
|
|
|
.toPostRequestBuilder()
|
2018-05-24 09:56:30 +02:00
|
|
|
.url("${PollingWorker.APP_SERVER}/webpushserverkey")
|
|
|
|
.build()
|
2019-10-06 13:23:33 +02:00
|
|
|
|
2018-05-24 09:56:30 +02:00
|
|
|
)
|
|
|
|
val res = r?.response
|
2019-08-24 05:35:22 +02:00
|
|
|
when(res?.code) {
|
2019-10-06 13:23:33 +02:00
|
|
|
|
|
|
|
null -> {
|
2019-08-24 05:35:22 +02:00
|
|
|
}
|
2019-10-06 13:23:33 +02:00
|
|
|
|
2019-08-24 05:35:22 +02:00
|
|
|
200 -> {
|
|
|
|
// 登録できたサーバーキーをアプリ内DBに保存
|
|
|
|
SubscriptionServerKey.save(clientIdentifier, serverKey)
|
|
|
|
addLog("(server public key is registered.)")
|
|
|
|
}
|
|
|
|
|
|
|
|
else -> {
|
|
|
|
addLog("(server public key registration failed.)")
|
|
|
|
addLog("${res.code} ${res.message}")
|
2018-05-24 09:56:30 +02:00
|
|
|
}
|
2018-05-16 21:09:49 +02:00
|
|
|
}
|
|
|
|
}
|
2018-05-24 09:56:30 +02:00
|
|
|
return TootApiResult()
|
2018-05-16 21:09:49 +02:00
|
|
|
}
|
|
|
|
|
2019-12-18 08:52:55 +01:00
|
|
|
// アプリサーバにendpoint URLの変更を伝える
|
|
|
|
private fun registerEndpoint(
|
|
|
|
client : TootApiClient,
|
|
|
|
deviceId : String,
|
|
|
|
endpoint : String
|
|
|
|
) : TootApiResult? {
|
2019-12-18 05:38:57 +01:00
|
|
|
|
2019-12-18 08:52:55 +01:00
|
|
|
if( account.last_push_endpoint == endpoint) return TootApiResult()
|
2019-12-18 05:38:57 +01:00
|
|
|
|
2019-12-18 08:52:55 +01:00
|
|
|
return client.http(
|
2020-01-07 09:03:32 +01:00
|
|
|
jsonObject {
|
|
|
|
put("acct", account.acct)
|
|
|
|
put("deviceId", deviceId)
|
|
|
|
put("endpoint", endpoint)
|
|
|
|
}
|
2019-12-18 08:52:55 +01:00
|
|
|
.toPostRequestBuilder()
|
|
|
|
.url("${PollingWorker.APP_SERVER}/webpushendpoint")
|
|
|
|
.build()
|
|
|
|
)?.also{ result ->
|
|
|
|
val res = result.response
|
|
|
|
if(res!=null){
|
|
|
|
val code = res.code
|
|
|
|
if( code in 200 until 300 ) {
|
|
|
|
account.updateLastPushEndpoint(endpoint)
|
|
|
|
}else{
|
|
|
|
result.caption = "(SubwayTooter App server)"
|
|
|
|
client.readBodyString(result)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun updateSubscriptionMisskey(client : TootApiClient) : TootApiResult? {
|
2019-12-17 20:29:30 +01:00
|
|
|
|
|
|
|
// 現在の購読状態を取得できないので、毎回購読の更新を行う
|
|
|
|
// FCMのデバイスIDを取得
|
|
|
|
val device_id = PollingWorker.getDeviceId(context)
|
|
|
|
?: return TootApiResult(error = context.getString(R.string.missing_fcm_device_id))
|
|
|
|
|
2019-12-18 05:38:57 +01:00
|
|
|
// アクセストークン
|
|
|
|
val accessToken = account.misskeyApiToken
|
|
|
|
?: return TootApiResult(error = "missing misskeyApiToken.")
|
|
|
|
|
|
|
|
// インストールIDを取得
|
|
|
|
val install_id = PollingWorker.prepareInstallId(context)
|
|
|
|
?: return TootApiResult(error = context.getString(R.string.missing_install_id))
|
|
|
|
|
|
|
|
// クライアント識別子
|
|
|
|
val clientIdentifier = "$accessToken$install_id".digestSHA256Base64Url()
|
|
|
|
|
2019-12-18 08:52:55 +01:00
|
|
|
// 購読が不要な場合
|
|
|
|
// アプリサーバが410を返せるように状態を通知する
|
|
|
|
if(flags == 0) return registerEndpoint(client,device_id,"none")?.also{
|
|
|
|
if(it.error ==null && verbose ) addLog(context.getString(R.string.push_subscription_updated))
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
https://github.com/syuilo/misskey/blob/master/src/services/create-notification.ts#L46
|
|
|
|
Misskeyは通知に既読の概念があり、イベント発生後2秒たっても未読の時だけプッシュ通知が発生する。
|
|
|
|
STでプッシュ通知を試すにはSTの画面を非表示にする必要があるのでWebUIを使って投稿していたが、
|
|
|
|
WebUIを開いていると通知はすぐ既読になるのでプッシュ通知は発生しない。
|
|
|
|
プッシュ通知のテスト時はST2台を使い、片方をプッシュ通知の受信チェック、もう片方を投稿などの作業に使うことになる。
|
|
|
|
*/
|
|
|
|
|
|
|
|
// https://github.com/syuilo/misskey/issues/2541
|
|
|
|
// https://github.com/syuilo/misskey/commit/4c6fb60dd25d7e2865fc7c4d97728593ffc3c902
|
|
|
|
// 2018/9/1 の上記コミット以降、Misskeyでもサーバ公開鍵を得られるようになった
|
|
|
|
|
2019-12-17 20:29:30 +01:00
|
|
|
val endpoint =
|
2019-12-18 08:52:55 +01:00
|
|
|
"${PollingWorker.APP_SERVER}/webpushcallback/${device_id.encodePercent()}/${account.acct.encodePercent()}/$flags/$clientIdentifier/misskey"
|
|
|
|
|
|
|
|
// アプリサーバが過去のendpoint urlに410を返せるよう、状態を通知する
|
|
|
|
val r = registerEndpoint(client,device_id,endpoint.toUri().encodedPath!!)
|
|
|
|
if(r==null || r.error!=null) return r
|
2019-12-17 20:29:30 +01:00
|
|
|
|
|
|
|
// 購読
|
|
|
|
return client.request(
|
|
|
|
"/api/sw/register",
|
2020-01-07 09:03:32 +01:00
|
|
|
account.putMisskeyApiToken().apply{
|
|
|
|
put("endpoint", endpoint)
|
|
|
|
put("auth", "iRdmDrOS6eK6xvG1H6KshQ")
|
|
|
|
put(
|
2019-12-17 20:29:30 +01:00
|
|
|
"publickey",
|
|
|
|
"BBEUVi7Ehdzzpe_ZvlzzkQnhujNJuBKH1R0xYg7XdAKNFKQG9Gpm0TSGRGSuaU7LUFKX-uz8YW0hAshifDCkPuE"
|
|
|
|
)
|
2020-01-07 09:03:32 +01:00
|
|
|
}
|
2019-12-17 20:29:30 +01:00
|
|
|
.toPostRequestBuilder()
|
|
|
|
)?.also { result ->
|
2019-12-18 05:38:57 +01:00
|
|
|
val jsonObject = result.jsonObject
|
|
|
|
if(jsonObject == null) {
|
2019-12-17 20:29:30 +01:00
|
|
|
addLog("API error.")
|
|
|
|
} else {
|
2019-12-18 05:38:57 +01:00
|
|
|
if(verbose) addLog(context.getString(R.string.push_subscription_updated))
|
2019-12-17 20:29:30 +01:00
|
|
|
subscribed = true
|
2019-12-18 05:38:57 +01:00
|
|
|
return updateServerKey(
|
|
|
|
client,
|
|
|
|
clientIdentifier,
|
2020-01-08 04:23:45 +01:00
|
|
|
jsonObject.string("key") ?: "3q2+rw"
|
2019-12-18 05:38:57 +01:00
|
|
|
)
|
2019-12-17 20:29:30 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun updateSubscriptionMastodon(client : TootApiClient) : TootApiResult? {
|
|
|
|
// 現在の購読状態を取得
|
|
|
|
// https://github.com/tootsuite/mastodon/pull/7471
|
|
|
|
// https://github.com/tootsuite/mastodon/pull/7472
|
|
|
|
var r = client.request("/api/v1/push/subscription")
|
|
|
|
var res = r?.response ?: return r // cancelled or missing response
|
|
|
|
var subscription404 = false
|
|
|
|
when(res.code) {
|
|
|
|
200 -> {
|
|
|
|
if(r.error?.isNotEmpty() == true && r.jsonObject == null) {
|
|
|
|
// Pleromaが200応用でエラーHTMLを返す
|
2019-12-17 22:00:09 +01:00
|
|
|
addLog(context.getString(R.string.instance_does_not_support_push_api_pleroma))
|
|
|
|
return r
|
2018-05-16 21:09:49 +02:00
|
|
|
}
|
2019-12-17 20:29:30 +01:00
|
|
|
// たぶん購読が存在する
|
|
|
|
}
|
|
|
|
|
|
|
|
404 -> {
|
|
|
|
subscription404 = true
|
2019-12-17 22:00:09 +01:00
|
|
|
// この時点では存在しないのが購読なのかAPIなのか分からない
|
2019-12-17 20:29:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
403 -> {
|
|
|
|
// アクセストークンにpushスコープがない
|
2019-12-17 22:00:09 +01:00
|
|
|
if(flags != 0 || verbose)
|
2019-12-17 20:29:30 +01:00
|
|
|
addLog(context.getString(R.string.missing_push_scope))
|
2019-12-17 22:00:09 +01:00
|
|
|
return r
|
2019-12-17 20:29:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
in 400 until 500 -> {
|
|
|
|
addLog(context.getString(R.string.instance_does_not_support_push_api_pleroma))
|
|
|
|
return r
|
|
|
|
}
|
|
|
|
|
|
|
|
else -> {
|
|
|
|
addLog("${res.request}")
|
|
|
|
addLog("${res.code} ${res.message}")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
val oldSubscription = parseItem(::TootPushSubscription, r.jsonObject)
|
|
|
|
|
|
|
|
if(oldSubscription == null) {
|
|
|
|
|
|
|
|
// 現在の購読状況が分からない場合はインスタンスのバージョンを調べる必要がある
|
|
|
|
val (ti, result) = TootInstance.get(client)
|
|
|
|
ti ?: return result
|
|
|
|
|
2019-12-17 22:00:09 +01:00
|
|
|
// 2.4.0rc1 未満にはプッシュ購読APIはない
|
|
|
|
if(! ti.versionGE(TootInstance.VERSION_2_4_0_rc1))
|
2019-12-17 20:29:30 +01:00
|
|
|
return TootApiResult(
|
2019-12-17 22:00:09 +01:00
|
|
|
context.getString(R.string.instance_does_not_support_push_api, ti.version)
|
2019-12-17 20:29:30 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
if(subscription404 && flags == 0) {
|
|
|
|
when {
|
|
|
|
ti.versionGE(TootInstance.VERSION_2_4_0_rc2) -> {
|
|
|
|
// 購読が不要で現在の状況が404だった場合
|
|
|
|
// 2.4.0rc2以降では「購読が存在しない」を示すので何もしなくてよい
|
|
|
|
if(verbose) addLog(context.getString(R.string.push_subscription_not_exists))
|
|
|
|
return TootApiResult()
|
2018-11-22 01:07:53 +01:00
|
|
|
}
|
|
|
|
|
2018-05-16 21:09:49 +02:00
|
|
|
else -> {
|
2019-12-17 20:29:30 +01:00
|
|
|
// 2.4.0rc1では「APIが存在しない」と「購読が存在しない」を判別できない
|
2018-05-16 21:09:49 +02:00
|
|
|
}
|
|
|
|
}
|
2019-12-17 20:29:30 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// FCMのデバイスIDを取得
|
|
|
|
val device_id = PollingWorker.getDeviceId(context)
|
|
|
|
?: return TootApiResult(error = context.getString(R.string.missing_fcm_device_id))
|
|
|
|
|
|
|
|
// アクセストークン
|
|
|
|
val accessToken = account.getAccessToken()
|
|
|
|
?: return TootApiResult(error = "missing access token.")
|
|
|
|
|
|
|
|
// インストールIDを取得
|
|
|
|
val install_id = PollingWorker.prepareInstallId(context)
|
|
|
|
?: return TootApiResult(error = context.getString(R.string.missing_install_id))
|
|
|
|
|
|
|
|
// アクセストークンのダイジェスト
|
|
|
|
val tokenDigest = accessToken.digestSHA256Base64Url()
|
|
|
|
|
|
|
|
// クライアント識別子
|
|
|
|
val clientIdentifier = "$accessToken$install_id".digestSHA256Base64Url()
|
|
|
|
|
|
|
|
val endpoint =
|
|
|
|
"${PollingWorker.APP_SERVER}/webpushcallback/${device_id.encodePercent()}/${account.acct.encodePercent()}/$flags/$clientIdentifier"
|
|
|
|
|
2019-12-17 22:00:09 +01:00
|
|
|
if(oldSubscription?.endpoint == endpoint) {
|
|
|
|
// 既に登録済みで、endpointも一致している
|
|
|
|
subscribed = true
|
|
|
|
if(verbose) addLog(context.getString(R.string.push_subscription_already_exists))
|
|
|
|
return updateServerKey(client, clientIdentifier, oldSubscription.server_key)
|
2019-12-17 20:29:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// アクセストークンの優先権を取得
|
|
|
|
r = client.http(
|
2020-01-07 09:03:32 +01:00
|
|
|
jsonObject{
|
|
|
|
put("token_digest", tokenDigest)
|
|
|
|
put("install_id", install_id)
|
|
|
|
}
|
2019-12-17 20:29:30 +01:00
|
|
|
.toPostRequestBuilder()
|
|
|
|
.url("${PollingWorker.APP_SERVER}/webpushtokencheck")
|
|
|
|
.build()
|
2019-12-17 22:00:09 +01:00
|
|
|
) ?: return null
|
2019-12-17 20:29:30 +01:00
|
|
|
|
|
|
|
res = r.response ?: return r
|
|
|
|
if(res.code != 200) {
|
|
|
|
if(res.code == 403) addLog(context.getString(R.string.token_exported))
|
|
|
|
r.caption = "(SubwayTooter App server)"
|
|
|
|
client.readBodyString(r)
|
|
|
|
return r
|
|
|
|
}
|
|
|
|
|
2019-12-17 22:00:09 +01:00
|
|
|
return if(flags == 0) {
|
2019-12-17 20:29:30 +01:00
|
|
|
// 通知設定が全てカラなので、購読を取り消したい
|
|
|
|
|
2019-12-17 22:00:09 +01:00
|
|
|
r = client.request("/api/v1/push/subscription", Request.Builder().delete())
|
2019-12-17 20:29:30 +01:00
|
|
|
res = r?.response ?: return r
|
|
|
|
|
2019-12-17 22:00:09 +01:00
|
|
|
when(res.code) {
|
2019-12-17 20:29:30 +01:00
|
|
|
200 -> {
|
2019-12-17 22:00:09 +01:00
|
|
|
if(verbose) addLog(context.getString(R.string.push_subscription_deleted))
|
|
|
|
TootApiResult()
|
2018-05-16 21:09:49 +02:00
|
|
|
}
|
|
|
|
|
2019-12-17 20:29:30 +01:00
|
|
|
404 -> {
|
2019-12-17 22:00:09 +01:00
|
|
|
if(verbose) {
|
2019-12-17 20:29:30 +01:00
|
|
|
addLog(context.getString(R.string.missing_push_api))
|
|
|
|
r
|
2019-12-17 22:00:09 +01:00
|
|
|
} else {
|
|
|
|
TootApiResult()
|
2018-08-30 08:51:32 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-17 20:29:30 +01:00
|
|
|
403 -> {
|
|
|
|
addLog(context.getString(R.string.missing_push_scope))
|
|
|
|
r
|
|
|
|
}
|
2018-05-16 21:09:49 +02:00
|
|
|
|
2019-12-17 20:29:30 +01:00
|
|
|
else -> {
|
|
|
|
addLog("${res.request}")
|
|
|
|
addLog("${res.code} ${res.message}")
|
|
|
|
r
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
// 通知設定が空ではないので購読を行いたい
|
|
|
|
|
|
|
|
r = client.request(
|
|
|
|
"/api/v1/push/subscription",
|
2020-01-07 09:03:32 +01:00
|
|
|
JsonObject().apply {
|
|
|
|
put("subscription", JsonObject().apply {
|
2019-12-17 22:00:09 +01:00
|
|
|
put("endpoint", endpoint)
|
2020-01-07 09:03:32 +01:00
|
|
|
put("keys", JsonObject().apply {
|
2019-12-17 22:00:09 +01:00
|
|
|
put(
|
|
|
|
"p256dh",
|
|
|
|
"BBEUVi7Ehdzzpe_ZvlzzkQnhujNJuBKH1R0xYg7XdAKNFKQG9Gpm0TSGRGSuaU7LUFKX-uz8YW0hAshifDCkPuE"
|
|
|
|
)
|
|
|
|
put("auth", "iRdmDrOS6eK6xvG1H6KshQ")
|
|
|
|
})
|
|
|
|
})
|
2020-01-07 09:03:32 +01:00
|
|
|
put("data", JsonObject().apply {
|
|
|
|
put("alerts", JsonObject().apply {
|
2019-12-17 22:00:09 +01:00
|
|
|
put("follow", account.notification_follow)
|
|
|
|
put("favourite", account.notification_favourite)
|
|
|
|
put("reblog", account.notification_boost)
|
|
|
|
put("mention", account.notification_mention)
|
|
|
|
put("poll", account.notification_vote)
|
|
|
|
put("follow_request", account.notification_follow_request)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
.toPostRequestBuilder()
|
|
|
|
) ?: return null
|
2019-12-17 20:29:30 +01:00
|
|
|
|
2019-12-17 22:00:09 +01:00
|
|
|
res = r.response ?: return r
|
2019-12-17 20:29:30 +01:00
|
|
|
|
2019-12-17 22:00:09 +01:00
|
|
|
when(res.code) {
|
2019-12-17 20:29:30 +01:00
|
|
|
404 -> {
|
|
|
|
addLog(context.getString(R.string.missing_push_api))
|
|
|
|
r
|
2018-08-30 08:51:32 +02:00
|
|
|
}
|
2018-05-16 21:09:49 +02:00
|
|
|
|
2019-12-17 20:29:30 +01:00
|
|
|
403 -> {
|
|
|
|
addLog(context.getString(R.string.missing_push_scope))
|
|
|
|
r
|
|
|
|
}
|
|
|
|
|
|
|
|
200 -> {
|
2019-12-17 22:00:09 +01:00
|
|
|
val newSubscription = parseItem(::TootPushSubscription, r.jsonObject)
|
|
|
|
?: return r.setError("parse error.")
|
2018-05-16 21:09:49 +02:00
|
|
|
|
2019-12-17 22:00:09 +01:00
|
|
|
subscribed = true
|
|
|
|
if(verbose) addLog(context.getString(R.string.push_subscription_updated))
|
2018-05-16 21:09:49 +02:00
|
|
|
|
2019-12-17 22:00:09 +01:00
|
|
|
return updateServerKey(
|
|
|
|
client,
|
|
|
|
clientIdentifier,
|
|
|
|
newSubscription.server_key
|
|
|
|
)
|
2019-12-17 20:29:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
else -> {
|
2019-12-17 22:00:09 +01:00
|
|
|
addLog(r.jsonObject?.toString())
|
2019-12-17 20:29:30 +01:00
|
|
|
r
|
2018-05-16 21:09:49 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-17 22:00:09 +01:00
|
|
|
fun updateSubscription(client : TootApiClient) : TootApiResult? =
|
2019-12-17 20:29:30 +01:00
|
|
|
try {
|
|
|
|
when {
|
2019-12-18 05:38:57 +01:00
|
|
|
isRecentlyChecked() ->
|
2019-12-17 20:29:30 +01:00
|
|
|
TootApiResult(ERROR_PREVENT_FREQUENTLY_CHECK)
|
|
|
|
|
|
|
|
account.isPseudo ->
|
|
|
|
TootApiResult(context.getString(R.string.pseudo_account_not_supported))
|
|
|
|
|
|
|
|
account.isMisskey ->
|
|
|
|
updateSubscriptionMisskey(client)
|
|
|
|
|
|
|
|
else ->
|
|
|
|
updateSubscriptionMastodon(client)
|
|
|
|
}
|
|
|
|
} catch(ex : Throwable) {
|
|
|
|
TootApiResult(ex.withCaption("error."))
|
2019-12-17 22:00:09 +01:00
|
|
|
}?.apply {
|
|
|
|
|
2019-12-17 20:29:30 +01:00
|
|
|
if(error != null) addLog("$error $requestInfo".trimEnd())
|
2019-12-17 18:58:49 +01:00
|
|
|
|
2019-12-18 05:38:57 +01:00
|
|
|
// update error text on account table
|
2019-12-17 20:29:30 +01:00
|
|
|
val log = log
|
2019-12-17 18:58:49 +01:00
|
|
|
when {
|
2019-12-17 22:00:09 +01:00
|
|
|
|
2019-12-17 20:29:30 +01:00
|
|
|
log.contains(ERROR_PREVENT_FREQUENTLY_CHECK) -> {
|
2019-12-18 05:38:57 +01:00
|
|
|
// don't update if check was skipped.
|
2019-12-17 18:58:49 +01:00
|
|
|
}
|
|
|
|
|
2019-12-17 20:29:30 +01:00
|
|
|
subscribed || log.isEmpty() ->
|
2019-12-17 22:00:09 +01:00
|
|
|
// clear error text if succeeded or no error log
|
|
|
|
if(account.last_subscription_error != null)
|
|
|
|
account.updateSubscriptionError(null)
|
2019-12-17 18:58:49 +01:00
|
|
|
|
2019-12-17 22:00:09 +01:00
|
|
|
else ->
|
|
|
|
// record error text
|
|
|
|
account.updateSubscriptionError(log)
|
2019-12-17 18:58:49 +01:00
|
|
|
}
|
|
|
|
}
|
2018-05-16 21:09:49 +02:00
|
|
|
}
|