Skip to content

Commit

Permalink
Merge pull request #24 from zenvia/con203_instagram-sdk-node
Browse files Browse the repository at this point in the history
Include instagram
  • Loading branch information
Marcelo Vasques committed Jun 9, 2021
2 parents 9444602 + 7999dac commit 7446fbc
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ The channels that can be used to send the content are:
| RCS | X | X | | | |
| WhatsApp | X | X | X | X | X |
| Facebook | X | X | | | |
| Instagram| X | X | | | |

Use the `sendMessage` method to messages to your customers.

Expand Down
25 changes: 25 additions & 0 deletions src/lib/channels/instagram.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { AbstractChannel } from './abstract-channel';
import { ContentType, IContent, ILoggerInstance } from '../../types';

export class InstagramChannel extends AbstractChannel {

private supportedContents: ContentType[];

/**
* Returns a new `InstagramChannel` that is used to set the Instagram channel.
*
* @param token Zenvia platform token.
* @param loggerInstance If you want, you can pass your log instance.
*/
constructor(token: string, loggerInstance?: ILoggerInstance) {
super(token, 'instagram', loggerInstance);
this.supportedContents = ['text', 'file'];
}

protected contentSupportValidation(content: IContent): void | never {
if (!this.supportedContents.includes(content.type)) {
throw new Error(`Content of type ${content.type} is not supported in Instagram channel`);
}
}

}
2 changes: 2 additions & 0 deletions src/lib/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Channel, IChannel, IMessageBatch, ILoggerInstance, ISubscription, IPart
import { Logger } from '../utils/logger';
import { SmsChannel } from './channels/sms';
import { RcsChannel } from './channels/rcs';
import { InstagramChannel } from './channels/instagram';
import { FacebookChannel } from './channels/facebook';
import { WhatsAppChannel } from './channels/whatsapp';
import * as request from '../utils/request';
Expand Down Expand Up @@ -42,6 +43,7 @@ export class Client {
case 'rcs': return new RcsChannel(this.token, this.logger);
case 'facebook': return new FacebookChannel(this.token, this.logger);
case 'whatsapp': return new WhatsAppChannel(this.token, this.logger);
case 'instagram': return new InstagramChannel(this.token, this.logger);
default: throw new Error('Unsupported channel');
}
}
Expand Down
6 changes: 4 additions & 2 deletions src/types/zenvia.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// tslint:disable:prefer-array-literal
import { SmsChannel } from '../lib/channels/sms';
import { RcsChannel } from '../lib/channels/rcs';
import { InstagramChannel } from '../lib/channels/instagram';
import { FacebookChannel } from '../lib/channels/facebook';
import { WhatsAppChannel } from '../lib/channels/whatsapp';
import { TextContent } from '../lib/contents/text';
Expand All @@ -16,6 +17,7 @@ import { MessageStatusSubscription } from '../lib/subscriptions/message-status';
export {
SmsChannel,
RcsChannel,
InstagramChannel,
FacebookChannel,
WhatsAppChannel,
TextContent,
Expand All @@ -29,7 +31,7 @@ export {
MessageStatusSubscription,
};

export type Channel = 'sms' | 'whatsapp' | 'facebook' | 'rcs';
export type Channel = 'sms' | 'whatsapp' | 'facebook' | 'rcs' | 'instagram';
export type ContentType = 'text' | 'file' | 'template' | 'contacts' | 'location' | 'json';
export type MessageType = 'message' | 'notification';
export type MessageDirection = 'IN' | 'OUT';
Expand Down Expand Up @@ -334,7 +336,7 @@ export interface IButtonsItems {
}

export interface IChannels {
type: 'WHATSAPP' | 'FACEBOOK' | 'SMS' | 'RCS';
type: 'WHATSAPP' | 'FACEBOOK' | 'SMS' | 'RCS' | 'INSTAGRAM';
status: 'APPROVED' | 'REFUSED' | 'PENDING' | 'CANCELED';
senderId: string;
whatsapp: any;
Expand Down
122 changes: 122 additions & 0 deletions test/lib/client.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,128 @@ describe('Client', () => {

});

describe('Instagram Channel', () => {

it('should send message with text content', async () => {
const expectedMessage = {
from: 'FROM',
to: 'TO',
contents: [
{
type: 'text',
text: 'some text message',
},
],
};
const zenviaNock = nock('https://api.zenvia.com')
.post('/v2/channels/instagram/messages', expectedMessage)
.matchHeader('X-API-Token', 'SOME_TOKEN')
.reply(200, expectedMessage);

const client = new Client('SOME_TOKEN');
const rcs = client.getChannel('instagram');
const content = new TextContent('some text message');
const actualMessageResponse = await rcs.sendMessage('FROM', 'TO', content);
zenviaNock.isDone().should.be.true;
actualMessageResponse.should.be.deep.equal(expectedMessage);
});

it('should send message with an array of text content', async () => {
const expectedMessage = {
from: 'FROM',
to: 'TO',
contents: [
{
type: 'text',
text: 'first text message',
},
{
type: 'text',
text: 'second text message',
},
],
};
const zenviaNock = nock('https://api.zenvia.com')
.post('/v2/channels/instagram/messages', expectedMessage)
.matchHeader('X-API-Token', 'SOME_TOKEN')
.reply(200, expectedMessage);

const client = new Client('SOME_TOKEN');
const rcs = client.getChannel('instagram');
const contents = [new TextContent('first text message'), new TextContent('second text message')];
const actualMessageResponse = await rcs.sendMessage('FROM', 'TO', ...contents);
zenviaNock.isDone().should.be.true;
actualMessageResponse.should.be.deep.equal(expectedMessage);
});

it('should send message with file content', async () => {
const expectedMessage = {
from: 'FROM',
to: 'TO',
contents: [
{
type: 'file',
fileUrl: 'http://server.com/file.jpeg',
fileMimeType: 'image/jpeg',
fileCaption: 'some file caption',
},
],
};
const zenviaNock = nock('https://api.zenvia.com')
.post('/v2/channels/instagram/messages', expectedMessage)
.matchHeader('X-API-Token', 'SOME_TOKEN')
.reply(200, expectedMessage);

const client = new Client('SOME_TOKEN');
const rcs = client.getChannel('instagram');
const content = new FileContent('http://server.com/file.jpeg', 'image/jpeg', 'some file caption');
const actualMessageResponse = await rcs.sendMessage('FROM', 'TO', content);
zenviaNock.isDone().should.be.true;
actualMessageResponse.should.be.deep.equal(expectedMessage);
});

it('should fail when trying to send template content', async () => {
const client = new Client('SOME_TOKEN');
const rcs = client.getChannel('instagram');
const content = new TemplateContent('templateId', {});

try {
await rcs.sendMessage('FROM', 'TO', content);
throw new Error('An expected error was not thrown');
} catch (error) {
error.message.should.be.deep.equal('Content of type template is not supported in Instagram channel');
}
});

it('should fail when trying to send location content', async () => {
const client = new Client('SOME_TOKEN');
const rcs = client.getChannel('instagram');
const content = new LocationContent(-46.511170, -23.442930, 'Name of location', 'Address of location', 'URL');

try {
await rcs.sendMessage('FROM', 'TO', content);
throw new Error('An expected error was not thrown');
} catch (error) {
error.message.should.be.deep.equal('Content of type location is not supported in Instagram channel');
}
});

it('should fail when trying to send contacts content', async () => {
const client = new Client('SOME_TOKEN');
const rcs = client.getChannel('instagram');
const content = new ContactsContent([]);

try {
await rcs.sendMessage('FROM', 'TO', content);
throw new Error('An expected error was not thrown');
} catch (error) {
error.message.should.be.deep.equal('Content of type contacts is not supported in Instagram channel');
}
});

});


describe('Facebook Channel', () => {

it('should send message with text content', async () => {
Expand Down

0 comments on commit 7446fbc

Please sign in to comment.