Skip to content

Commit

Permalink
Merge pull request #1 from vernu/v2
Browse files Browse the repository at this point in the history
V2
  • Loading branch information
vernu authored Jun 19, 2023
2 parents b86f0cf + f37a7e7 commit a8e3466
Show file tree
Hide file tree
Showing 37 changed files with 452 additions and 206 deletions.
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# TextBee - Android SMS Gateway

A simple SMS gateway that allows users to send SMS messages from a web interface or
from their application via a REST API. It utilizes android phones as SMS gateways.

- **Technology stack**: React, Next.js, Node.js, NestJs, MongoDB, Android, Java
- **Status**: MVP in development, not ready for production use yet
- **Link**: [https://textbee.vernu.dev](https://textbee.vernu.dev/)

![](https://ik.imagekit.io/vernu/textbee/texbee-landing-light.png?updatedAt=1687076964687)

## Usage

1. Go to [textbee.vernu.dev](https://textbee.vernu.dev) and register or login with your account
2. Install the app on your android phone from [textbee.vernu.dev/android](https://textbee.vernu.dev/android)
3. Open the app and grant the permissions for SMS
4. Go to [textbee.vernu.dev/dashboard](https://textbee.vernu.dev/dashboard) and click register device/ generate API Key
5. Scan the QR code with the app or enter the API key manually
6. You are ready to send SMS messages from the dashboard or from your application via the REST API

**Code Snippet**: Few lines of code showing how to send an SMS message via the REST API

```javascript
const API_KEY = 'YOUR_API_KEY';
const DEVICE_ID = 'YOUR_DEVICE_ID';

await axios.post(`https://api.textbee.vernu.dev/api/v1/devices/${DEVICE_ID}/sendSMS?apiKey=${API_KEY}`, {
receivers: [ '+251912345678' ],
smsBody: 'Hello World!',
})

```

## Contributing

Contributions are welcome!

1. Fork the project.
2. Create a feature or bugfix branch from `main` branch.
3. Make sure your commit messages and PR comment summaries are descriptive.
4. Create a pull request to the `main` branch.
2 changes: 1 addition & 1 deletion android/.idea/.name

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ android {
applicationId "com.vernu.sms"
minSdk 24
targetSdk 32
versionCode 5
versionName "1.3.0"
versionCode 7
versionName "2.0"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public class MainActivity extends AppCompatActivity {
private static final int SEND_SMS_PERMISSION_REQUEST_CODE = 0;
private static final int SCAN_QR_REQUEST_CODE = 49374;

private static final String API_BASE_URL = "https://api.sms.vernu.dev/api/v1/";
private static final String API_BASE_URL = "https://api.textbee.vernu.dev/api/v1/";
private String deviceId = null;


Expand Down Expand Up @@ -89,6 +89,12 @@ protected void onCreate(Bundle savedInstanceState) {
deviceIdTxt.setText(deviceId);
deviceBrandAndModelTxt.setText(Build.BRAND + " " + Build.MODEL);

if(deviceId == null || deviceId.isEmpty()) {
registerDeviceBtn.setText("Register");
} else {
registerDeviceBtn.setText("Update");
}

if (isSMSPermissionGranted(mContext)) {
grantSMSPermissionBtn.setEnabled(false);
grantSMSPermissionBtn.setText("SMS Permission Granted");
Expand Down Expand Up @@ -146,7 +152,7 @@ public void onFailure(Call<RegisterDeviceResponseDTO> call, Throwable t) {

scanQRBtn.setOnClickListener(view -> {
IntentIntegrator intentIntegrator = new IntentIntegrator(MainActivity.this);
intentIntegrator.setPrompt("Go to sms.vernu.dev/dashboard and click Register Device to generate QR Code");
intentIntegrator.setPrompt("Go to textbee.vernu.dev/dashboard and click Register Device to generate QR Code");
intentIntegrator.setRequestCode(SCAN_QR_REQUEST_CODE);
intentIntegrator.initiateScan();
});
Expand Down
2 changes: 1 addition & 1 deletion android/app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Go to sms.vernu.dev/dashboard and click register device, then copy and paste the api key generated or scan the QR code" />
android:text="Go to textbee.vernu.dev/dashboard and click register device, then copy and paste the api key generated or scan the QR code" />

<Button
android:id="@+id/grantSMSPermissionBtn"
Expand Down
8 changes: 4 additions & 4 deletions android/app/src/main/res/values-night/themes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
<!-- Base application theme. -->
<style name="Theme.SMSGateway" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">#f35b04</item>
<item name="colorPrimaryVariant">#f18701</item>
<item name="colorPrimary">#4299E1</item>
<item name="colorPrimaryVariant">#4299cc</item>
<item name="colorOnPrimary">@color/white</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">#3d348b</item>
<item name="colorSecondaryVariant">#7678ed</item>
<item name="colorSecondary">#f35b04</item>
<item name="colorSecondaryVariant">#f18701</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
Expand Down
2 changes: 1 addition & 1 deletion android/app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<resources>
<string name="app_name">SMS Gateway</string>
<string name="app_name">TextBee</string>
</resources>
8 changes: 4 additions & 4 deletions android/app/src/main/res/values/themes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
<!-- Base application theme. -->
<style name="Theme.SMSGateway" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">#f35b04</item>
<item name="colorPrimaryVariant">#f18701</item>
<item name="colorPrimary">#4299E1</item>
<item name="colorPrimaryVariant">#4299cc</item>
<item name="colorOnPrimary">@color/white</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">#3d348b</item>
<item name="colorSecondaryVariant">#7678ed</item>
<item name="colorSecondary">#f35b04</item>
<item name="colorSecondaryVariant">#f18701</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
Expand Down
2 changes: 1 addition & 1 deletion android/settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ dependencyResolutionManagement {
mavenCentral()
}
}
rootProject.name = "SMS Gateway"
rootProject.name = "TextBee"
include ':app'
4 changes: 2 additions & 2 deletions api/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ async function bootstrap() {
})

const config = new DocumentBuilder()
.setTitle('VERNU SMS Gateway api docs')
.setDescription('api docs')
.setTitle('TextBee API Docs')
.setDescription('TextBee - Android SMS Gateway API Docs')
.setVersion('1.0')
.addBearerAuth()
.build()
Expand Down
2 changes: 1 addition & 1 deletion web/.env.example
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
NEXT_PUBLIC_API_BASE_URL=https://api.sms.vernu.dev/api/v1
NEXT_PUBLIC_API_BASE_URL=https://api.textbee.vernu.dev/api/v1
NEXT_PUBLIC_GOOGLE_CLIENT_ID=
52 changes: 52 additions & 0 deletions web/components/Footer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import {
Box,
chakra,
Container,
Stack,
Text,
useColorModeValue,
} from '@chakra-ui/react'
import Link from 'next/link'

export default function Footer() {
return (
<Box
bg={useColorModeValue('gray.50', 'gray.900')}
color={useColorModeValue('gray.700', 'gray.200')}
>
<Container
as={Stack}
maxW={'6xl'}
py={4}
spacing={4}
justify={'center'}
align={'center'}
>
<Stack direction={'row'} spacing={6}>
<Link href='/'>Home</Link>
<Link href='/dashboard'>Dashboard</Link>
<Link href='/android'>Download App</Link>
<Link href='https://github.com/vernu/textbee'>Github</Link>
</Stack>
</Container>

<Box
borderTopWidth={1}
borderStyle={'solid'}
borderColor={useColorModeValue('gray.200', 'gray.700')}
>
<Container
as={Stack}
maxW={'6xl'}
py={4}
direction={{ base: 'column', md: 'row' }}
spacing={4}
justify='center'
align={{ base: 'center', md: 'center' }}
>
<Text>© {new Date().getFullYear()} All rights reserved</Text>
</Container>
</Box>
</Box>
)
}
17 changes: 14 additions & 3 deletions web/components/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@ export default function Navbar() {

return (
<>
<Box bg={useColorModeValue('gray.100', 'gray.700')} px={4} shadow='lg' mb={1}>
<Box
bg={useColorModeValue('gray.100', 'blue.600')}
px={4}
shadow='lg'
mb={1}
>
<Flex h={16} alignItems={'center'} justifyContent={'space-between'}>
<Link href='/' passHref>
<Flex alignItems={'center'}>
Expand All @@ -37,9 +42,10 @@ export default function Navbar() {
w={'30px'}
h={'30px'}
src={'/images/sms-gateway-logo.png'}
borderRadius='full'
/>
<Box style={{ cursor: 'pointer', marginLeft: '5px' }}>
VERNU SMS
TextBee
</Box>
</Flex>
</Link>
Expand All @@ -50,6 +56,12 @@ export default function Navbar() {
{colorMode === 'light' ? <MoonIcon /> : <SunIcon />}
</Button>

<Menu>
<Link href='https://github.com/vernu/textbee' passHref>
<MenuButton>Github</MenuButton>
</Link>
</Menu>

{!user ? (
<>
<Menu>
Expand Down Expand Up @@ -102,7 +114,6 @@ export default function Navbar() {
>
Dashboard
</MenuItem>
<MenuItem>Account Settings</MenuItem>
<MenuItem
onClick={() => {
dispatch(logout())
Expand Down
11 changes: 2 additions & 9 deletions web/components/dashboard/DeviceList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,20 +64,13 @@ const DeviceList = () => {
<Tr key={_id}>
<Td>{`${brand}/ ${model}`}</Td>
<Td>{enabled ? 'enabled' : 'disabled'}</Td>
<Td>
<EmailIcon onDoubleClick={(e) => {}} />
</Td>
<Td>{/* <EmailIcon onDoubleClick={(e) => {}} /> */}</Td>
<Td>
<Tooltip label='Double Click to delete'>
<IconButton
aria-label='Delete'
icon={<DeleteIcon />}
onDoubleClick={(e) => {
sendSMSRequest(_id, {
receivers: ['+251912657519'],
smsBody: 'Hello World',
})
}}
onDoubleClick={(e) => {}}
/>
</Tooltip>
</Td>
Expand Down
61 changes: 35 additions & 26 deletions web/components/dashboard/GenerateApiKey.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
Box,
Button,
chakra,
Flex,
Expand Down Expand Up @@ -112,32 +113,40 @@ export default function GenerateApiKey() {
}
return (
<>
{' '}
<Flex justifyContent='center'>
<Button
/* flex={1} */
px={4}
fontSize={'sm'}
rounded={'full'}
bg={'blue.400'}
color={'white'}
boxShadow={
'0px 1px 25px -5px rgb(66 153 225 / 48%), 0 10px 10px -5px rgb(66 153 225 / 43%)'
}
_hover={{
bg: 'blue.500',
}}
_focus={{
bg: 'blue.500',
}}
onClick={generateApiKey}
disabled={generatingApiKey}
>
{generatingApiKey
? 'generating... '
: 'Generate Api Key/ Register Device'}
</Button>
</Flex>
<Box padding={5} border='1px solid gray' marginBottom={10} borderRadius='2xl'>
<Flex direction='row' justifyContent='space-between'>
{' '}
<chakra.h1
fontSize='md'
fontWeight='bold'
mt={2}
color={useColorModeValue('gray.800', 'white')}
>
Generate Api Key and Register Device
</chakra.h1>
<Button
/* flex={1} */
px={4}
fontSize={'sm'}
rounded={'full'}
bg={'blue.400'}
color={'white'}
boxShadow={
'0px 1px 25px -5px rgb(66 153 225 / 48%), 0 10px 10px -5px rgb(66 153 225 / 43%)'
}
_hover={{
bg: 'blue.500',
}}
_focus={{
bg: 'blue.500',
}}
onClick={generateApiKey}
disabled={generatingApiKey}
>
{generatingApiKey ? 'loading... ' : 'Get Started'}
</Button>
</Flex>{' '}
</Box>
{generatedApiKey && (
<>
{
Expand Down
7 changes: 6 additions & 1 deletion web/components/dashboard/SendSMS.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
Box,
Button,
Flex,
FormLabel,
Input,
Modal,
Expand Down Expand Up @@ -53,7 +54,11 @@ export default function SendSMS() {

return (
<>
<Button onClick={onOpen}>Start Sending</Button>
<Flex justifyContent='flex-end' marginBottom={20}>
<Button bg={'blue.400'} color={'white'} onClick={onOpen}>
Send SMS
</Button>
</Flex>

<Modal isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
Expand Down
Loading

1 comment on commit a8e3466

@vercel
Copy link

@vercel vercel bot commented on a8e3466 Jun 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.