Несколько дней назад я Blogged Об добавлении индивидуальной обработки формы на ваш статический сайт в NetLify. Это было сделано с помощью простой функции без сервеса, которая слушала для представлений формы и использовала Sendgrid API для отправки электронного письма. Пока это работает нормально, у меня на самом деле было что-то более интересное, что мне пришлось немного отложить. Представьте, что если вместо того, чтобы просто получать электронные письма о контактных формах представления, вы на самом деле получили что-то с небольшим предупреждением с точки зрения их содержания:
На изображении выше вы можете увидеть какую-то основную информацию о содержании электронной почты на основе их тона. Это было бы отличным способом узнать, что приоритетно приоритетировать с точки зрения чтения и ответа. Чтобы построить это, я использовал IBM Watson Tone Analyzer услуга. Я использовал это несколько раз в прошлом с различными демонстрационными демонстрациями без сервеса с OpenWhisk, но я подумал, что даст ему выстрел с NetLify и Lambda. Вот полный скрипт (и обязательно прочитайте Последняя запись для контекста о том, как он работает) с добавленной новой функцией:
const helper = require('sendgrid').mail;
const SG_KEY = process.env.SENDGRID;
const axios = require('axios');
const ToneAnalyzerV3 = require('watson-developer-cloud/tone-analyzer/v3')
const TA_KEY = process.env.TONEANALZYER;
exports.handler = async (event, context, callback) => {
console.log('submission created error testing');
let payload = JSON.parse(event.body).payload;
let analysis = '';
let toneString = '';
//lets analyze the text
if(payload.data.comments && payload.data.comments.length) {
analysis = await analyze(payload.data.comments);
/*
if we get results, its an array of tones, ex:
[ { score: 0.633327, tone_id: 'fear', tone_name: 'Fear' },
{ score: 0.84639, tone_id: 'tentative', tone_name: 'Tentative' } ]
So what we will do is create an analysis string based on tone_names where score > 0.5
*/
analysis = analysis.filter(t => t.score > 0.5);
// and now we'll build an array of just tones
let tones = analysis.map(t => t.tone_name);
// and then a string
toneString = tones.join(', ');
}
// note - no validation - booooo
let from_email = new helper.Email(payload.data.email);
let to_email = new helper.Email('raymondcamden@gmail.com');
let subject = 'Contact Form Submission';
if(toneString.length > 0) subject += ` [Tone: ${toneString}]`;
let date = new Date();
let content = `
Form Submitted at ${date}
--------------------------------
`;
for(let key in payload.data) {
content += `
${key}: ${payload.data[key]}
`;
}
let mailContent = new helper.Content('text/plain', content);
let mail = new helper.Mail(from_email, subject, to_email, mailContent);
let sg = require('sendgrid')(SG_KEY);
let request = sg.emptyRequest({
method: 'POST',
path: '/v3/mail/send',
body: mail.toJSON()
});
await sg.API(request, function(error, response) {
if(error) {
console.log(error.response.body);
} else console.log(response);
});
console.log('And done...');
};
async function analyze(str) {
console.log('going to tone analzye '+str);
let toneAnalyzer = new ToneAnalyzerV3({
username: 'apikey',
password: TA_KEY,
version: '2017-09-21',
url: 'https://gateway.watsonplatform.net/tone-analyzer/api/'
});
const result = await new Promise((resolve, reject) => {
toneAnalyzer.tone(
{
tone_input: str,
content_type: 'text/plain'
},
function(err, tone) {
if (err) {
console.log(err);
reject(err);
} else {
resolve(tone.document_tone.tones);
}
}
);
});
return result;
}
Хорошо, давайте сломаем это. Во-первых, я загружаю в Watson Node.js SDK Отказ Хотя это не нужно, у меня были проблемы с использованием API для отдыха для тонального анализа напрямую и решили просто сделать легкий путь и использовать их пакет.
const ToneAnalyzerV3 = require('watson-developer-cloud/tone-analyzer/v3')
const TA_KEY = process.env.TONEANALZYER;
Где Process.env. Toneanalzyer Ключ исходит от? Не забудьте, что вы можете определить пользовательские переменные среды для ваших сайтов NetLify.
Далее давайте посмотрим, есть ли у нас данные для проверки. В этом случае я предполагаю, что у меня есть поле под названием Комментарии И это блок текста. Вы можете сделать это более универсальным или даже использовать скрытые поля формы как способ сказать, что следует проверить.
let analysis = '';
let toneString = '';
//lets analyze the text
if(payload.data.comments && payload.data.comments.length) {
analysis = await analyze(payload.data.comments);
Обратите внимание на модное использование Ждите . Как предупреждение, пожалуйста, обратите внимание, что я все еще ломаюсь вокруг async/a ждать . Давайте посмотрим на анализировать :
async function analyze(str) {
console.log('going to tone analzye '+str);
let toneAnalyzer = new ToneAnalyzerV3({
username: 'apikey',
password: TA_KEY,
version: '2017-09-21',
url: 'https://gateway.watsonplatform.net/tone-analyzer/api/'
});
const result = await new Promise((resolve, reject) => {
toneAnalyzer.tone(
{
tone_input: str,
content_type: 'text/plain'
},
function(err, tone) {
if (err) {
console.log(err);
reject(err);
} else {
resolve(tone.document_tone.tones);
}
}
);
});
return result;
}
Это в основном просто оборачивает вызов API Tone Analyzer и возвращает данные результата. Я держал это в основном общим. Теперь вернемся к абонеру:
/*
if we get results, its an array of tones, ex:
[ { score: 0.633327, tone_id: 'fear', tone_name: 'Fear' },
{ score: 0.84639, tone_id: 'tentative', tone_name: 'Tentative' } ]
So what we will do is create an analysis string based on tone_names where score > 0.5
*/
analysis = analysis.filter(t => t.score > 0.5);
// and now we'll build an array of just tones
let tones = analysis.map(t => t.tone_name);
// and then a string
toneString = tones.join(', ');
Поскольку комментарии говорят, вы получаете массив тонов назад И они не кажутся отсортированными. Я сделал быстрое «качественное» фильтр, удалив тона с баллом менее 0,5. Это было произвольным. Затем я составляю только имя и, наконец, сделаю строку.
Кстати, мне 99% уверены, что эти три вещи могут быть сделаны в одной необычной линии JavaScript кем-то, кто может работать в Google. Я не работаю в Google.
Последний бит – просто добавить тона, если мы получим их:
if(toneString.length > 0) subject += ` [Tone: ${toneString}]`;
И это все! Итак, давайте повеселимся с этим. Предупреждение, язык взрослых входящий. Если у вас взрослый язык не имеет смысла для вас, спросите своих детей.
I AM SO FUCKING MAD AT YOU I WISH YOU WOULD DIE I HATE YOUR SERVICE. I HATE EVERYTHING YOU DO. I HATE KITTENS. i HATE PUPPIES. I HATE BEER. OH MY GOD IM SO MAD AT EVERYTHING
Это вернуло то, что вы ожидаете: Отправка формы контакта [тона: гнев]
Теперь проверьте этот вход:
i'm so happy with your service, but i'm nervous that if i commit to a monthly payment i'll not actually make use of it enough to get value. can you give me some more details on what i get with this service and help convince me it's worth it?
Пока я знаю, Уотсон не идеален, но вау, проверьте результат: Подписание формы контакта [Tone: Preatative] Я бы считал это рядом с идеальным.
Вы можете себе представить, что подключив это к некоторым правилам на вашем почтовом сервере, так что люди обслуживания клиентов с историей обработки сердитых клиентов автоматически получают эти электронные письма и так далее. Во всяком случае, дайте мне знать, что вы думаете, оставив комментарий ниже. В качестве напоминания это все делается через так называемый «статический» сайт. Довольно чертовски впечатляет, верно?
Оригинал: “https://dev.to/raymondcamden/adding-emotional-tone-analysis-to-your-contact-form-2n76”