@xmtp/broadcast-sdk
Advanced tools
Comparing version 0.1.0 to 0.2.0
import { Client, Conversation } from '@xmtp/xmtp-js'; | ||
type Conversations = Client["conversations"]; | ||
type CreateConvo = Conversations["newConversation"]; | ||
type CreateConversationArgs = Parameters<CreateConvo>; | ||
type RemoveFirstFromTuple<T extends unknown[]> = T extends [ | ||
unknown, | ||
...infer Rest | ||
] ? Rest : []; | ||
type AdditionalConversationArgs = RemoveFirstFromTuple<CreateConversationArgs>; | ||
type OnBatchStart = (addresses: string[]) => void; | ||
type OnBatchComplete = (addresses: string[]) => void; | ||
type OnBroadcastComplete = () => void; | ||
type OnCantMessageAddress = (address: string) => void; | ||
type OnCanMessageAddressesUpdate = (addresses: string[]) => void; | ||
type OnMessageSending<ContentTypes = unknown> = (address: string) => Promise<Exclude<ContentTypes, undefined>>; | ||
type OnMessageFailed = (address: string) => void; | ||
type OnMessageSent = (address: string) => void; | ||
type OnDelay = (ms: number) => void; | ||
type OnWillConversationCreate = (address: string) => Promise<AdditionalConversationArgs>; | ||
interface BroadcastConstructorParams<ContentTypes = unknown> { | ||
@@ -9,12 +27,44 @@ client: Client<ContentTypes>; | ||
rateLimitTime?: number; | ||
onBatchStart?: (addresses: string[]) => void; | ||
onBatchComplete?: (addresses: string[]) => void; | ||
onBroadcastComplete?: () => void; | ||
onCantMessageAddress?: (address: string) => void; | ||
onCanMessageAddreses?: (addresses: string[]) => void; | ||
onMessageSending?: (address: string) => void; | ||
onMessageFailed?: (address: string) => void; | ||
onMessageSent?: (address: string) => void; | ||
onCanMessageAddressesUpdate?: (addresses: string[]) => void; | ||
onDelay?: (ms: number) => void; | ||
/** | ||
* Called when a batch of addresses is about to be sent | ||
*/ | ||
onBatchStart?: OnBatchStart; | ||
/** | ||
* Called when a batch of addresses has been sent/failed | ||
*/ | ||
onBatchComplete?: OnBatchComplete; | ||
/** | ||
* Called when all addresses have been sent/failed | ||
*/ | ||
onBroadcastComplete?: OnBroadcastComplete; | ||
/** | ||
* Called when an address can't be messaged | ||
*/ | ||
onCantMessageAddress?: OnCantMessageAddress; | ||
/** | ||
* Called when the list of addresses that can be messaged is updated, this is useful for caching | ||
*/ | ||
onCanMessageAddressesUpdate?: OnCanMessageAddressesUpdate; | ||
/** | ||
* Called when a message is about to be sent | ||
* This can be used to return a different message for each address | ||
*/ | ||
onMessageSending?: OnMessageSending<ContentTypes>; | ||
/** | ||
* Called when a message fails to send | ||
*/ | ||
onMessageFailed?: OnMessageFailed; | ||
/** | ||
* Called when a message is successfully sent | ||
*/ | ||
onMessageSent?: OnMessageSent; | ||
/** | ||
* Called when a delay is about to happen | ||
*/ | ||
onDelay?: OnDelay; | ||
/** | ||
* Called when a new conversation is about to be created | ||
* This can be used to add additional payload for individual addresses like conversation context and consent proofs | ||
*/ | ||
onWillConversationCreate?: OnWillConversationCreate; | ||
} | ||
@@ -37,36 +87,41 @@ interface BroadcastOptions { | ||
*/ | ||
onBatchStart?: (addresses: string[]) => void; | ||
onBatchStart?: OnBatchStart; | ||
/** | ||
* Called when a batch of addresses has been sent/failed | ||
*/ | ||
onBatchComplete?: (addresses: string[]) => void; | ||
onBatchComplete?: OnBatchComplete; | ||
/** | ||
* Called when all addresses have been sent/failed | ||
*/ | ||
onBroadcastComplete?: () => void; | ||
onBroadcastComplete?: OnBroadcastComplete; | ||
/** | ||
* Called when an address can't be messaged | ||
*/ | ||
onCantMessageAddress?: (address: string) => void; | ||
onCantMessageAddress?: OnCantMessageAddress; | ||
/** | ||
* Called when a message is about to be sent | ||
*/ | ||
onMessageSending?: (address: string) => void; | ||
onMessageSending?: OnMessageSending<ContentTypes>; | ||
/** | ||
* Called when a message fails to send | ||
*/ | ||
onMessageFailed?: (address: string) => void; | ||
onMessageFailed?: OnMessageFailed; | ||
/** | ||
* Called when a message is successfully sent | ||
*/ | ||
onMessageSent?: (address: string) => void; | ||
onMessageSent?: OnMessageSent; | ||
/** | ||
* Called when the list of addresses that can be messaged is updated, this is useful for caching | ||
*/ | ||
onCanMessageAddressesUpdate?: (addresses: string[]) => void; | ||
onCanMessageAddressesUpdate?: OnCanMessageAddressesUpdate; | ||
/** | ||
* Called when a delay is about to happen | ||
*/ | ||
onDelay?: (ms: number) => void; | ||
constructor({ client, addresses, cachedCanMessageAddresses, rateLimitAmount, rateLimitTime, onBatchStart, onBatchComplete, onBroadcastComplete, onCantMessageAddress, onMessageSending, onMessageFailed, onMessageSent, onCanMessageAddressesUpdate, onDelay, }: BroadcastConstructorParams<ContentTypes>); | ||
onDelay?: OnDelay; | ||
/** | ||
* Called when a new conversation is about to be created | ||
* This can be used to add additional payload for individual addresses like conversation context and consent proofs | ||
*/ | ||
onWillConversationCreate?: OnWillConversationCreate; | ||
constructor({ client, addresses, cachedCanMessageAddresses, rateLimitAmount, rateLimitTime, onBatchStart, onBatchComplete, onBroadcastComplete, onCantMessageAddress, onMessageSending, onMessageFailed, onMessageSent, onCanMessageAddressesUpdate, onDelay, onWillConversationCreate, }: BroadcastConstructorParams<ContentTypes>); | ||
broadcast: (messages: Exclude<ContentTypes, undefined>[], options: BroadcastOptions) => Promise<void>; | ||
@@ -81,13 +136,14 @@ private handleBatch; | ||
setRateLimitTime(time: number): void; | ||
setOnBatchStart(callback: (addresses: string[]) => void): void; | ||
setOnBatchComplete(callback: (addresses: string[]) => void): void; | ||
setOnBroadcastComplete(callback: () => void): void; | ||
setOnCantMessageAddress(callback: (address: string) => void): void; | ||
setOnMessageSending(callback: (address: string) => void): void; | ||
setOnMessageFailed(callback: (address: string) => void): void; | ||
setOnMessageSent(callback: (address: string) => void): void; | ||
setOnCanMessageAddressesUpdate(callback: (addresses: string[]) => void): void; | ||
setOnDelay(callback: (ms: number) => void): void; | ||
setOnBatchStart(callback: OnBatchStart): void; | ||
setOnBatchComplete(callback: OnBatchComplete): void; | ||
setOnBroadcastComplete(callback: OnBroadcastComplete): void; | ||
setOnCantMessageAddress(callback: OnCantMessageAddress): void; | ||
setOnMessageSending(callback: OnMessageSending<ContentTypes>): void; | ||
setOnMessageFailed(callback: OnMessageFailed): void; | ||
setOnMessageSent(callback: OnMessageSent): void; | ||
setOnCanMessageAddressesUpdate(callback: OnCanMessageAddressesUpdate): void; | ||
setOnDelay(callback: OnDelay): void; | ||
setOnWillConversationCreate(callback: OnWillConversationCreate): void; | ||
} | ||
export { BroadcastClient, type BroadcastConstructorParams, type BroadcastOptions }; | ||
export { BroadcastClient, type BroadcastConstructorParams, type BroadcastOptions, type OnBatchComplete, type OnBatchStart, type OnBroadcastComplete, type OnCanMessageAddressesUpdate, type OnCantMessageAddress, type OnDelay, type OnMessageFailed, type OnMessageSending, type OnMessageSent, type OnWillConversationCreate }; |
const GENERAL_RATE_LIMIT = 10000; | ||
class BroadcastClient { | ||
constructor({ client, addresses, cachedCanMessageAddresses, rateLimitAmount = 1000, rateLimitTime = 1000 * 60 * 5, onBatchStart, onBatchComplete, onBroadcastComplete, onCantMessageAddress, onMessageSending, onMessageFailed, onMessageSent, onCanMessageAddressesUpdate, onDelay, }) { | ||
constructor({ client, addresses, cachedCanMessageAddresses, rateLimitAmount = 1000, rateLimitTime = 1000 * 60 * 5, onBatchStart, onBatchComplete, onBroadcastComplete, onCantMessageAddress, onMessageSending, onMessageFailed, onMessageSent, onCanMessageAddressesUpdate, onDelay, onWillConversationCreate, }) { | ||
this.batches = []; | ||
@@ -44,9 +44,9 @@ this.errorBatch = []; | ||
if (!conversation) { | ||
conversation = | ||
await this.client.conversations.newConversation(address); | ||
const newConversationArgs = await this.onWillConversationCreate?.(address); | ||
conversation = await this.client.conversations.newConversation(address, ...(newConversationArgs ?? [])); | ||
this.conversationMapping.set(address, conversation); | ||
} | ||
for (const message of messages) { | ||
this.onMessageSending?.(address); | ||
await conversation.send(message); | ||
const personalizedMessage = await this.onMessageSending?.(address); | ||
await conversation.send(personalizedMessage || message); | ||
} | ||
@@ -74,5 +74,7 @@ this.onMessageSent?.(address); | ||
try { | ||
const conversation = await this.client.conversations.newConversation(address); | ||
const newConversationArgs = await this.onWillConversationCreate?.(address); | ||
const conversation = await this.client.conversations.newConversation(address, ...(newConversationArgs ?? [])); | ||
for (const message of messages) { | ||
await conversation.send(message); | ||
const personalizedMessage = await this.onMessageSending?.(address); | ||
await conversation.send(personalizedMessage ?? message); | ||
} | ||
@@ -166,2 +168,3 @@ this.onMessageSent?.(address); | ||
this.onDelay = onDelay; | ||
this.onWillConversationCreate = onWillConversationCreate; | ||
} | ||
@@ -204,2 +207,5 @@ setAddresses(addresses) { | ||
} | ||
setOnWillConversationCreate(callback) { | ||
this.onWillConversationCreate = callback; | ||
} | ||
} | ||
@@ -206,0 +212,0 @@ |
{ | ||
"name": "@xmtp/broadcast-sdk", | ||
"version": "0.1.0", | ||
"version": "0.2.0", | ||
"description": "Helper package for broadcasting XMTP messages to subscribers", | ||
@@ -40,3 +40,3 @@ "type": "module", | ||
"@rollup/plugin-typescript": "^11.1.6", | ||
"@xmtp/xmtp-js": "^11.3.12", | ||
"@xmtp/xmtp-js": "^11.6.3", | ||
"ethers": "^6.10.0", | ||
@@ -43,0 +43,0 @@ "rollup": "^4.13.0", |
# Broadcast SDK | ||
## Introduction | ||
User the Broadcast SDK to broadcast to thousands of your subscribers | ||
The Broadcast SDK attempts to take away the need to handle Rate Limiting logic while also allowing integrators information about the broadcast and current statuses | ||
Recommended to use with GRPC client and client caching like the Redis Client | ||
## Installation | ||
@@ -12,5 +19,12 @@ ``` | ||
import { BroadcastClient } from "@xmtp/broadcast-sdk" | ||
// It is highly recommended to use the GRPC client | ||
const client = await Client.create(wallet) | ||
// It is highly recommended to use the GRPC client and base a base persistence | ||
import { GrpcApiClient } from "@xmtp/grpc-api-client"; | ||
import { RedisPersistence } from "@xmtp/redis-persistence"; | ||
const client = await Client.create(wallet, { | ||
apiClientFactory: GrpcApiClient.fromOptions, | ||
basePersistence: new RedisPersistence(redis, "xmtp:"), | ||
}) | ||
const broadcastClient = new BroadcastClient({ | ||
@@ -17,0 +31,0 @@ client, |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
40889
566
36