change apns to use sandbox, and (somewhat) provide a custom payload
Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com>
This commit is contained in:
@@ -30,6 +30,7 @@ public_key = "BGcvgR-i2z4IQ5Mw841vJvkLjt8wY-FjmWrw83jOLCY52qcGZS0OF7nfLzuYbjsQIS
|
|||||||
api_key = ""
|
api_key = ""
|
||||||
|
|
||||||
[api.apn]
|
[api.apn]
|
||||||
|
sandbox = false
|
||||||
pkcs8 = ""
|
pkcs8 = ""
|
||||||
key_id = ""
|
key_id = ""
|
||||||
team_id = ""
|
team_id = ""
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ pub struct ApiFcm {
|
|||||||
|
|
||||||
#[derive(Deserialize, Debug, Clone)]
|
#[derive(Deserialize, Debug, Clone)]
|
||||||
pub struct ApiApn {
|
pub struct ApiApn {
|
||||||
|
pub sandbox: bool,
|
||||||
pub pkcs8: String,
|
pub pkcs8: String,
|
||||||
pub key_id: String,
|
pub key_id: String,
|
||||||
pub team_id: String,
|
pub team_id: String,
|
||||||
|
|||||||
@@ -6,13 +6,23 @@ use base64::{
|
|||||||
};
|
};
|
||||||
use deadqueue::limited::Queue;
|
use deadqueue::limited::Queue;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use revolt_a2::{Client, ClientConfig, DefaultNotificationBuilder};
|
use revolt_a2::{Client, ClientConfig, DefaultNotificationBuilder, Endpoint};
|
||||||
use revolt_a2::{Error, ErrorBody, ErrorReason, NotificationBuilder, Response};
|
use revolt_a2::{Error, ErrorBody, ErrorReason, NotificationBuilder, Response};
|
||||||
use revolt_config::config;
|
use revolt_config::config;
|
||||||
use revolt_models::v0::PushNotification;
|
use revolt_models::v0::{Message, PushNotification};
|
||||||
|
|
||||||
use crate::Database;
|
use crate::Database;
|
||||||
|
|
||||||
|
/// Payload information
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ApnCustomPayload {
|
||||||
|
message: Message,
|
||||||
|
serverId: String,
|
||||||
|
authorAvatar: String,
|
||||||
|
authorDisplayName: String,
|
||||||
|
channelName: String,
|
||||||
|
}
|
||||||
|
|
||||||
/// Task information
|
/// Task information
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ApnTask {
|
pub struct ApnTask {
|
||||||
@@ -30,9 +40,24 @@ pub struct ApnTask {
|
|||||||
|
|
||||||
/// Thread Id
|
/// Thread Id
|
||||||
thread_id: String,
|
thread_id: String,
|
||||||
|
|
||||||
|
/// Category (informs the client what kind of notification is being sent.)
|
||||||
|
category: String,
|
||||||
|
|
||||||
|
/// Payload used by the iOS client to modify the notification
|
||||||
|
payload: ApnCustomPayload,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ApnTask {
|
impl ApnTask {
|
||||||
|
fn format_title(notification: &PushNotification) -> String {
|
||||||
|
// ideally this changes depending on context
|
||||||
|
// in a server, it would look like "Sendername, #channelname in servername"
|
||||||
|
// in a group, it would look like "Sendername in groupname"
|
||||||
|
// in a dm it should just be "Sendername".
|
||||||
|
// not sure how feasible all those are given the PushNotification object as it currently stands.
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
|
||||||
pub fn from_notification(
|
pub fn from_notification(
|
||||||
session_id: String,
|
session_id: String,
|
||||||
device_token: String,
|
device_token: String,
|
||||||
@@ -41,9 +66,17 @@ impl ApnTask {
|
|||||||
ApnTask {
|
ApnTask {
|
||||||
session_id,
|
session_id,
|
||||||
device_token,
|
device_token,
|
||||||
title: notification.author.to_string(),
|
title: ApnTask::format_title(notification),
|
||||||
body: notification.body.to_string(),
|
body: notification.body.to_string(),
|
||||||
thread_id: notification.tag.to_string(),
|
thread_id: notification.tag.to_string(),
|
||||||
|
category: "ALERT_MESSAGE".to_string(),
|
||||||
|
payload: ApnCustomPayload {
|
||||||
|
message: (),
|
||||||
|
serverId: (),
|
||||||
|
authorAvatar: notification.icon.to_string(),
|
||||||
|
authorDisplayName: notification.author.to_string(),
|
||||||
|
channelName: (),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -67,15 +100,24 @@ pub async fn worker(db: Database) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let endpoint = if config.api.apn.sandbox {
|
||||||
|
Endpoint::Sandbox
|
||||||
|
} else {
|
||||||
|
Endpoint::Production
|
||||||
|
};
|
||||||
|
|
||||||
let pkcs8 = engine::general_purpose::STANDARD
|
let pkcs8 = engine::general_purpose::STANDARD
|
||||||
.decode(config.api.apn.pkcs8)
|
.decode(config.api.apn.pkcs8)
|
||||||
.expect("valid `pcks8`");
|
.expect("valid `pcks8`");
|
||||||
|
|
||||||
|
let client_config = ClientConfig::default();
|
||||||
|
client_config.endpoint = endpoint;
|
||||||
|
|
||||||
let client = Client::token(
|
let client = Client::token(
|
||||||
&mut Cursor::new(pkcs8),
|
&mut Cursor::new(pkcs8),
|
||||||
config.api.apn.key_id,
|
config.api.apn.key_id,
|
||||||
config.api.apn.team_id,
|
config.api.apn.team_id,
|
||||||
ClientConfig::default(),
|
client_config,
|
||||||
)
|
)
|
||||||
.expect("could not create APN client");
|
.expect("could not create APN client");
|
||||||
|
|
||||||
@@ -85,8 +127,14 @@ pub async fn worker(db: Database) {
|
|||||||
.set_title(&task.title)
|
.set_title(&task.title)
|
||||||
.set_body(&task.body)
|
.set_body(&task.body)
|
||||||
.set_thread_id(&task.thread_id)
|
.set_thread_id(&task.thread_id)
|
||||||
|
.set_category(&task.category)
|
||||||
|
.set_mutable_content() // allows the service extension to execute
|
||||||
.build(&task.device_token, Default::default());
|
.build(&task.device_token, Default::default());
|
||||||
|
|
||||||
|
payload.data = &task.payload; // this looks like a job for someone more rust-inclined than me. -tom
|
||||||
|
|
||||||
|
println!("sending APNS payload: {:?}", payload.data);
|
||||||
|
|
||||||
if let Err(err) = client.send(payload).await {
|
if let Err(err) = client.send(payload).await {
|
||||||
match err {
|
match err {
|
||||||
Error::ResponseError(Response {
|
Error::ResponseError(Response {
|
||||||
|
|||||||
Reference in New Issue
Block a user