Skip to content

Commit

Permalink
Merge pull request #636 from appwrite/feat-messaging-create-push-message
Browse files Browse the repository at this point in the history
Add support for creating push messages
  • Loading branch information
TorstenDittmann authored Jan 2, 2024
2 parents c096073 + ea3c866 commit 7669ad7
Show file tree
Hide file tree
Showing 7 changed files with 313 additions and 7 deletions.
14 changes: 11 additions & 3 deletions src/routes/console/project-[project]/messaging/create.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -54,18 +54,26 @@
);
break;
case ProviderTypes.Push:
const customData: Record<string, string> = {};
const { data } = $messageParams[ProviderTypes.Push];
if (data && data.length > 0) {
data.forEach((item) => {
if (item[0] === '') return;
customData[item[0]] = item[1];
});
}
response = await sdk.forProject.client.call(
'POST',
new URL(
sdk.forProject.client.config.endpoint + '/messaging/providers/telesign'
),
new URL(sdk.forProject.client.config.endpoint + '/messaging/messages/push'),
{
'X-Appwrite-Project': sdk.forProject.client.config.project,
'content-type': 'application/json',
'X-Appwrite-Mode': 'admin'
},
{
...$messageParams[$providerType],
data: customData,
messageId
}
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import { message } from './store';
import { ProviderTypes } from '../providerType.svelte';
import SMSPreview from './smsPreview.svelte';
import PushPreview from './pushPreview.svelte';
</script>

<Container>
Expand All @@ -14,6 +15,8 @@
<EmailPreview />
{:else if $message.providerType === ProviderTypes.Sms}
<SMSPreview />
{:else if $message.providerType === ProviderTypes.Push}
<PushPreview />
{/if}
<Delete />
</Container>
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<script lang="ts">
import { CardGrid, Heading } from '$lib/components';
import { FormList, InputText, InputTextarea } from '$lib/elements/forms';
import { message } from './store';
import PushPhone from '../pushPhone.svelte';
</script>

<CardGrid>
<div class="grid-1-2-col-1 u-flex-vertical u-cross-start u-gap-16">
<Heading tag="h6" size="7">Preview</Heading>
<PushPhone title={$message.data.title} body={$message.data.body} />
</div>
<svelte:fragment slot="aside">
<FormList>
<InputText id="title" label="Title" disabled={true} bind:value={$message.data.title}>
</InputText>
<InputTextarea
id="message"
label="Message"
disabled={true}
bind:value={$message.data.body}>
</InputTextarea>
</FormList>
</svelte:fragment>

<svelte:fragment slot="actions">
<!-- TODO: Add support for editing draft messages -->
<!-- <Button disabled={$message.status !== 'draft'} on:click={() => console.log('click')}
>Edit message</Button> -->
</svelte:fragment>
</CardGrid>
16 changes: 16 additions & 0 deletions src/routes/console/project-[project]/messaging/pushPhone.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<script lang="ts">
export let title = '';
export let body = '';
</script>

<!-- TODO: Style to look like a push notification -->
<div class="phone card is-only-desktop">
<p class="body-text-1 u-bold">{title}</p>
<p class="body-text-2">{body}</p>
</div>

<style lang="scss">
.phone {
inline-size: calc(320 * 1rem / 16);
}
</style>
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
<script context="module" lang="ts">
export async function createPushMessage(params: PushMessageParams) {
const response = await sdk.forProject.client.call(
'POST',
new URL(sdk.forProject.client.config.endpoint + '/messaging/messages/push'),
{
'X-Appwrite-Project': sdk.forProject.client.config.project,
'content-type': 'application/json',
'X-Appwrite-Mode': 'admin'
},
params
);
return response.json();
}
export function validateData(data: string[][]) {
if (!data || data.length === 0) return;
if (data.length === 1 && data[0][0] === '' && data[0][1] === '') return;
const dataKeys = new Set<string>();
for (let i = 0; i < data.length; i++) {
if (data[i][0] === '') {
return 'Keys cannot be empty';
}
if (data[i][1] === '') {
return 'Values cannot be empty';
}
dataKeys.add(data[i][0]);
}
if (dataKeys.size !== data.length) {
return 'Keys must be unique';
}
return '';
}
</script>

<script lang="ts">
import { messageParams, providerType, MessageStatuses, type PushMessageParams } from './store';
import {
Button,
FormItem,
FormItemPart,
FormList,
Helper,
InputEmail,
InputRadio,
InputText,
InputTextarea,
Label
} from '$lib/elements/forms';
import { Pill } from '$lib/elements';
import { CustomId, Modal } from '$lib/components';
import { user } from '$lib/stores/user';
import { clickOnEnter } from '$lib/helpers/a11y';
import { ID } from '@appwrite.io/console';
import { sdk } from '$lib/stores/sdk';
import { ProviderTypes } from '../providerType.svelte';
import PushPhone from '../pushPhone.svelte';
import { onMount } from 'svelte';
let showCustomId = false;
let showTest = false;
let selected = 'self';
let otherEmail = '';
let dataError = '';
let customData: [string, string][] = [];
onMount(() => {
$messageParams[ProviderTypes.Push].data = customData || [['', '']];
});
async function sendTestMessage() {
const email = selected === 'self' ? $user.email : otherEmail;
console.log(email);
createPushMessage({
topics: $messageParams[ProviderTypes.Push]?.topics || [],
targets: $messageParams[ProviderTypes.Push]?.targets || [],
description: $messageParams[ProviderTypes.Push]?.description || 'Test push',
status: MessageStatuses.PROCESSING,
messageId: ID.unique(),
// TODO: properly handle the test email address
users: ['steven'],
body: $messageParams[ProviderTypes.Push]?.body || '',
title: $messageParams[ProviderTypes.Push]?.title || '',
data: $messageParams[ProviderTypes.Push]?.data || []
});
}
$: otherEmail = selected === 'self' ? '' : otherEmail;
$: customData = $messageParams[ProviderTypes.Push].data;
$: dataError = validateData(customData || []);
</script>

<div class="u-flex u-gap-24">
<FormList class="u-stretch">
<InputText
id="title"
label="Title"
placeholder="Enter title"
bind:value={$messageParams[ProviderTypes.Push]['title']}>
</InputText>
<div class="u-colum-gap-2">
<InputTextarea
id="message"
label="Message"
placeholder="Type here..."
bind:value={$messageParams[ProviderTypes.Push]['body']}>
</InputTextarea>
<!-- TODO: Add support for draft messages -->
<!-- <div class="u-flex u-main-end">
<Button text on:click={() => (showTest = true)}>Send test message</Button>
</div> -->
<Modal
title="Send test message"
bind:show={showTest}
onSubmit={sendTestMessage}
size="big">
<slot />
<InputRadio
label={$user.phone}
bind:group={selected}
value="self"
id="self"
name="selected" />
<InputRadio
label="Other"
bind:group={selected}
value="other"
id="other"
name="selected"
fullWidth>
<svelte:fragment slot="description">
Enter the phone number to which the test message will be
<div
on:click={() => (selected = 'other')}
on:keyup|self={clickOnEnter}
role="button"
tabindex="0">
<InputEmail
showLabel={false}
id="email"
label="Email"
placeholder="Enter email"
bind:value={otherEmail} />
</div>
</svelte:fragment>
</InputRadio>

<svelte:fragment slot="footer">
<Button secondary on:click={() => (showTest = false)}>Cancel</Button>
<Button submit>Send</Button>
</svelte:fragment>
</Modal>
</div>
<form class="form">
<Label>Custom data <span class="u-color-text-gray">(Optional)</span></Label>
<div class=" u-grid u-gap-8">
<ul class="form-list" style="--p-form-list-gap: 1rem">
{#each customData || [] as _, rowIndex}
<FormItem isMultiple>
<InputText
id={`${rowIndex}-key`}
isMultiple
fullWidth
bind:value={$messageParams[ProviderTypes.Push].data[rowIndex][0]}
placeholder="Enter key"
label="Key"
showLabel={false} />

<InputText
id={`${rowIndex}-value`}
isMultiple
fullWidth
bind:value={$messageParams[ProviderTypes.Push].data[rowIndex][1]}
placeholder="Enter value"
label="Value"
showLabel={false}
required />
<FormItemPart alignEnd>
<Button
text
on:click={() => {
if (customData.length === 1) {
$messageParams[ProviderTypes.Push].data = [['', '']];
return;
}

$messageParams[ProviderTypes.Push].data = customData.filter(
(_, i) => i !== rowIndex
);
}}>
<span class="icon-x" aria-hidden="true" />
</Button>
</FormItemPart>
</FormItem>
{/each}
</ul>
{#if dataError}
<Helper type="warning">{dataError}</Helper>
{/if}
<Button
noMargin
text
disabled={customData && customData[customData.length - 1][0] === ''}
on:click={() => {
$messageParams[ProviderTypes.Push].data = [...customData, ['', '']];
}}>
<span class="icon-plus" aria-hidden="true" />
<span class="text">Add data</span>
</Button>
</div>
</form>
<InputText
id="description"
label="Description"
placeholder="Enter description"
tooltip="Provide a summary of the message. Users won't see this description."
bind:value={$messageParams[$providerType]['description']}>
</InputText>
{#if !showCustomId}
<div>
<Pill button on:click={() => (showCustomId = !showCustomId)}
><span class="icon-pencil" aria-hidden="true" /><span class="text">
Message ID
</span></Pill>
</div>
{:else}
<CustomId
bind:show={showCustomId}
name="Message"
bind:id={$messageParams[$providerType].messageId}
autofocus={false} />
{/if}
</FormList>
<PushPhone
title={$messageParams[$providerType]['title']}
body={$messageParams[$providerType]['body']} />
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@
import { ProviderTypes } from '../providerType.svelte';
import EmailFormList from './emailFormList.svelte';
import SmsFormList from './smsFormList.svelte';
import PushFormList, { validateData } from './pushFormList.svelte';
async function beforeSubmit() {
}
async function beforeSubmit() {}
</script>

<WizardStep {beforeSubmit}>
<WizardStep
{beforeSubmit}
nextDisabled={$providerType === ProviderTypes.Push &&
!!validateData($messageParams[ProviderTypes.Push].data)}>
<svelte:fragment slot="title">Message</svelte:fragment>
<svelte:fragment slot="subtitle">
<!-- TODO: update documentation link -->
Expand All @@ -21,5 +24,7 @@
<EmailFormList />
{:else if $providerType === ProviderTypes.Sms}
<SmsFormList />
{:else if $providerType === ProviderTypes.Push}
<PushFormList />
{/if}
</WizardStep>
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export type SMSMessageParams = MessageParams & {
export type PushMessageParams = MessageParams & {
title: string;
body: string;
data: Record<string, string>;
data: [string, string][];
action?: string;
icon?: string;
sound?: string;
Expand Down

0 comments on commit 7669ad7

Please sign in to comment.