Nexmo Voice API demo: voicemail app

This article features voicemail service built using Nexmo Voice APIs and Spring Boot

As a business owner it's not always easy to handle huge volume of calls 24/7. On another hand each customer is important and it deserve to be served well.

To kick off development you can checkout demo repository

What to expect in this tutorial

In this tutorial we build simple voice mail forwarder where callers asked to leave a voice message which will be sent to the email using Nexmo Voice API as an attachment.
Example of result:

Read more

JavaScript must go (ASAP)

JavaScript it's a cancer of modern software development industry

💥 DISCLAMER
1. This article is about JavaScript - the language happen to become a runtime for many types of applications.
2. TypeScript, CoffeeScript, *Script have nothing to do with JS, this post is not about it.
3. As many of you I'm also a JavaScript developer. I'm not addressing to anyone personally, the post below is just my opinion about technology
4. If you're happy with any technology and it helps to archive the business goals - I can be only happy for that!

Big claim, isn't it? Well, I'm sure I have a right to say that. I've been using suffering from JavaScript in last 10+ years. Really, I can't remember anything good about this shit language since I started to make money on programming being freelancer. I'm not mean, I just had enough. And please, don't take this article personally, you're not a programming language you use.

I'm a normal developer.

It means I'm not genius and I can't and wouldn't keep whole program code and it's complicated flow and branching in my head. I'd rather delegate this boring work to computer and focus on business logic as much as I can. I'm certain, there are about 2.5 really good developers who can write good code in javascript. But probably they don't as they are busy talking on conferences ¯_(ツ)_/¯

You cannot avoid JS

Read more

android kotlin gradle.build

Here skeleton of gradle.build script for madness people who try to code Android apps using kotlin language.

This gradle script uses another structure of subdirectories, more simple I would say. There is no useless "deep" folders like src/main/java, src/main/assets, etc..


buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.1.0'
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:0.10.770'
}
}

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'idea'

repositories {
mavenCentral()
}

dependencies {
compile 'org.jetbrains.kotlin:kotlin-stdlib:0.10.770'
}

android {
compileSdkVersion 21
buildToolsVersion "21.1.2"

defaultConfig {
minSdkVersion 15
targetSdkVersion 21
}

dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
}

sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['java', 'kotlin']
aidl.srcDirs = ['java']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
}
}

Read more

Android: отправка письма дефолтным клиентом

gmail-app-with-predefined-text-via-mailto-intent

Задача: отрыть дефолтный email клиент у пользователя на устройстве с предустановленным заголовком письма, текстом и адресатом.

При этом не должно всплывать окно IntentChooser, предоставляющее варианты каким приложением воспользоваться для написания письма. Пользователь должен сразу увидеть его дефолтный email клиент (и это не всегда gmail). Тысячи ответов на StackOverflow показывают диалог, схожий с "share". Некоторые товарищи в лучшем случае предлагают фильтровать по ContentType и другим косвенным признакам того, что это почтовый клиент, хотя достаточно часто все равно просачиваются приложения вроде Evernote или даже пресловутый bluetooth. Иногда предлагают не переносимые решения, типа использование курсора для получения доступных email клиентов.

Read more

Android: сниппет для тостов

Toast прекрасный способ оповестить пользователя о чем то, не блокируя интерфейс. У них можно завадать отзывы, показывать в разных местах и даже делать кастомные view и все это с помощью fluent interface. Уверен, что читатели если и слышали о таких расширенных возможностях, то никогда не пользовались этим. Самый стандартный юзкейс - показать текст.

По моему опыту часто нужно показать toast как результат не успешной процедуры, которая обычно выполняется в фоне в отдельном треде или воркере, т.е. не в UI. А для этого приходится писать лапшу только для того, Toast.makeText(...).show() выполнился в UI треде.

Для этого набросал сниппет, который уменьшит количество кода и ошибки, связанные с вызовом тоста из нетого потока и банальному забыванию метода show().

Было

Toast.makeText(this,
getText(R.string.messages_storage_invalid),
Toast.LENGTH_SHORT).show();

Стало

toastShort(R.string.messages_storage_invalid);

Причем метод можно вызывать из любого потока. Показыватся тост будет из UI треда через runnable

Read more

Kotlin: джависты, завидуйте

Около года назад, в подкасте радио-т я впервые услышал о инициативе JetBrains, новом языке программирования kotlin. С тех пор внимательно слежу за его развитием.
Они позиционируют котлин как "better java" и, надо сказать, у это получается. Это статический типизированный, язык со вшитой nullable-проверкой Так же он поддерживает функции высшего порядка(замыкания), extension functions и trait. Может немного напоминать scala - но, достаточно далеко от неё.

Read more

Play Framework: локализация Date.since()

Play framework позволяет в шаблонах groovy использовать extension functions - т.е прицеплять методы на ходу к объектам.

В частности в play имеет расширение экземпляров класса Date - since(), который возвращает сколько времени прошло от указанной даты. Например "13 minutes ago"

С since() все хорошо, пока не требуется интернационализация. Если переопределить соответствующие ключи в файлах перевода, то для русского он возвращает нечто вроде 3 дняs назад. Другими словами этот метод не может отображать количество пройденного времени на любом языке, кроме английского.

Read more

Android: не используйте String.isEmpty

Ни eclipse ни intellj Idea ни android lint не предупреждают, что String.isEmpty() появился в Java 6, и после Android 2.3.


java.lang.NoSuchMethodError: java.lang.String.isEmpty
at pro.ezway.carmonitor.entity.TroubleCode.hasTitle(TroubleCode.java:142)
at pro.ezway.carmonitor.ui.fragments.TroubleCodesFragment$TroubleCodesAdapter.getView(TroubleCodesFragment.java:242)
at android.widget.AbsListView.obtainView(AbsListView.java:1315)
at android.widget.ListView.makeAndAddView(ListView.java:1727)

Read more

Android: запуск дефолтного ланчера

Есть неочевидная ситуация: вы пишете лаунчер лончер или что-то его заменяющее, отдебажили, всё работало. Конечно же, вы поставили его как програму по умолчанию и теперь он стартует вместо дефолтого. И вдруг, вылезает некая бага, которая начинает крушить, бомбить ронять телефон, перезапуская приложение. Перезапустится, конечно же, то, что упало, а упал лончер. И он снова падает. Development mode в продакшене отключён. Ну вы поняли.

На самом деле бывают ситуации ещё хуже, например, для vendor lock-in приложений, которые вообще скрывают, что они работают под андроид.

Предвкушая первую мысль как вернуть дефолтный лончер: вызвать в приложении finish(). Чёрт, это же домашний экран %)

Read more

Groovy: java слишком проста

Возьмём довольно частую задачку: есть несколько значений первой переменной, нужно сделать присвоить второй переменной какое-то значение, в зависимости от первой переменной, т.е. value mapping.

В джаве это делается примерно так:


String alertClass = "";
switch(code.toUpperCase().charAt(0)) {
case 'U':
alertClass = "alert";
break;
case 'P':
alertClass = "alert-error";
break;
case 'B':
alertClass = "alert-warning";
break;
case 'C':
alertClass = "alert-info";
break;
}
// now alertClass has value

Read more