forked from jmug/stoatchat
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.apn]
|
||||
sandbox = false
|
||||
pkcs8 = ""
|
||||
key_id = ""
|
||||
team_id = ""
|
||||
|
||||
@@ -79,6 +79,7 @@ pub struct ApiFcm {
|
||||
|
||||
#[derive(Deserialize, Debug, Clone)]
|
||||
pub struct ApiApn {
|
||||
pub sandbox: bool,
|
||||
pub pkcs8: String,
|
||||
pub key_id: String,
|
||||
pub team_id: String,
|
||||
|
||||
@@ -6,13 +6,23 @@ use base64::{
|
||||
};
|
||||
use deadqueue::limited::Queue;
|
||||
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_config::config;
|
||||
use revolt_models::v0::PushNotification;
|
||||
use revolt_models::v0::{Message, PushNotification};
|
||||
|
||||
use crate::Database;
|
||||
|
||||
/// Payload information
|
||||
#[derive(Debug)]
|
||||
pub struct ApnCustomPayload {
|
||||
message: Message,
|
||||
serverId: String,
|
||||
authorAvatar: String,
|
||||
authorDisplayName: String,
|
||||
channelName: String,
|
||||
}
|
||||
|
||||
/// Task information
|
||||
#[derive(Debug)]
|
||||
pub struct ApnTask {
|
||||
@@ -30,9 +40,24 @@ pub struct ApnTask {
|
||||
|
||||
/// Thread Id
|
||||
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 {
|
||||
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(
|
||||
session_id: String,
|
||||
device_token: String,
|
||||
@@ -41,9 +66,17 @@ impl ApnTask {
|
||||
ApnTask {
|
||||
session_id,
|
||||
device_token,
|
||||
title: notification.author.to_string(),
|
||||
title: ApnTask::format_title(notification),
|
||||
body: notification.body.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;
|
||||
}
|
||||
|
||||
let endpoint = if config.api.apn.sandbox {
|
||||
Endpoint::Sandbox
|
||||
} else {
|
||||
Endpoint::Production
|
||||
};
|
||||
|
||||
let pkcs8 = engine::general_purpose::STANDARD
|
||||
.decode(config.api.apn.pkcs8)
|
||||
.expect("valid `pcks8`");
|
||||
|
||||
let client_config = ClientConfig::default();
|
||||
client_config.endpoint = endpoint;
|
||||
|
||||
let client = Client::token(
|
||||
&mut Cursor::new(pkcs8),
|
||||
config.api.apn.key_id,
|
||||
config.api.apn.team_id,
|
||||
ClientConfig::default(),
|
||||
client_config,
|
||||
)
|
||||
.expect("could not create APN client");
|
||||
|
||||
@@ -85,8 +127,14 @@ pub async fn worker(db: Database) {
|
||||
.set_title(&task.title)
|
||||
.set_body(&task.body)
|
||||
.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());
|
||||
|
||||
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 {
|
||||
match err {
|
||||
Error::ResponseError(Response {
|
||||
|
||||
Reference in New Issue
Block a user