You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I work on Expo and React, I was trying to get WhatsApp stickers working using the exposed native modules provided by react-native and the Expo SDK. This is in contrast to using specific native code dedicated to WhatsApp.
On iOS, nearly everything works except the interface with the Pasteboard. react-native only surfaces the bare minimum for setting a string to the clipboard here.
Adding support for [UIPasteboard setItems] would be a reasonable native change to make, but even that wouldn't be enough due to the usage of NSJSONSerialization which makes things much trickier.
Here is the minimum required native Objective-C code for supporting stickers on iOS:
import{NativeModulesProxy}from'@unimodules/core';NativeModulesProxy.Clipboard.copy({'net.whatsapp.third-party.sticker-pack': {/* Object created using other JS modules */}})
From what I understand, it may require changes on the WhatsApp iOS side to also accept an NSDictionary object in addition to the usual NSData generated by NSJSONSerialization.
If this is a reasonable change to make that would be awesome! Stickers would be really easy to create and customize using a non-native interface.
Further
I figured I'd also leave my findings here for anyone else trying to get this working in the future:
import{NativeModulesProxy,Platform}from"@unimodules/core";import*asApplicationfrom"expo-application";import{Asset}from"expo-asset";import*asFileSystemfrom"expo-file-system";import*asIntentLauncherfrom"expo-intent-launcher";import*asLinkingfrom"expo-linking";importConstantsfrom"expo-constants";constappUrl="whatsapp://stickerPack";/** * Requires the following in your app.config.js: * "infoPlist": { * "LSApplicationQueriesSchemes": ["whatsapp"] * } * This can be tested in bare-workflow or a custom client with `expo client:ios` */exportasyncfunctionisAvailableAsync(): Promise<boolean>{// https://github.com/WhatsApp/stickers/blob/master/iOS/README.md#structure-of-the-json-file-that-is-sent-to-whatsappreturnLinking.canOpenURL(appUrl);}functiongetAndroidReactContextPackageName(): string{returnApplication.applicationId;}asyncfunctionsendToWhatsapp(json: Record<string,any>): Promise<boolean>{if(Platform.OS==="android"){awaitIntentLauncher.startActivityAsync("com.whatsapp.intent.action.ENABLE_STICKER_PACK",{extra: {sticker_pack_id: json.identifier,sticker_pack_name: json.name,// https://github.com/WhatsApp/stickers/tree/master/Android#intent// todo: is there an alternative to a native content provider?sticker_pack_authority:
getAndroidReactContextPackageName()+".stickercontentprovider",},});returntrue;}awaitNativeModulesProxy.Clipboard.setItems([{"net.whatsapp.third-party.sticker-pack": json}],{});awaitLinking.openURL(appUrl);returntrue;}asyncfunctionreadFileAsB64(fileUri: string): Promise<string>{returnFileSystem.readAsStringAsync(fileUri,{encoding: FileSystem.EncodingType.Base64,});}// Spec https://github.com/WhatsApp/stickers/blob/master/iOS/README.mdexportasyncfunctionsend(config: {/** * The identifier should be unique and can be alphanumeric: a-z, A-Z, 0-9, and the following characters are also allowed "_", "-", "." and " ". The identifier should be less than 128 characters. */identifier: string;/** * the sticker pack's name (128 characters max) */name: string;publisher: string;stickers: {asset: number;emojis?: string[]}[];trayImage: number;/** * an overall representation of the version of the stickers and tray icon. When you update stickers or tray icon in your pack, please update this string, this will tell WhatsApp that the pack has new content and update the stickers on WhatsApp side. */image_data_version: string;/** * this tells WhatsApp that the stickers from your pack should not be cached. By default, you should keep it false. Exception is that if your app updates stickers without user actions, you can keep it true, for example: your app provides clock sticker that updates stickers every minute. */avoid_cache: boolean;// todo: publisher_website, privacy_policy_website, license_agreement_website}){constjson: Record<string,any>={identifier: config.identifier,name: config.name,publisher: config.publisher,// android// image_data_version: config.image_data_version,// avoid_cache: config.avoid_cache,};// todo: use image-manipulator to ensure PNGconstasset=Asset.fromModule(config.trayImage);awaitasset.downloadAsync();json.tray_image=awaitreadFileAsB64(asset.localUri);conststickersArray: Record<string,any>[]=[];for(conststickerofconfig.stickers){constasset=Asset.fromModule(sticker.asset);awaitasset.downloadAsync();constb64webp=awaitreadFileAsB64(asset.localUri);stickersArray.push({image_data: b64webp,emojis: sticker.emojis,});}json.stickers=stickersArray;json["ios_app_store_link"]=Constants.manifest?.ios?.appStoreUrl;json["android_play_store_link"]=Constants.manifest?.android?.playStoreUrl;returnsendToWhatsapp(json);}
The text was updated successfully, but these errors were encountered:
I work on Expo and React, I was trying to get WhatsApp stickers working using the exposed native modules provided by
react-native
and the Expo SDK. This is in contrast to using specific native code dedicated to WhatsApp.On iOS, nearly everything works except the interface with the Pasteboard.
react-native
only surfaces the bare minimum for setting a string to the clipboard here.Adding support for
[UIPasteboard setItems]
would be a reasonable native change to make, but even that wouldn't be enough due to the usage ofNSJSONSerialization
which makes things much trickier.Here is the minimum required native Objective-C code for supporting stickers on iOS:
It's concise but also very WhatsApp specific. A more ideal interface would be something like this:
On the Javascript side it can be used like this:
From what I understand, it may require changes on the WhatsApp iOS side to also accept an
NSDictionary
object in addition to the usualNSData
generated byNSJSONSerialization
.If this is a reasonable change to make that would be awesome! Stickers would be really easy to create and customize using a non-native interface.
Further
I figured I'd also leave my findings here for anyone else trying to get this working in the future:
The text was updated successfully, but these errors were encountered: