I have a project that I want to send an SMS to a list of contacts that I have.
unfortunately, I have no idea how to do this and everything I try just does not seem to work.
I want to iterate through all the numbers in the array and then send an SMS with the IONIC SMS Plugin to these numbers.
Here is the Component that stores that contacts
constructor(private contacts: Contacts, private storage: Storage) {
this.getContact();
}
key = 'contacts';
mContacts = [
{
id: [0],
name: '',
number: ''
},
{
id: [1],
name : [''],
number: ['']
},
{
id: [2],
name : [''],
number: ['']
},
{
id: [3],
name : [''],
number: ['']
},
{
id: [4],
name : [''],
number: ['']
}
];
ngOnInit() {}
pickContact(contactId) {
this.contacts.pickContact().then((contact) => {
this.mContacts[contactId].name = contact.name.givenName;
this.mContacts[contactId].number = contact.phoneNumbers[0].value;
this.saveContacts();
});
}
saveContacts() {
this.storage.set(this.key, JSON.stringify(this.mContacts));
}
getContact() {
this.storage.get(this.key).then((val) => {
console.log('Contact Name: ', val);
if (val != null && val !== undefined) {
this.mContacts = JSON.parse(val);
}
});
}
}
and here is the function that sends the SMS. it starts with getContacts() method, as the Contacts are originally stored with the IONIC storage Plugin
EDIT
I want to retrieve the contents of the the array list from the Contacts Component, however when I call the function sendSMS() it returns a null for the number
sendSMS()
{
this.contactComponent.getContact();
let number = this.contactComponent.mContacts[0][2];
let message = "Hello World";
console.log("number=" + number + ", message= " + message);
//CONFIGURATION
var options = {
replaceLineBreaks: false, // true to replace \n by a new line, false by default
android: {
intent: 'INTENT' // send SMS with the native android SMS messaging
//intent: '' // send SMS without opening any other app
}
};
this.sms.send(number, message, options);
}
Hope this helps someone.
I decided to do this instead to make things simplier.
this.checkSMSPermission();
this.contactComponent.getContact();
const numberOne = this.contactComponent.mContacts[0].number;
const numberTwo = this.contactComponent.mContacts[1].number;
const numbeThree = this.contactComponent.mContacts[2].number;
const numberFour = this.contactComponent.mContacts[3].number;
const numberFive = this.contactComponent.mContacts[4].number;
console.log(numberOne);
// tslint:disable-next-line: max-line-length
const message = this.messageComponent.dangerMessage + ' my location is: lat: ' + this.latitude.toString() + 'lng: ' + this.longitude.toString();
console.log('number=' + numberOne + ', message= ' + message);
// CONFIGURATION
const options = {
replaceLineBreaks: false, // true to replace \n by a new line, false by default
android: {
intent: '' // send SMS with the native android SMS messaging
// intent: '' // send SMS without opening any other app
}
};
this.sms.send(numberOne,numberTwo ,numberThree,numberFour,numberFive, message, options).then(() => {
this.presentAlert('Success', 'message has been sent');
})
.catch(error => {
this.presentAlert('Error', 'Failed: ' + error);
});
}
Related
I am working on a project that requires internationalisation using AWS for translation. I currently store translations in objects that are recursively
looped through, each string being sent off for translation and then re-added to the object. I need to leave the object key untranslated.
However, I am experiencing inconsistent results, most of the time the full object is returned translated, however sometimes there are values missing,
and the ones that are missing are inconsistent as well, sometimes there, sometimes not.
I think the issue may be to do with sending hundreds of requests to the API in a short space of time.
QUESTION:
Any ideas what the issue could be?
What is the best way for translating an object using AWS Translate API?
Is there a way to send the entire object off at once keeping keys un-mutated?
Below is my code for translation:
const translateText = async ({ text = '', sourceLang, targetLang }) => {
if (!targetLang || !sourceLang) {
throw new Error('Missing source or target lang');
}
const params = {
SourceLanguageCode: sourceLang,
TargetLanguageCode: targetLang,
Text: text,
};
try {
const translationData = await translateAWS.translateText(params).promise();
return translationData.TranslatedText;
} catch (error) {
throw new Error('translateText API error :>> ', error);
}
};
const translateJSON = async ({
obj,
targetLang,
sourceLang,
displayLang = true,
}) => {
const response = {};
for (const key in obj) {
let word = '';
try {
if (typeof obj[key] === 'object') {
word = await translateJSON({
obj: obj[key],
targetLang,
sourceLang,
displayLang: false,
});
} else {
word = await translateText({ text: obj[key], sourceLang, targetLang });
}
} catch (error) {
Sentry.captureException('translateJSON API error:', error);
word = '';
}
if (displayLang) {
response[targetLang] = response[targetLang] || {};
response[targetLang][key] = word;
} else {
response[key] = word;
}
}
return response;
};
Example object to translate:
const common = {
buttons: {
readMore: 'Read more',
seeAdvice: 'See advice',
goBack: 'Go back',
accessibility: 'Accessibility',
decreaseTextSize: '- Decrease text size',
increaseTextSize: '+ Increase text size',
seeMore: 'See more',
seeLess: 'See less',
addATip: 'Add a tip',
addAnotherTip: 'Add another tip',
addColourOverlay: 'Add colour overlay',
},
words: { and: 'and' },
placeholders: { select: 'Select...' },
heading: {
shareThisPage: 'Share this page',
helpfulResources: 'Helpful resources',
},
section: {
subSection: {
description:
'So we can show you the best information, which one of these best describes you?',
},
changeLanguage: {
title: 'Change language',
placeholder: 'Search',
},
helpMe: {
title: 'Help!',
subtitle: 'Text here',
},
helpBudget: {
title: 'Need help with budgeting?',
},
colors: [
{
label: 'Blue',
},
{
label: 'Green',
},
{
label: 'Yellow',
},
{
label: 'Red',
},
],
};
export default common;
Using this node-ews package, I can send email, but I haven't been able to find a good example of how to read mails from the Inbox folder and get the email's text and attachments.
I've read the Microsoft documentation, such as this one: https://learn.microsoft.com/en-us/exchange/client-developer/exchange-web-services/how-to-work-with-exchange-mailbox-items-by-using-ews-in-exchange#get-an-item-by-using-the-ews-managed-api, but the examples are in C#, C++, or VB.
However, I would like to use Nodejs for this.
**I have found a best way extract every content using mailparser. see bellow
// At first Read emails from Inbox
const EWS = require('node-ews');
const simpleParser = require('mailparser').simpleParser;
// exchange server connection info
const ewsConfig = {
username: 'username',
password: 'password',
host: 'hostname'
};
const options = {
rejectUnauthorized: false,
strictSSL: false
};
// initialize node-ews
const ews = new EWS(ewsConfig, options);
var ewsFunction = 'FindItem';
var ewsArgs = {
'attributes': {
'Traversal': 'Shallow'
},
'ItemShape': {
't:BaseShape': 'Default'
},
'ParentFolderIds' : {
'DistinguishedFolderId': {
'attributes': {
'Id': 'inbox'
}
}
}
};
// Itreate over all the emails and store Id and ChangeKey.
ews.run(ewsFunction, ewsArgs, ewsSoapHeader)
.then(result => {
// Iterate over the result and extract Id and ChangeKey of the messages and pass those to GetItem function to read messages
})
// For reading individual messages returned by FindItem (using Id and ChangeKey)
var ewsFunction = 'GetItem';
var ewsArgs = {
'ItemShape': {
'BaseShape': 'Default',
'AdditionalProperties': {
'FieldURI': [
{ 'attributes': { 'FieldURI': 'item:MimeContent'}}
]
}
},
'ItemIds': {
'ItemId': {
'attributes': {
'Id': Id,
'ChangeKey': ChangeKey
}
}
}
};
await ews.run(ewsFunction, ewsArgs, ewsSoapHeader)
.then(result => {
// Iterate over the result and extract meesage
const {Message} = result.ResponseMessages.GetItemResponseMessage.Items
let mimeContent = Buffer.from(Message.MimeContent['$value'], 'base64').toString('binary');// decode mime content
simpleParser(mimeContent).then(async function (mail) {
console.log("mail")
console.log(mail.attachments)
console.log(mail.headers.get('message-id'))
console.log(mail.headers.get('references'))
console.log(mail.headers.get('in-reply-to'))
console.log({
// text: mail.text,
// html: mail.html ? mail.html.replace(/<meta([^>]+)>/g, "") : "",
from: (mail.from) ? mail.from.value.map(item => item.address) : [],
to: (mail.to) ? mail.to.value.map(item => item.address) : [],
cc: (mail.cc) ? mail.cc.value.map(item => item.address) : [],
bcc: (mail.bcc) ? mail.bcc.value.map(item => item.address) : [],
messageId: mail.messageId,
subject: mail.subject
})
}).catch((err) => {
console.log("err")
console.log(err)
})
})
Here you will get the full parsed mail contents with attachments. Happy Coding!!!
I am using converse.js to provide chat functionality. I am looking for a way to add reply to specific chat room message. any one know how can i do that?
for example:
in group user1 send: hello
and user2 wants reply to this message and say hello to
my initial code:
<script>
converse.initialize({
authentication: 'login',
//
auto_login: true,
allow_logout: false,
show_client_info: false,
allow_adhoc_commands: false,
allow_contact_requests: false,
hidden_occupants: true,
blacklisted_plugins: [
'converse-register',
'converse-rosterview',
'converse-bookmarks',
'converse-profile',
],
jid: "person#example.com",
password: "somepassword",
auto_join_rooms: [
{
'jid': 'group#conference.example.com',
'nick': 'myname',
'name': 'title',
'minimized': true
},
],
//
auto_reconnect: true,
bosh_service_url: 'https://example.com:7443/http-bind/',
message_archiving: 'always',
view_mode: 'fullscreen'
});
</script>
thanks all.
Finally I find way to solve this problem.
first in convers.js/src/plugins/chatview/view.js add this before onMessageEditButtonClicked:
onMessageReplyButtonClicked (message) {
const currently_correcting = this.model.messages.findWhere('correcting');
const unsent_text = this.el.querySelector('.chat-textarea')?.value;
if (unsent_text && (!currently_correcting || currently_correcting.get('message') !== unsent_text)) {
if (!confirm(__('You have an unsent message which will be lost if you continue. Are you sure?'))) {
return;
}
}
this.insertIntoTextArea(u.prefixMentions(message, true), true, false);
},
and in convers.js/src/components/message-actions.js file add below code before onMessageEditButtonClicked
onMessageReplyButtonClicked(ev) {
ev.preventDefault();
this.chatview.onMessageReplyButtonClicked(this.model);
}
and in convers.js/src/headless/utils/cores.js change the u.prefixMentions function to:
u.prefixMentions = function (message, reply = false) {
/* Given a message object, return its text with # chars
* inserted before the mentioned nicknames.
*/
let text = message.get('message');
(message.get('references') || [])
.sort((a, b) => b.begin - a.begin)
.forEach(ref => {
text = `${text.slice(0, ref.begin)}#${text.slice(ref.begin)}`
});
if (reply){
const lines = text.split('\n');
let newtxt = ""
for(let i = 0;i < lines.length;i++){
if(!lines[i].startsWith(">")){
newtxt += "> " + lines[i] + "\n"
}
}
return "> reply to " + message.get('nick') + ":\n" + newtxt
}
else
return text;
};
I have made a scheduled script which is sending PDF though email.send()
I have get the filters as params from Suitelet. I want to get the name of the user (from runtime.getCurrentUser) and pass it to my PDF. I m just confused how to pass them and will that API be used in Suitelet or Sched script.
Can anyone help me with the code?
Here is my Scheduled script code:
/**
* #NApiVersion 2.x
* #NScriptType scheduledscript
*/
define(['N/ui/serverWidget', 'N/search', 'N/render', 'N/runtime', 'N/file', 'N/email'],
function (ui, search, render, runtime, file, email) {
function execute() {
try {
generateReport();
}
catch (e) {
log.error('generateReport ERROR', e);
}
}
function generateReport() {
var slfilters = runtime.getCurrentScript().getParameter({ name: 'custscript_searchfilter_report' });
log.debug('slfilters', slfilters);
if (!!slfilters) {
slfilters = JSON.parse(slfilters);
}
log.debug('slfilters2', slfilters);
var user = runtime.getCurrentUser();//Need this user to be passed to my xml template
var gender = slfilters.gender;//getting this from Suitelet
log.debug('gender', gender);
var item = slfilters.item;//getting this from Suitelet
log.debug('item', item);
var item_ = getItems(item, gender);
log.debug('getItems(item, gender)', item_);
//return item;
var xmlTemplateFile = file.load(3918);
//var template = script.getParameter({ name: 'custscript_template' });
var renderer = render.create();
renderer.templateContent = xmlTemplateFile.getContents();
var customSources = {
alias: 'searchdata',
format: render.DataSource.JSON,
data: JSON.stringify({
value: item_,
})
};
renderer.addCustomDataSource(customSources);
var xml = renderer.renderAsString();
var pdf = render.xmlToPdf({
"xmlString": xml
});
email.send({
author: 317,
recipients: 'aniswtf#gmail.com',
subject: 'Item Report',
body: 'Report Generated: ',
attachments: [pdf]
});
}
//
// ─── GET RESULTS ───────────────────────────────────────────────────
//
const getResults = function (set) {
var results = [];
var i = 0;
while (true) {
var result = set.getRange({
"start": i,
"end": i + 1000
});
if (!result) break;
results = results.concat(result);
if (result.length < 1000) break;
i += 1000;
}
return results;
};
//
// ─── GET ITEMS ───────────────────────────────────────────────────
//
function getItems(item, gender,user) {
try {
log.error('getItems Function started');
var itemSearch = search.load({
id: 'customsearch_mx_itemsearch'
});
var defaultFilters = itemSearch.filters;
itemSearch.filters.push(
search.createFilter({
name: "custitem5",
operator: 'anyof',
values: gender
}),
search.createFilter({
name: "internalid",
operator: 'anyof',
values: item
})
);
//defaultFilters = arrFilters;
//defaultFilters = defaultFilters.concat(arrFilters);
//log.error('Updated Filters', defaultFilters)
log.error('itemSearch', itemSearch);
//return defaultFilters;
var results = itemSearch.run().getRange({
start: 0,
end: 150
});
var result2 = results.map(function (x) {
// var results = getResults(itemSearch.run()).map(function (x) {
return {
'category': x.getText({
name: "custitem10",
join: "parent"
}),
'season': x.getValue({
name: "custitem11",
join: "parent"
}),
'riselabel': x.getText({
name: "custitem_itemriselabel",
join: "parent"
}),
'fit': x.getText({
name: "custitem9",
join: "parent"
}),
'name': x.getText({ //sku
name: "itemid",
join: "parent"
}),
'style': x.getText({
name: "custitem8",
join: "parent"
}),
'inseam': x.getText({
name: "custitem7",
join: "parent"
}),
'wash': x.getText({
name: "custitem_washname",
join: "parent"
}),
};
});
log.debug('Results', results.length);
log.debug('results', results);
log.debug('result2', result2);
// return results;//nabeeel's
return result2;//mine
} catch (e) {
log.error('error in getItems', e)
}
}
return {
execute: execute
};
});
There is no User in a Scheduled Script, so runtime.getCurrentUser() there will not return a value. You will need to retrieve the User via that method in the Suitelet (assuming it is not an anonymous external Suitelet).
From there you can add a Script Parameter to the Scheduled Script to hold the User, and then your Scheduled Script can read the Parameter and add the value as another Data Source on your template.
I have been struggling for a pretty long while now with sending dates JS -> Python -> MySQL.
With the code below I get the error message "query failed - ['unicode' object has no attribute 'isoformat']". I hope that you know a solution.
Here is the database server code, abridged:
class AddLicenseCode(graphene.Mutation):
class Arguments:
valid_from = graphene.String()
valid_to = graphene.String()
valid_from = graphene.types.datetime.DateTime()
valid_to = graphene.types.datetime.DateTime()
#staticmethod
def mutate(root, info, **args):
context = info.context
valid_from = args.get('valid_from')
valid_to = args.get('valid_to')
licenseCodeResponse = license_service.add_license_code(valid_from, valid_to)
return AddLicenseCode(
valid_from=licenseCodeResponse['valid_from'],
valid_to=licenseCodeResponse['valid_to'])
...
def add_license_code(self, valid_from, valid_to):
db = self.get_write_db()
variables = {
"valid_from": valid_from.isoformat(), <-----ERROR HAPPENS HERE
"valid_to": valid_to.isoformat(),
}
Here is the code from a client/server that sits between the frontend and the database server, abridged:
const addLicenseCodeMutation = {
name: 'AddLicenseCodeMutation',
type: addLicenseCodeType,
description: "Mutation for adding a license code",
args: {
validFrom: { type: graphql.GraphQLInt },
validTo: { type: graphql.GraphQLInt },
},
resolve: function (source, args, context, _info) {
return licenseService.addLicenseCode(args, context);
}
};
addLicenseCode = function(args, context) {
const validFrom = args.validFrom;
const validTo = args.validTo;
const query = 'mutation licenseMutation { addLicenseCode(' +
'validFrom: "' + validFrom + '", ' +
'validTo: "' + validTo + '", ' +
'){validFrom, validTo}}'
return queryLicenseService(query, requestId, context, function (data) {
return data['addLicenseCode'];
});
Here is the front end code, abridged:
const variables = {
validFrom: timeLimit ? null : Date.parse(validFrom),
validTo: timeLimit ? null : Date.parse(validTo),
};
const result = yield client.mutate({
mutation: gql`
mutation licensemutation($validFrom: Int, $validTo: Int) {
addLicenseCode(validFrom: $validFrom, validTo: $validTo) {
validFrom,
validTo
}
}
`,
variables: {...variables},
});