Envoyer et recevoir des images
Product deprecation notice
Effective April 30th, 2026, Vonage In-App Messaging will no longer be available. Access for new users will be closed, and the service will be discontinued for all existing users.
If you have any questions regarding this product’s discontinuation, please contact your account manager or our support team.
Vue d'ensemble
Ce guide traite de l'envoi et de la réception d'images dans le cadre d'une conversation.
Avant de commencer, assurez-vous que ajouter le SDK à votre application et vous êtes en mesure de créer une conversation.
NOTE: A step-by-step tutorial to build a chat application is available here.
Ce guide s'appuie sur les concepts suivants :
- Événements de conversation -
messageles événements qui se déclenchent sur une conversation, une fois que vous êtes membre
Envoyer une image
Vous êtes déjà membre d'une conversation :
// Scenario #1: Send an image from a URL
conversation.sendMessage({
"message_type": "image",
"image": {
"url": "https://example.com/image.jpg"
}
}).then((event) => {
console.log("message was sent", event);
}).catch((error)=>{
console.error("error sending the message", error);
});
// Scenario #2: Upload an image from a file input to Vonage, then send
// Note: the URL will need to be downloaded using the fetch image method mentioned in the next section.
const fileInput = document.getElementById('fileInput');
const params = {
quality_ratio : "90",
medium_size_ratio: "40",
thumbnail_size_ratio: "20"
}
conversation.uploadImage(fileInput.files[0], params).then((imageRequest) => {
imageRequest.onreadystatechange = () => {
if (imageRequest.readyState === 4 && imageRequest.status === 200) {
try {
const { original, medium, thumbnail } = JSON.parse(imageRequest.responseText);
const message = {
message_type: 'image',
image: {
url: original.url ?? medium.url ?? thumbnail.url
}
}
return conversation.sendMessage(message);
} catch (error) {
console.error("error sending the image", error);
}
}
if (imageRequest.status !== 200) {
console.error("error uploading the image");
}
};
return imageRequest;
}).catch((error) => {
console.error("error uploading the image ", error);
});
fun sendImage(file: File){
client.uploadAttachment(file, object : NexmoRequestListener<NexmoImage> {
override fun onSuccess(image: NexmoImage?) {
val message = image?.original?.let { NexmoMessage.fromImage(it.url) }
if (message != null) {
conversation?.sendMessage(message, object: NexmoRequestListener<Void?> {
override fun onError(apiError: NexmoApiError) {
Log.d("TAG", "Error: failed to send message, ${apiError.message}")
}
override fun onSuccess(aVoid: Void?) {}
})
}
}
override fun onError(error: NexmoApiError) {
Log.d("TAG", "Error: Image not uploaded, ${error.message}")
}
})
}
public void sendImage(File file){
client.uploadAttachment(file, new NexmoRequestListener<NexmoImage>() {
@Override
public void onSuccess(@Nullable NexmoImage result) {
if (result != null){
NexmoMessage message = NexmoMessage.fromImage(result.getOriginal().getUrl());
conversation.sendMessage(message, new NexmoRequestListener<Void>() {
@Override
public void onError(@NonNull NexmoApiError error) {
Log.d("TAG", "Error: failed to send message, " + error.getMessage());
}
@Override
public void onSuccess(@Nullable Void result) {}
});
}
}
@Override
public void onError(@NonNull NexmoApiError error) {
Log.d("TAG", "Error: Image not uploaded, " + error.getMessage());
}
});
}
let image = UIImage(named: "file.png")
guard let imageData = image?.pngData() else { return }
client.uploadAttachment(with: .image, name: "File name", data: imageData) { error, data in
if let error = error {
print("Error sending image: \(error.localizedDescription)")
return
}
if let imageObject = data?["original"] as? [String: Any],
let imageUrl = imageObject["url"] as? String {
let imageMessage = NXMMessage(imageUrl: imageUrl)
conversation.sendMessage(imageMessage, completionHandler: { [weak self] (error) in
...
})
}
}
NSData *imageData = UIImagePNGRepresentation([UIImage imageNamed:@"file.png"]);
[self.client uploadAttachmentWithType:NXMAttachmentTypeImage
name:@"File name 2"
data:imageData
completionHandler:^(NSError * _Nullable error, NSDictionary * _Nullable data) {
if (error == nil) {
NSLog(@"Error sending image");
}
NSString *imageUrl = [data valueForKeyPath:@"original.url"];
NXMMessage *imageMessage = [[NXMMessage alloc] initWithImageUrl:imageUrl];
[conversation sendMessage:message completionHandler:^(NSError * _Nullable error) {
...
}];
}];
Recevoir l'URL d'une image
A message sera reçu lorsqu'un membre envoie une image dans une conversation :
conversation.on('message', (sender, event) => {
if (event.body.message_type === 'image'){
console.log('*** Image sender: ', sender);
console.log('*** Image event: ', event);
}
});
private val messageListener = object : NexmoMessageEventListener {
override fun onTypingEvent(typingEvent: NexmoTypingEvent) {}
override fun onMessageEvent(messageEvent: NexmoMessageEvent) {
val userName = messageEvent.embeddedInfo.user.name
val imageURL = messageEvent.message.imageUrl
Log.d("TAG", "Message received. User $userName : $imageURL")
}
override fun onAttachmentEvent(attachmentEvent: NexmoAttachmentEvent) {}
override fun onTextEvent(textEvent: NexmoTextEvent) {}
override fun onSeenReceipt(seenEvent: NexmoSeenEvent) {}
override fun onEventDeleted(deletedEvent: NexmoDeletedEvent) {}
override fun onDeliveredReceipt(deliveredEvent: NexmoDeliveredEvent) {}
}
conversation?.addMessageEventListener(messageListener)
private NexmoMessageEventListener messageListener = new NexmoMessageEventListener() {
@Override
public void onTextEvent(@NonNull NexmoTextEvent textEvent) {}
@Override
public void onMessageEvent(@NonNull NexmoMessageEvent messageEvent) {
String userName = messageEvent.getEmbeddedInfo().getUser().getName();
String imageURL = messageEvent.getMessage().getImageUrl();
Log.d("TAG", "Message received. User " + userName + " : " + imageURL);
}
@Override
public void onAttachmentEvent(@NonNull NexmoAttachmentEvent attachmentEvent) {}
@Override
public void onEventDeleted(@NonNull NexmoDeletedEvent deletedEvent) {}
@Override
public void onSeenReceipt(@NonNull NexmoSeenEvent seenEvent) {}
@Override
public void onDeliveredReceipt(@NonNull NexmoDeliveredEvent deliveredEvent) {}
@Override
public void onTypingEvent(@NonNull NexmoTypingEvent typingEvent) {}
};
conversation.addMessageEventListener(messageListener);
Add NXMConversationDelegate as an extension to a ViewController or similar, and implement conversation(_ conversation: NXMConversation, didReceive event: NXMMessageEvent):
Note: The first method below is required when implementing NXMConversationDelegate:
extension ViewController: NXMConversationDelegate {
func conversation(_ conversation: NXMConversation, didReceive error: Error) {
NSLog("Conversation error: \(error.localizedDescription)")
}
func conversation(_ conversation: NXMConversation, didReceive event: NXMMessageEvent) {
NSLog("Received image: \(event.imageUrl)")
}
}
Have a ViewController, or similar, conform to NXMConversationDelegate and implement conversation:didReceiveMessageEvent::
Note: The first method below is required when implementing NXMConversationDelegate:
- (void)conversation:(NXMConversation *)conversation didReceive:(NSError *)error {
NSLog(@"Conversation error: %@", error.localizedDescription);
}
- (void)conversation:(NXMConversation *)conversation didReceiveMessageEvent:(NXMMessageEvent *)event {
NSLog(@"Received image event: %@", event.imageUrl);
}
Télécharger des images de Vonage
Client web
Pour télécharger une image, vous devez utiliser la fonction récupérer l'image méthode.
Client mobile (Android, iOS)
Pour télécharger une image, vous devez ajouter un JWT à la demande de récupération d'image. Le JWT est transmis en tant qu'en-tête d'autorisation (Authorization: Bearer <JWT> ). Il s'agit du JWT utilisé pour connecter l'utilisateur.
Les différentes bibliothèques d'images gèrent les en-têtes de requête différemment. Vous trouverez ci-dessous des exemples complets pour les bibliothèques les plus populaires. Notez que le JWT est défini comme l'en-tête Authorization pour la requête :
// ==== LOAD IMAGE USING COIL ====
// https://github.com/coil-kt/coil
private fun loadImageUsingCoil(url: String, jwt: String, context: Context) {
imageView.load(
Uri.parse(url),
context.imageLoader,
) {
addHeader("Authorization", "bearer $jwt")
}
}
// ==== LOAD IMAGE USING GLIDE ====
// https://github.com/bumptech/glide
private fun loadImageUsingGlide(url: String, jwt: String, context: Context) {
val build = LazyHeaders.Builder()
.addHeader("Authorization", "bearer $jwt")
.build()
val glideUrl = GlideUrl(url, build)
Glide.with(context)
.load(glideUrl)
.into(imageView)
}
// ==== LOAD IMAGE USING PICASSO ====
// https://github.com/square/picasso
// Define custom Authentication interceptor
class AuthenticationInterceptor(private val jwt: String) : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response = chain.request().let {
val newRequest = it.newBuilder()
.header("Authorization", "bearer $jwt")
.build()
chain.proceed(newRequest)
}
}
// Create Picasso instance that uses the Authenticator
private fun getPicassoInstance(jwt: String): Picasso {
val okHttpClient = OkHttpClient.Builder()
.addInterceptor(AuthenticationInterceptor(jwt))
.build()
return Picasso.Builder(requireContext()).downloader(OkHttp3Downloader(okHttpClient)).build()
}
// Load image using custom picasso instance (that under the hood uses the authentication interceptor)
private fun loadImageUsingPicasso(url: String, jwt: String, context: Context) {
getPicassoInstance(jwt)
.load(url)
.into(imageView)
}
// ==== LOAD IMAGE USING GLIDE ====
// https://github.com/bumptech/glide
private void loadImageUsingGlide(String url, String jwt, Context context) {
LazyHeaders build = new LazyHeaders.Builder()
.addHeader("Authorization", "bearer " + jwt)
.build();
GlideUrl glideUrl = new GlideUrl(url, build);
Glide.with(context)
.load(glideUrl)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.into(imageView);
}
// ==== LOAD IMAGE USING PICASSO ====
// https://github.com/square/picasso
// Define custom Authentication interceptor
class AuthenticationInterceptor implements Interceptor {
private String jwt;
public AuthenticationInterceptor(String jwt) {
this.jwt = jwt;
}
@NotNull
@Override
public Response intercept(@NotNull Chain chain) throws IOException {
Request request = chain.request();
Request newRequest = request.newBuilder()
.header("Authorization", "bearer " + jwt)
.build();
return chain.proceed(newRequest);
}
}
// Create Picasso instance that uses the Authenticator
private Picasso getPicassoInstance(String jwt) {
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(new AuthenticationInterceptor(jwt))
.build();
return new Picasso.Builder(requireContext())
.downloader(new OkHttp3Downloader(okHttpClient))
.build();
}
// Load image using custom picasso instance (that under the hood uses the authentication interceptor)
private void loadImageUsingPicasso(String url, String jwt, Context context) {
getPicassoInstance(jwt)
.load(url)
.into(imageView);
}
You can download the image using URLSession:
func loadImage(urlString: String, token: String, completionHandler: @escaping (UIImage?) -> Void) {
if let url = URL(string: urlString) {
var request = URLRequest(url: url)
request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data,
let httpResponse = response as? HTTPURLResponse,
(200...299).contains(httpResponse.statusCode),
error == nil else {
completionHandler(nil)
return
}
completionHandler(UIImage(data: data))
}
task.resume()
}
}
When calling the above function make sure to update your UIImageView on the main thread:
loadImage(urlString: "IMAGE_URL", token: "JWT") { image in
if let image = image {
DispatchQueue.main.async {
self.imageView.image = image
}
}
}
You can download the image using URLSession:
- (void)loadImageWithURLString:(NSString *)urlString
token:(NSString *)token
completionHandler:(void (^_Nonnull)(UIImage * _Nullable image))completionHandler {
NSURL *url = [[NSURL alloc] initWithString:urlString];
if (url) {
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
[request setValue:[NSString stringWithFormat:@"Bearer %@", token] forHTTPHeaderField:@"Authorization"];
NSURLSessionTask *task = [NSURLSession.sharedSession dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (!error && data && response) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
if (httpResponse.statusCode >= 200 && httpResponse.statusCode <= 299) {
completionHandler([[UIImage alloc] initWithData:data]);
}
}
completionHandler(nil);
}];
[task resume];
}
}
When calling the above function make sure to update your UIImageView on the main thread:
[self loadImageWithURLString:@"IMAGE_URL" token:@"JWT" completionHandler:^(UIImage * _Nullable image) {
if (image) {
dispatch_async(dispatch_get_main_queue(), ^{
[self.imageView setImage:image];
});
}
}];