Skip to content

Commit

Permalink
Conversation API support (#13)
Browse files Browse the repository at this point in the history
* DEVEXP-272: Conversation API - First commit

* DEVEXP-274: Conversation API - Write tests (#14)

* DEVEXP-276: Conversation API - Add example files (#15)

* DEVEXP-288: Support Callback Events in Conversation API (#16)

* Support multiple regions for the conversation API (#17)

* DEVEXP-295: Refactor channel credentials interface (#18)

* DEVEXP-290: Support Templates API v1 and v2 (#20)

* Revive dates
  • Loading branch information
asein-sinch authored Feb 14, 2024
1 parent 9d9e45b commit 2ed277d
Show file tree
Hide file tree
Showing 398 changed files with 10,744 additions and 166 deletions.
20 changes: 19 additions & 1 deletion examples/simple-examples/.env.template
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,32 @@ SMS_REGION=Value to determine according to your use case (default will be 'us')
# Application credentials for Verification and Voice APIs
SINCH_APPLICATION_KEY=application-key found at https://dashboard.sinch.com/verification/apps
SINCH_APPLICATION_SECRET=application-secret found at https://dashboard.sinch.com/verification/apps
# Properties to fill according to some API responses
# The phone number you will use for your tests
PHONE_NUMBER=phone-number to fill with one of your numbers rented with the Numbers API
NUMBER_CALLBACK_URL=URL to receive callbacks relative a number you own
# Generally, you phone number to interact with the API
RECIPIENT_PHONE_NUMBER=phone-number to fill with the number to which you want to send a batch with the SMS API
## SMS API
BATCH_ID=batch-id to fill with one the batches created with the SMS API
GROUP_ID=group-id to fill with one of the groups created with the SMS API
INBOUND_ID=inbound-id to fill with one of the ids found when listing inbound messages with the SMS API
## Verification API
VERIFICATION_ID=verification-id to fill with the verification started with the Verification API
VERIFICATION_IDENTITY=verification-identity to fill with the identity of the user
VERIFICATION_REFERENCE=verification-reference to add when starting a verification or getting its status
VERIFICATION_CODE=verification-code received for a verification via SMS or callout
VERIFICATION_CLI=verification-cli received for a verification via flashCall
## Voice API
CALL_ID=call_id to fill with one of the callouts created with the Voice API
CONFERENCE_ID=unique identifier of the conference you want to interact with
VOICE_CALLBACK_URL=URL found in the Voice dashboard to handle webhooks
## Conversation API
CONVERSATION_APP_ID=app_id (Conversation App) to fill with one of the Conversation App created with the Conversation API or in the Dashboard
CONVERSATION_CONTACT_ID=contact_id to fill with one of the contacts created by the Contact API or the Conversation API
MESSENGER_USER_ID=identity on the MESSENGER channel (can be found on a desktop by selecting a user: the user id will be in the URL)
MESSENGER_TOKEN=static_token to define credentials for a MESSENGER channel
CONVERSATION_ID=conversation_id to fill with one of the conversations created with the Conversation API
MESSAGE_ID=message_id to fill with one of the messages sent or injected with the Conversation API
TEMPLATE_ID=template_id to fill with one of the templates created with the Templates API (v1 or v2)
WEBHOOK_ID=webhook_id to fill with one of the webhooks created with the Conversation API or the Dashboard
WEBHOOK_TARGET=target URL where the events should be sent to
196 changes: 140 additions & 56 deletions examples/simple-examples/README.md

Large diffs are not rendered by default.

42 changes: 42 additions & 0 deletions examples/simple-examples/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,48 @@
"build": "yarn run clean && yarn run compile",
"clean": "rimraf dist tsconfig.tsbuildinfo",
"compile": "tsc --build --verbose",
"conversation:app:create": "ts-node src/conversation/app/create.ts",
"conversation:app:get": "ts-node src/conversation/app/get.ts",
"conversation:app:list": "ts-node src/conversation/app/list.ts",
"conversation:app:update": "ts-node src/conversation/app/update.ts pretty",
"conversation:app:delete": "ts-node src/conversation/app/delete.ts",
"conversation:contact:create": "ts-node src/conversation/contact/create.ts",
"conversation:contact:get": "ts-node src/conversation/contact/get.ts",
"conversation:contact:list": "ts-node src/conversation/contact/list.ts",
"conversation:contact:update": "ts-node src/conversation/contact/update.ts",
"conversation:contact:merge": "ts-node src/conversation/contact/merge.ts",
"conversation:contact:getChannelProfile": "ts-node src/conversation/contact/getChannelProfile.ts",
"conversation:contact:delete": "ts-node src/conversation/contact/delete.ts",
"conversation:messages:send": "ts-node src/conversation/messages/send.ts",
"conversation:messages:get": "ts-node src/conversation/messages/get.ts",
"conversation:messages:list": "ts-node src/conversation/messages/list.ts",
"conversation:messages:delete": "ts-node src/conversation/messages/delete.ts",
"conversation:conversation:create": "ts-node src/conversation/conversation/create.ts",
"conversation:conversation:get": "ts-node src/conversation/conversation/get.ts",
"conversation:conversation:list": "ts-node src/conversation/conversation/list.ts",
"conversation:conversation:injectMessage": "ts-node src/conversation/conversation/injectMessage.ts",
"conversation:conversation:update": "ts-node src/conversation/conversation/update.ts",
"conversation:conversation:stop": "ts-node src/conversation/conversation/stop.ts",
"conversation:conversation:delete": "ts-node src/conversation/conversation/delete.ts",
"conversation:events:send": "ts-node src/conversation/events/send.ts",
"conversation:transcoding:transcode": "ts-node src/conversation/transcoding/transcode.ts",
"conversation:capability:lookup": "ts-node src/conversation/capability/lookup.ts",
"conversation:webhooks:create": "ts-node src/conversation/webhooks/create.ts",
"conversation:webhooks:get": "ts-node src/conversation/webhooks/get.ts",
"conversation:webhooks:list": "ts-node src/conversation/webhooks/list.ts",
"conversation:webhooks:update": "ts-node src/conversation/webhooks/update.ts",
"conversation:webhooks:delete": "ts-node src/conversation/webhooks/delete.ts",
"conversation:templatev1:create": "ts-node src/conversation/templates-v1/create.ts",
"conversation:templatev1:get": "ts-node src/conversation/templates-v1/get.ts",
"conversation:templatev1:list": "ts-node src/conversation/templates-v1/list.ts",
"conversation:templatev1:update": "ts-node src/conversation/templates-v1/update.ts",
"conversation:templatev1:delete": "ts-node src/conversation/templates-v1/delete.ts",
"conversation:templatev2:create": "ts-node src/conversation/templates-v2/create.ts",
"conversation:templatev2:get": "ts-node src/conversation/templates-v2/get.ts",
"conversation:templatev2:list": "ts-node src/conversation/templates-v2/list.ts pretty",
"conversation:templatev2:listTranslations": "ts-node src/conversation/templates-v2/list-translations.ts pretty",
"conversation:templatev2:update": "ts-node src/conversation/templates-v2/update.ts",
"conversation:templatev2:delete": "ts-node src/conversation/templates-v2/delete.ts",
"numbers:regions:list": "ts-node src/numbers/regions/list.ts",
"numbers:available:list": "ts-node src/numbers/available/list.ts",
"numbers:available:checkAvailability": "ts-node src/numbers/available/checkAvailability.ts",
Expand Down
36 changes: 36 additions & 0 deletions examples/simple-examples/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,42 @@ export const getVoiceCallBackUrl = (): string => {
return readVariable('VOICE_CALLBACK_URL');
};

export const getAppIdFromConfig = () => {
return readVariable('CONVERSATION_APP_ID');
};

export const getContactIdFromConfig = () => {
return readVariable('CONVERSATION_CONTACT_ID');
};

export const getMessengerTokenFormConfig = () => {
return readVariable('MESSENGER_TOKEN');
};

export const getMessengerUserIdFromConfig = () => {
return readVariable('MESSENGER_USER_ID');
};

export const getConversationIdFromConfig = () => {
return readVariable('CONVERSATION_ID');
};

export const getMessageIdFromConfig = () => {
return readVariable('MESSAGE_ID');
};

export const getWebhookIdFromConfig = () => {
return readVariable('WEBHOOK_ID');
};

export const getWebhookTargetFromConfig = () => {
return readVariable('WEBHOOK_TARGET');
};

export const getTemplateIdFromConfig = () => {
return readVariable('TEMPLATE_ID');
};

const readVariable = ( name: string): string => {
const value = process.env[name];
if (!value) {
Expand Down
41 changes: 41 additions & 0 deletions examples/simple-examples/src/conversation/app/create.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { CreateAppRequestData } from '@sinch/sdk-core';
import { getMessengerTokenFormConfig, getPrintFormat, initClient, printFullResponse } from '../../config';

(async () => {
console.log('*****************');
console.log('* App_CreateApp *');
console.log('*****************');

const messengerToken = getMessengerTokenFormConfig();

const requestData: CreateAppRequestData = {
appCreateRequestBody: {
display_name: 'New app created with the Node.js SDK',
channel_credentials: [
{
channel: 'MESSENGER',
static_token: {
token: messengerToken,
},
},
],
conversation_metadata_report_view: 'FULL',
retention_policy: {
retention_type: 'CONVERSATION_EXPIRE_POLICY',
ttl_days: 60,
},
},
};

const sinchClient = initClient();
const response = await sinchClient.conversation.app.create(requestData);

const printFormat = getPrintFormat(process.argv);

if (printFormat === 'pretty') {
console.log(`New app created with the id '${response.id}'`);
} else {
printFullResponse(response);
}
console.log(`You may want to update your .env file with the following value: CONVERSATION_APP_ID=${response.id}`);
})();
20 changes: 20 additions & 0 deletions examples/simple-examples/src/conversation/app/delete.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { DeleteAppRequestData } from '@sinch/sdk-core';
import { getAppIdFromConfig, initClient, printFullResponse } from '../../config';

(async () => {
console.log('*****************');
console.log('* App_DeleteApp *');
console.log('*****************');

const appId = getAppIdFromConfig();

const requestData: DeleteAppRequestData = {
app_id: appId,
};

const sinchClient = initClient();
const response = await sinchClient.conversation.app.delete(requestData);

printFullResponse(response);

})();
26 changes: 26 additions & 0 deletions examples/simple-examples/src/conversation/app/get.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { GetAppRequestData } from '@sinch/sdk-core';
import { getAppIdFromConfig, getPrintFormat, initClient, printFullResponse } from '../../config';

(async () => {
console.log('**************');
console.log('* App_GetApp *');
console.log('**************');

const appId = getAppIdFromConfig();

const requestData: GetAppRequestData = {
app_id: appId,
};

const sinchClient = initClient();
const response = await sinchClient.conversation.app.get(requestData);

const printFormat = getPrintFormat(process.argv);

if (printFormat === 'pretty') {
console.log(`The app with the id '${response.id}' is named '${response.display_name}'`);
} else {
printFullResponse(response);
}

})();
24 changes: 24 additions & 0 deletions examples/simple-examples/src/conversation/app/list.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { ListAppsRequestData } from '@sinch/sdk-core';
import { getPrintFormat, initClient, printFullResponse } from '../../config';

(async () => {
console.log('****************');
console.log('* App_ListApps *');
console.log('****************');

const requestData: ListAppsRequestData= {};

const sinchClient = initClient();
const response = await sinchClient.conversation.app.list(requestData);

const printFormat = getPrintFormat(process.argv);

if (printFormat === 'pretty') {
console.log(response.apps
? response.apps.map((app) => `'${app.id}': ${app.display_name}`).join('\n')
: 'No Conversation Applications were found');
} else {
printFullResponse(response);
}

})();
50 changes: 50 additions & 0 deletions examples/simple-examples/src/conversation/app/update.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { UpdateAppRequestData } from '@sinch/sdk-core';
import {
getAppIdFromConfig, getMessengerTokenFormConfig,
getPrintFormat,
initClient,
printFullResponse,
} from '../../config';

(async () => {
console.log('*****************');
console.log('* App_UpdateApp *');
console.log('*****************');

const appId = getAppIdFromConfig();

const requestData: UpdateAppRequestData = {
app_id: appId,
update_mask: ['display_name', 'conversation_metadata_report_view'],
appUpdateRequestBody: {
display_name: 'Updated name by the Node.js SDK',
conversation_metadata_report_view: 'NONE',
channel_credentials: [
{
channel: 'MESSENGER',
static_token: {
token: 'new token (invalid) - should not be updated thanks to the mask',
},
},
],

},
};

const sinchClient = initClient();
const response = await sinchClient.conversation.app.update(requestData);

const printFormat = getPrintFormat(process.argv);

if (printFormat === 'pretty') {
console.log(`App updated! New name: '${response.display_name}'.`);
const token = getMessengerTokenFormConfig();
const channelCredentials = response.channel_credentials?.[0];
if(channelCredentials?.channel === 'MESSENGER') {
console.log(`Verifying the token (it should be unchanged):\nOLD: '${token}'\nNEW: '${channelCredentials.static_token?.token}'`);
}
} else {
printFullResponse(response);
}

})();
27 changes: 27 additions & 0 deletions examples/simple-examples/src/conversation/capability/lookup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { LookupCapabilityRequestData } from '@sinch/sdk-core';
import { getAppIdFromConfig, getContactIdFromConfig, initClient, printFullResponse } from '../../config';

(async () => {
console.log('******************************');
console.log('* Capability_QueryCapability *');
console.log('******************************');

const appId = getAppIdFromConfig();
const contactId = getContactIdFromConfig();

const requestData: LookupCapabilityRequestData = {
lookupCapabilityRequestBody: {
app_id: appId,
recipient: {
contact_id: contactId,
},
request_id: 'myPersonalId_' + new Date().getTime(),
},
};

const sinchClient = initClient();
const response = await sinchClient.conversation.capability.lookup(requestData);

printFullResponse(response);

})();
50 changes: 50 additions & 0 deletions examples/simple-examples/src/conversation/contact/create.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { CreateContactRequestData } from '@sinch/sdk-core';
import {
getAppIdFromConfig,
getMessengerUserIdFromConfig,
getPhoneNumberFromConfig,
getPrintFormat,
initClient,
printFullResponse,
} from '../../config';

(async () => {
console.log('*************************');
console.log('* Contact_CreateContact *');
console.log('*************************');

const phoneNumber = getPhoneNumberFromConfig();
const messengerUserId = getMessengerUserIdFromConfig();
const appId = getAppIdFromConfig();

const requestData: CreateContactRequestData = {
contactCreateRequestBody: {
display_name: 'New contact created with the Node.js SDK',
channel_identities: [
{
identity: messengerUserId,
channel: 'MESSENGER',
app_id:appId,
},
{
identity: phoneNumber,
channel: 'WHATSAPP',
},
],
channel_priority: ['MESSENGER'],
language: 'EN_US',
},
};

const sinchClient = initClient();
const response = await sinchClient.conversation.contact.create(requestData);

const printFormat = getPrintFormat(process.argv);

if (printFormat === 'pretty') {
console.log(`New contact created with the id '${response.id}'`);
} else {
printFullResponse(response);
}

})();
20 changes: 20 additions & 0 deletions examples/simple-examples/src/conversation/contact/delete.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { DeleteContactRequestData } from '@sinch/sdk-core';
import { getContactIdFromConfig, initClient, printFullResponse } from '../../config';

(async () => {
console.log('*************************');
console.log('* Contact_DeleteContact *');
console.log('*************************');

const contactId = getContactIdFromConfig();

const requestData: DeleteContactRequestData = {
contact_id: contactId,
};

const sinchClient = initClient();
const response = await sinchClient.conversation.contact.delete(requestData);

printFullResponse(response);

})();
Loading

0 comments on commit 2ed277d

Please sign in to comment.